keyring

package
v0.0.48-fix Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 27, 2020 License: MIT Imports: 24 Imported by: 3

README

Keyring

Securely store secrets.

This package provides a cross platform keyring using system APIs (macOS/keychain, Windows/wincred, Linux/SecretService) or filesystem, protected by a password derived key.

For more details visit keys.pub.

Example

// Initialize Keyring.
// You can use keyring.System, keyring.SystemOrFS, keyring.FS, keyring.Mem, git.NewRepository.
kr, err := keyring.New(keyring.System("AppName"))
if err != nil {
    log.Fatal(err)
}

// Setup keyring auth.
if err := kr.UnlockWithPassword("mypassword", true); err != nil {
    log.Fatal(err)
}

// Create item.
// Item IDs are NOT encrypted.
item := keyring.NewItem("id1", []byte("mysecret"), "", time.Now())
if err := kr.Create(item); err != nil {
    log.Fatal(err)
}

// Get item.
out, err := kr.Get("id1")
if err != nil {
    log.Fatal(err)
}
fmt.Printf("secret: %s\n", string(out.Data))

// List items.
items, err := kr.List()
if err != nil {
    log.Fatal(err)
}
for _, item := range items {
    fmt.Printf("%s: %v\n", item.ID, string(item.Data))
}

macOS

The Keychain API via the github.com/keybase/go-keychain package.

Windows

The Windows Credential Manager API via the github.com/danieljoos/wincred package.

Linux

The SecretService dbus interface via the github.com/zalando/go-keyring package. The SecretService dbus interface, which is provided by GNOME Keyring.

We are still exploring whether to use kwallet or libsecret directly for linux environments that support that instead. In the meantime, you can fall back to the FS based keyring.

FS

There is a filesystem based keyring for OS' that have no system keyring.

Mem

The is an in memory keyring for ephemeral keys or for testing.

Git

A git backed keyring allowing for backup/sync, see github.com/keys-pub/keysd/git.

Documentation

Overview

Package keyring provides a cross-platform secure keyring.

Index

Examples

Constants

View Source
const HiddenPrefix = "."

HiddenPrefix are hidden items.

View Source
const ReservedPrefix = "#"

ReservedPrefix are reserved items.

Variables

View Source
var ErrAlreadySetup = errors.New("keyring is already setup")

ErrAlreadySetup if already setup.

View Source
var ErrInvalidAuth = errors.New("invalid keyring auth")

ErrInvalidAuth if auth is invalid.

View Source
var ErrItemAlreadyExists = errors.New("keyring item already exists")

ErrItemAlreadyExists if item already exists trying to create.

View Source
var ErrItemNotFound = errors.New("keyring item not found")

ErrItemNotFound if item not found when trying to update.

View Source
var ErrItemValueTooLarge = errors.New("keyring item value is too large")

ErrItemValueTooLarge is item value is too large. Item.ID is max of 254 bytes. Item.Type is max of 32 bytes. Item.Data is max of 2048 bytes.

View Source
var ErrLocked = errors.New("keyring is locked")

ErrLocked if no keyring key is set.

Functions

func Backup added in v0.1.1

func Backup(path string, st Store, now time.Time) error

Backup Store into {path}.tgz.

func Copy

func Copy(from Store, to Store, opt ...CopyOption) ([]string, error)

Copy data from a keyring.Store to another keyring.Store. It copies raw data, it doesn't need to be unlocked. Doesn't overwrite existing data.

func Restore added in v0.1.1

func Restore(path string, st Store) error

Restore from path.tgz into Store.

func SetLogger

func SetLogger(l Logger)

SetLogger sets logger for the package.

Types

type AuthType

type AuthType string

AuthType describes an auth method.

const (
	// UnknownAuth ...
	UnknownAuth AuthType = ""
	// PasswordAuth ...
	PasswordAuth AuthType = "password"
	// FIDO2HMACSecretAuth ...
	FIDO2HMACSecretAuth AuthType = "fido2-hmac-secret" // #nosec
)

type CopyOption

type CopyOption func(*CopyOptions)

CopyOption ...

func DryRun

func DryRun() CopyOption

DryRun to pretend to copy.

func SkipExisting

func SkipExisting() CopyOption

SkipExisting to skip existing entries, otherwise error.

type CopyOptions

type CopyOptions struct {
	SkipExisting bool
	DryRun       bool
}

CopyOptions ...

type CreateEvent

type CreateEvent struct {
	ID string
}

CreateEvent when item is created.

type Event

type Event interface{}

Event from keyring.

type IDsOption

type IDsOption func(*IDsOptions)

IDsOption ...

func Hidden

func Hidden() IDsOption

Hidden ...

func Reserved

func Reserved() IDsOption

Reserved ...

func WithPrefix

func WithPrefix(prefix string) IDsOption

WithPrefix ...

func WithReservedPrefix

func WithReservedPrefix(prefix string) IDsOption

WithReservedPrefix ...

type IDsOptions

type IDsOptions struct {
	Prefix   string
	Hidden   bool
	Reserved bool
}

IDsOptions ...

func NewIDsOptions

func NewIDsOptions(opts ...IDsOption) IDsOptions

NewIDsOptions ...

type Item added in v0.1.18

type Item struct {
	// ID for item. IDs are NOT encrypted.
	ID string `msgpack:"id"`
	// Type for item data.
	Type string `msgpack:"typ"`
	// Data for item.
	Data []byte `msgpack:"dat"`
	// CreatedAt when item was created.
	CreatedAt time.Time `msgpack:"cts"`
}

Item is a keyring entry.

func DecryptItem

func DecryptItem(b []byte, secretKey SecretKey) (*Item, error)

DecryptItem returns Item from bytes.

func List

func List(st Store, key SecretKey, opts ...ListOption) ([]*Item, error)

List items from Store.

func NewItem

func NewItem(id string, b []byte, typ string, createdAt time.Time) *Item

NewItem creates an Item.

func (*Item) Encrypt

func (i *Item) Encrypt(secretKey SecretKey) ([]byte, error)

Encrypt item with a secret key.

type Keyring

type Keyring struct {
	// contains filtered or unexported fields
}

Keyring stores encrypted keyring items.

func New

func New(opt ...Option) (*Keyring, error)

New creates a new Keyring with backing Store.

Use keyring.System for the default system Store. On macOS this is the Keychain, on Windows wincred and linux SecretService.

Use keyring.SystemOrFS for the default system Store or fallback to FS. Use keyring.Mem for testing or ephemeral keys. Use keyring.FS for filesystem based keyring.

Example
package main

import (
	"fmt"
	"log"
	"time"

	"github.com/keys-pub/keys/keyring"
)

func main() {
	// Initialize Keyring.
	// You can use keyring.System(service), keyring.SystemOrFS(service), keyring.FS(service, dir), or keyring.Mem().
	kr, err := keyring.New(keyring.SystemOrFS("AppName"))
	if err != nil {
		log.Fatal(err)
	}
	// Remove this Reset() if you want to keep the Keyring.
	defer func() { _ = kr.Reset() }()
	// Setup keyring auth.
	if err := kr.UnlockWithPassword("mypassword", true); err != nil {
		log.Fatal(err)
	}

	// Create item.
	// Item IDs are NOT encrypted.
	item := keyring.NewItem("id1", []byte("mysecret"), "", time.Now())
	if err := kr.Create(item); err != nil {
		log.Fatal(err)
	}

	// Get item.
	out, err := kr.Get("id1")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("secret: %s\n", string(out.Data))

	// List items.
	items, err := kr.List()
	if err != nil {
		log.Fatal(err)
	}
	for _, item := range items {
		fmt.Printf("%s: %v\n", item.ID, string(item.Data))
	}

}
Output:

secret: mysecret
id1: mysecret

func NewMem

func NewMem(setup bool) *Keyring

NewMem returns an in memory Keyring useful for testing or ephemeral keys. The Keyring is unlocked (setup with a random key). If setup is true, the mem Keyring will be setup with a random key.

func (*Keyring) Create

func (k *Keyring) Create(item *Item) error

Create item. Requires Unlock(). Item IDs are not encrypted.

func (*Keyring) Delete

func (k *Keyring) Delete(id string) (bool, error)

Delete item. Doesn't require Unlock().

func (*Keyring) Deprovision

func (k *Keyring) Deprovision(id string) (bool, error)

Deprovision auth. Doesn't require Unlock().

func (*Keyring) Exists

func (k *Keyring) Exists(id string) (bool, error)

Exists returns true it has the id. Doesn't require Unlock().

func (*Keyring) Get

func (k *Keyring) Get(id string) (*Item, error)

Get item. Requires Unlock().

func (*Keyring) IDs

func (k *Keyring) IDs(opts ...IDsOption) ([]string, error)

IDs returns item IDs. Doesn't require Unlock().

func (*Keyring) List

func (k *Keyring) List(opts ...ListOption) ([]*Item, error)

List items. Requires Unlock(). Items with ids that start with "." or "#" are not returned by List. If you need to list IDs only, see Keyring.IDs.

func (*Keyring) Lock

func (k *Keyring) Lock() error

Lock the keyring.

func (*Keyring) MasterKey

func (k *Keyring) MasterKey() SecretKey

MasterKey returns master key, if unlocked. It's not recommended to use this key for anything other than possibly deriving new keys.

func (*Keyring) Provision

func (k *Keyring) Provision(key SecretKey, provision *Provision) error

Provision new auth. Requires Unlock().

func (*Keyring) Provisions

func (k *Keyring) Provisions() ([]*Provision, error)

Provisions are currently provisioned auth. Doesn't require Unlock().

func (*Keyring) Reset

func (k *Keyring) Reset() error

Reset keyring. Doesn't require Unlock().

func (*Keyring) Salt

func (k *Keyring) Salt() ([]byte, error)

Salt is default salt value, generated on first access and persisted until Reset(). This salt value is not encrypted in the keyring. Doesn't require Unlock().

func (*Keyring) SaveProvision

func (k *Keyring) SaveProvision(provision *Provision) error

SaveProvision for auth methods that need to store registration data before key is available (for example, FIDO2 hmac-secret).

func (*Keyring) SetMasterKey

func (k *Keyring) SetMasterKey(mk SecretKey)

SetMasterKey directly sets the master key. If the key is wrong this could leave the keyring in a weird state and should only be used in special circumstances. You probably want to use Setup or Unlock instead.

func (*Keyring) Setup

func (k *Keyring) Setup(key SecretKey, provision *Provision) error

Setup auth, if no auth exists. Returns ErrAlreadySetup if already setup. Doesn't require Unlock().

func (*Keyring) Status

func (k *Keyring) Status() (Status, error)

Status returns keyring status. Doesn't require Unlock().

func (*Keyring) Store

func (k *Keyring) Store() Store

Store used by Keyring.

func (*Keyring) Subscribe

func (k *Keyring) Subscribe(topic string) chan Event

Subscribe to topic.

func (*Keyring) Unlock

func (k *Keyring) Unlock(key SecretKey) (*Provision, error)

Unlock with auth. Returns provision used to unlock.

func (*Keyring) UnlockWithPassword

func (k *Keyring) UnlockWithPassword(password string, setup bool) error

UnlockWithPassword unlocks keyring with a password. If setup is true, we are setting up the keyring auth for the first time. This is a convenience method, calling Setup or Unlock with KeyForPassword using the keyring#Salt.

func (*Keyring) Unsubscribe

func (k *Keyring) Unsubscribe(topic string)

Unsubscribe from topic.

func (*Keyring) Update

func (k *Keyring) Update(id string, b []byte) error

Update item data. Requires Unlock().

type ListOption

type ListOption func(*ListOptions)

ListOption ...

func WithTypes

func WithTypes(types ...string) ListOption

WithTypes ...

type ListOptions

type ListOptions struct {
	Types []string
}

ListOptions ...

func NewListOptions

func NewListOptions(opts ...ListOption) ListOptions

NewListOptions ...

type LockEvent

type LockEvent struct{}

LockEvent when keyring is locked.

type LogLevel

type LogLevel int

LogLevel ...

const (
	// DebugLevel ...
	DebugLevel LogLevel = 3
	// InfoLevel ...
	InfoLevel LogLevel = 2
	// WarnLevel ...
	WarnLevel LogLevel = 1
	// ErrLevel ...
	ErrLevel LogLevel = 0
)

func (LogLevel) String

func (l LogLevel) String() string

type Logger

type Logger interface {
	Debugf(format string, args ...interface{})
	Infof(format string, args ...interface{})
	Warningf(format string, args ...interface{})
	Errorf(format string, args ...interface{})
	Fatalf(format string, args ...interface{})
}

Logger interface used in this package.

func NewLogger

func NewLogger(lev LogLevel) Logger

NewLogger ...

type Option

type Option func(*Options) error

Option ...

func FS

func FS(service string, dir string) Option

FS Store option.

func System

func System(service string) Option

System Store option.

func SystemOrFS

func SystemOrFS(service string) Option

SystemOrFS Store option.

func WithStore

func WithStore(st Store) Option

WithStore specifies Store to use with Keyring.

type Options

type Options struct {
	// contains filtered or unexported fields
}

Options ...

type Provision

type Provision struct {
	ID        string    `msgpack:"id"`
	Type      AuthType  `msgpack:"type"`
	CreatedAt time.Time `msgpack:"cts"`

	AAGUID string `msgpack:"aaguid"`
	Salt   []byte `msgpack:"salt"`
	NoPin  bool   `msgpack:"nopin"`
}

Provision is unencrypted provision and parameters used by client auth.

func NewProvision

func NewProvision(typ AuthType) *Provision

NewProvision creates a new provision.

type SecretKey

type SecretKey *[32]byte

SecretKey for encrypting items.

func KeyForPassword

func KeyForPassword(password string, salt []byte) (SecretKey, error)

KeyForPassword generates a key from a password and salt.

type Status

type Status string

Status for keyring.

const (
	// Unknown status.
	Unknown Status = ""
	// Setup if setup needed.
	Setup Status = "setup"
	// Unlocked if unlocked.
	Unlocked Status = "unlocked"
	// Locked if locked.
	Locked Status = "locked"
)

type Store

type Store interface {
	// Name of the Store implementation (keychain, wincred, secret-service, mem, fs, git).
	Name() string

	// Get bytes.
	Get(id string) ([]byte, error)
	// Set bytes.
	Set(id string, data []byte) error
	// Delete bytes.
	Delete(id string) (bool, error)

	// List IDs.
	IDs(opts ...IDsOption) ([]string, error)

	// Exists returns true if exists.
	Exists(id string) (bool, error)

	// Reset removes all items.
	Reset() error
}

Store is the interface that a Keyring uses to save data.

func Mem

func Mem() Store

Mem returns in memory keyring.Store.

func NewFS

func NewFS(service string, dir string) (Store, error)

NewFS returns keyring.Store backed by the filesystem.

func NewSystem

func NewSystem(service string) Store

NewSystem creates system Store.

func NewSystemOrFS

func NewSystemOrFS(service string) (Store, error)

NewSystemOrFS returns system keyring store or FS if unavailable. On linux, if dbus is not available, uses the filesystem at ~/.keyring.

type UnlockEvent

type UnlockEvent struct {
	Provision *Provision
}

UnlockEvent when keyring is unlocked.

type UpdateEvent

type UpdateEvent struct {
	ID string
}

UpdateEvent when item is updated.

Directories

Path Synopsis
cmd
keyring command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL