keyring

package module
v1.6.1 Latest Latest
Warning

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

Go to latest
Published: Jan 8, 2026 License: MIT Imports: 23 Imported by: 2

README

Keyring

Build Status Documentation

[!NOTE] This is a maintained fork of https://github.com/99designs/keyring which seems to be an abandoned project. Contributions are welcome, but keep in mind this is a side project and maintained on best effort basis!

Keyring provides a common interface to a range of secure credential storage services. Originally developed as part of AWS Vault, a command line tool for securely managing AWS access from developer workstations.

Currently Keyring supports the following backends

Usage

The short version of how to use keyring is shown below.

ring, _ := keyring.Open(keyring.Config{
  ServiceName: "example",
})

_ = ring.Set(keyring.Item{
	Key: "foo",
	Data: []byte("secret-bar"),
})

i, _ := ring.Get("foo")

fmt.Printf("%s", i.Data)

To configure TouchId biometrics:

keyring.Config.UseBiometrics = true
keyring.Config.TouchIDAccount = "cc.byteness.aws-vault.biometrics"
keyring.Config.TouchIDService = "aws-vault"

For more detail on the API please check the keyring godocs

Testing

Vagrant is used to create linux and windows test environments.

# Start vagrant
vagrant up

# Run go tests on all platforms
./bin/go-test

Contributing

Contributions to the keyring package are most welcome from engineers of all backgrounds and skill levels. In particular the addition of extra backends across popular operating systems would be appreciated.

This project will adhere to the Go Community Code of Conduct in the github provided discussion spaces, with the moderators being the part of ByteNess engineering team.

To make a contribution:

  • Fork the repository
  • Make your changes on the fork
  • Submit a pull request back to this repo with a clear description of the problem you're solving
  • Ensure your PR passes all current (and new) tests
  • Ideally verify that aws-vault works with your changes (optional)

...and we'll do our best to get your work merged in!

Documentation

Overview

Package keyring provides a uniform API over a range of desktop credential storage engines.

Index

Examples

Constants

View Source
const (
	KEYCTL_PERM_VIEW    = uint32(1 << 0)
	KEYCTL_PERM_READ    = uint32(1 << 1)
	KEYCTL_PERM_WRITE   = uint32(1 << 2)
	KEYCTL_PERM_SEARCH  = uint32(1 << 3)
	KEYCTL_PERM_LINK    = uint32(1 << 4)
	KEYCTL_PERM_SETATTR = uint32(1 << 5)
	KEYCTL_PERM_ALL     = uint32((1 << 6) - 1)

	KEYCTL_PERM_OTHERS  = 0
	KEYCTL_PERM_GROUP   = 8
	KEYCTL_PERM_USER    = 16
	KEYCTL_PERM_PROCESS = 24
)
View Source
const (
	OPEnvVaultID            = "OP_VAULT_ID"
	OPItemFieldTitle        = "keyring"
	OPItemTag               = "keyring"
	OPItemTitlePrefix       = "keyring"
	OPItemTitlePrefixKeySep = ": "
)
View Source
const (
	OPConnectEnvHost       = "OP_CONNECT_HOST"
	OPConnectEnvToken      = "OP_CONNECT_TOKEN"
	OPConnectItemCategory  = connectop.ApiCredential
	OPConnectItemFieldType = connectop.FieldTypeConcealed
)
View Source
const (
	OPStandardIntegrationName    = "keyring"
	OPStandardIntegrationVersion = "v1.0.0"
	OPStandardItemCategory       = onepassword.ItemCategoryAPICredentials
	OPStandardItemFieldType      = onepassword.ItemFieldTypeConcealed
)
View Source
const (
	OPDesktopEnvAccountID = "OP_DESKTOP_ACCOUNT_ID"
)
View Source
const (
	OPSrvAccountEnvToken = "OP_SERVICE_ACCOUNT_TOKEN"
)

Variables

View Source
var (
	ErrEnvUnsetOrEmpty = errors.New("Environment variable unset or empty")
	OPErrClient        = errors.New(
		"Unable to create a 1Password Connect / Service Accounts / Desktop Integration client",
	)
	OPErrItemMultiple       = errors.New("Found multiple matching 1Password items")
	OPErrItemTitleDuplicate = errors.New("Found duplicate 1Password item title")
	OPErrKeyring            = errors.New(
		"Unable to create a 1Password Connect / Service Accounts / Desktop Integration keyring",
	)
	OPErrTokenFuncNil = fmt.Errorf("%w: Token function is nil", OPErrClient)
	OPErrVaultID      = fmt.Errorf("%w: %w: %#v", OPErrKeyring, ErrEnvUnsetOrEmpty, OPEnvVaultID)
)
View Source
var (
	OPConnectErrHost = fmt.Errorf(
		"%w: %w: %#v",
		OPConnectErrKeyring,
		ErrEnvUnsetOrEmpty,
		OPConnectEnvHost,
	)
	OPConnectErrKeyring = errors.New("Unable to create a 1Password Connect keyring")
)
View Source
var (
	OPDesktopErrAccountID = fmt.Errorf(
		"%w: %w: %#v",
		OPDesktopErrKeyring,
		ErrEnvUnsetOrEmpty,
		OPDesktopEnvAccountID,
	)

	OPDesktopErrClient    = errors.New("Unable to create a 1Password Desktop client")
	OPDesktopErrKeyring   = errors.New("Unable to create a 1Password Desktop keyring")
	OPDesktopErrNewClient = fmt.Errorf(
		"%w: onepassword.NewClient returned an error",
		OPDesktopErrClient,
	)
	OPDesktopErrTimeout = fmt.Errorf(
		"%w: Timeout must be a non-zero duration",
		OPDesktopErrKeyring,
	)
)
View Source
var (
	OPSrvAccountErrClient    = errors.New("Unable to create a 1Password Service Accounts client")
	OPSrvAccountErrKeyring   = errors.New("Unable to create a 1Password Service Accounts keyring")
	OPSrvAccountErrNewClient = fmt.Errorf(
		"%w: onepassword.NewClient returned an error",
		OPSrvAccountErrClient,
	)
	OPSrvAccountErrTimeout = fmt.Errorf(
		"%w: Timeout must be a non-zero duration",
		OPSrvAccountErrKeyring,
	)
)
View Source
var (
	// Debug specifies whether to print debugging output.
	Debug bool
)
View Source
var ErrKeyNotFound = errors.New("The specified item could not be found in the keyring")

ErrKeyNotFound is returned by Keyring Get when the item is not on the keyring.

View Source
var ErrMetadataNeedsCredentials = errors.New("The keyring backend requires credentials for metadata access")

ErrMetadataNeedsCredentials is returned when Metadata is called against a backend which requires credentials even to see metadata.

View Source
var ErrMetadataNotSupported = errors.New("The keyring backend does not support metadata access")

ErrMetadataNotSupported is returned when Metadata is not available for the backend.

View Source
var ErrNoAvailImpl = errors.New("Specified keyring backend not available")

ErrNoAvailImpl is returned by Open when a backend cannot be found.

Functions

func ExpandTilde

func ExpandTilde(dir string) (string, error)

ExpandTilde will expand tilde (~/ or ~\ depending on OS) for the user home directory.

func GetKeyringIDForScope

func GetKeyringIDForScope(scope string) (int32, error)

GetKeyringIDForScope get the keyring ID for a given scope.

func GetPermissions

func GetPermissions(process, user, group, others uint32) uint32

GetPermissions constructs the permission mask from the elements.

func TerminalPrompt

func TerminalPrompt(prompt string) (string, error)

Types

type ArrayKeyring

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

ArrayKeyring is a mock/non-secure backend that meets the Keyring interface. It is intended to be used to aid unit testing of code that relies on the package. NOTE: Do not use in production code.

func NewArrayKeyring

func NewArrayKeyring(initial []Item) *ArrayKeyring

NewArrayKeyring returns an ArrayKeyring, optionally constructed with an initial slice of items.

func (*ArrayKeyring) Get

func (k *ArrayKeyring) Get(key string) (Item, error)

Get returns an Item matching Key.

func (*ArrayKeyring) GetMetadata

func (k *ArrayKeyring) GetMetadata(_ string) (Metadata, error)

func (*ArrayKeyring) Keys

func (k *ArrayKeyring) Keys() ([]string, error)

Keys provides a slice of all Item keys on the Keyring.

func (*ArrayKeyring) Remove

func (k *ArrayKeyring) Remove(key string) error

Remove will delete an Item from the Keyring.

func (*ArrayKeyring) Set

func (k *ArrayKeyring) Set(i Item) error

Set will store an item on the mock Keyring.

type BackendType

type BackendType string

BackendType is an identifier for a credential storage service.

const (
	InvalidBackend       BackendType = ""
	SecretServiceBackend BackendType = "secret-service"
	KeychainBackend      BackendType = "keychain"
	KeyCtlBackend        BackendType = "keyctl"
	KWalletBackend       BackendType = "kwallet"
	WinCredBackend       BackendType = "wincred"
	FileBackend          BackendType = "file"
	PassBackend          BackendType = "pass"
	OPBackend            BackendType = "op"
	OPConnectBackend     BackendType = "op-connect"
	OPDesktopBackend     BackendType = "op-desktop"
)

All currently supported secure storage backends.

func AvailableBackends

func AvailableBackends() []BackendType

AvailableBackends provides a slice of all available backend keys on the current OS.

type Config

type Config struct {
	// AllowedBackends is a whitelist of backend providers that can be used. Nil means all available.
	AllowedBackends []BackendType

	// ServiceName is a generic service name that is used by backends that support the concept
	ServiceName string

	// MacOSKeychainNameKeychainName is the name of the macOS keychain that is used
	KeychainName string

	// KeychainTrustApplication is whether the calling application should be trusted by default by items
	KeychainTrustApplication bool

	// KeychainSynchronizable is whether the item can be synchronized to iCloud
	KeychainSynchronizable bool

	// KeychainAccessibleWhenUnlocked is whether the item is accessible when the device is locked
	KeychainAccessibleWhenUnlocked bool

	// KeychainPasswordFunc is an optional function used to prompt the user for a password
	KeychainPasswordFunc PromptFunc

	// FilePasswordFunc is a required function used to prompt the user for a password
	FilePasswordFunc PromptFunc

	// FileDir is the directory that keyring files are stored in, ~/ is resolved to the users' home dir
	FileDir string

	// KeyCtlScope is the scope of the kernel keyring (either "user", "session", "process" or "thread")
	KeyCtlScope string

	// KeyCtlPerm is the permission mask to use for new keys
	KeyCtlPerm uint32

	// KWalletAppID is the application id for KWallet
	KWalletAppID string

	// KWalletFolder is the folder for KWallet
	KWalletFolder string

	// LibSecretCollectionName is the name collection in secret-service
	LibSecretCollectionName string

	// PassDir is the pass password-store directory, ~/ is resolved to the users' home dir
	PassDir string

	// PassCmd is the name of the pass executable
	PassCmd string

	// PassPrefix is a string prefix to prepend to the item path stored in pass
	PassPrefix string

	// WinCredPrefix is a string prefix to prepend to the key name
	WinCredPrefix string

	// UseBiometrics is whether to use biometrics (where available) to unlock the keychain
	UseBiometrics bool

	// TouchIDAccount is the name of the account that we store the unlock password in keychain
	TouchIDAccount string

	// TouchIDService is the name of the service that we store the unlock password in keychain
	TouchIDService string

	// OPTimeout is the timeout for 1Password API operations (1Password Service Accounts only)
	OPTimeout time.Duration

	// OPVaultID is the UUID of the 1Password vault
	OPVaultID string

	// OPItemTitlePrefix is the prefix to prepend to 1Password item titles
	OPItemTitlePrefix string

	// OPItemTag is the tag to apply to 1Password items
	OPItemTag string

	// OPItemFieldTitle is the title of the 1Password item field
	OPItemFieldTitle string

	// OPConnectHost is the 1Password Connect server HTTP(S) URI
	OPConnectHost string

	// OPConnectTokenEnv is the primary environment variable from which to look up the 1Password Connect token
	OPConnectTokenEnv string

	// OPTokenEnv is the primary environment variable from which to look up the 1Password service account token
	OPTokenEnv string

	// OPTokenFunc is the function used to prompt the user for the 1Password Connect / service account token
	OPTokenFunc PromptFunc

	// OPDesktopAccountID is the 1Password account name or UUIDj for Desktop Integration (1Password Desktop App only)
	OPDesktopAccountID string
}

Config contains configuration for keyring.

type Item

type Item struct {
	Key         string
	Data        []byte
	Label       string
	Description string

	// Backend specific config
	KeychainNotTrustApplication bool
	KeychainNotSynchronizable   bool
}

Item is a thing stored on the keyring.

type Keyring

type Keyring interface {
	// Returns an Item matching the key or ErrKeyNotFound
	Get(key string) (Item, error)
	// Returns the non-secret parts of an Item
	GetMetadata(key string) (Metadata, error)
	// Stores an Item on the keyring
	Set(item Item) error
	// Removes the item with matching key
	Remove(key string) error
	// Provides a slice of all keys stored on the keyring
	Keys() ([]string, error)
}

Keyring provides the uniform interface over the underlying backends.

func Open

func Open(cfg Config) (Keyring, error)

Open will open a specific keyring backend.

Example
package main

import (
	"log"

	"github.com/byteness/keyring"
)

func main() {
	// Use the best keyring implementation for your operating system
	kr, err := keyring.Open(keyring.Config{
		ServiceName:    "my-service",
		UseBiometrics:  true,
		TouchIDAccount: "cc.byteness.aws-vault.biometrics",
		TouchIDService: "aws-vault",
	})
	if err != nil {
		log.Fatal(err)
	}

	v, err := kr.Get("llamas")
	if err != nil {
		log.Fatal(err)
	}

	log.Printf("llamas was %v", v)
}

type Metadata

type Metadata struct {
	*Item
	ModificationTime time.Time
}

Metadata is information about a thing stored on the keyring; retrieving metadata must not require authentication. The embedded Item should be filled in with an empty Data field. It's allowed for Item to be a nil pointer, indicating that all we have is the timestamps.

type OPBaseKeyring added in v1.4.0

type OPBaseKeyring struct {
	VaultID         string
	ItemTitlePrefix string
	ItemTag         string
	ItemFieldTitle  string
	TokenEnvs       []string
	TokenFunc       PromptFunc
}

func (*OPBaseKeyring) GetItemFromOPItemFieldValue added in v1.4.0

func (k *OPBaseKeyring) GetItemFromOPItemFieldValue(opItemFieldValue string) (*Item, error)

func (*OPBaseKeyring) GetKeyFromOPItemTitle added in v1.4.0

func (k *OPBaseKeyring) GetKeyFromOPItemTitle(opItemTitle string) string

func (*OPBaseKeyring) GetOPItemFieldValueFromItem added in v1.4.0

func (k *OPBaseKeyring) GetOPItemFieldValueFromItem(item *Item) (string, error)

func (*OPBaseKeyring) GetOPItemTitleFromKey added in v1.4.0

func (k *OPBaseKeyring) GetOPItemTitleFromKey(key string) string

func (*OPBaseKeyring) GetOPToken added in v1.4.0

func (k *OPBaseKeyring) GetOPToken(prompt string) (string, error)

type OPConnectClientAPI added in v1.4.0

type OPConnectClientAPI interface {
	CreateItem(item *connectop.Item, vaultQuery string) (*connectop.Item, error)
	DeleteItemByID(itemUUID string, vaultQuery string) error
	GetItemByUUID(uuid string, vaultQuery string) (*connectop.Item, error)
	GetItems(vaultQuery string) ([]connectop.Item, error)
	GetItemsByTitle(title string, vaultQuery string) ([]connectop.Item, error)
	UpdateItem(item *connectop.Item, vaultQuery string) (*connectop.Item, error)
}

type OPConnectKeyring added in v1.4.0

type OPConnectKeyring struct {
	OPBaseKeyring
	Host   string
	Client OPConnectClientAPI
}

func NewOPConnectKeyring added in v1.4.0

func NewOPConnectKeyring(cfg *Config) (*OPConnectKeyring, error)

func (OPConnectKeyring) Get added in v1.4.0

func (k OPConnectKeyring) Get(key string) (Item, error)

func (OPConnectKeyring) GetMetadata added in v1.4.0

func (k OPConnectKeyring) GetMetadata(key string) (Metadata, error)

func (*OPConnectKeyring) GetOPItem added in v1.4.0

func (k *OPConnectKeyring) GetOPItem(key string) (*onepassword.Item, error)

func (*OPConnectKeyring) GetOPItems added in v1.4.0

func (k *OPConnectKeyring) GetOPItems() ([]onepassword.Item, error)

func (*OPConnectKeyring) InitializeOPConnectClient added in v1.4.0

func (k *OPConnectKeyring) InitializeOPConnectClient() error

func (OPConnectKeyring) Keys added in v1.4.0

func (k OPConnectKeyring) Keys() ([]string, error)

func (*OPConnectKeyring) PruneAndHydrateOPItemOverviews added in v1.4.0

func (k *OPConnectKeyring) PruneAndHydrateOPItemOverviews(
	opConnectItemOverviews []connectop.Item,
) ([]onepassword.Item, error)

func (OPConnectKeyring) Remove added in v1.4.0

func (k OPConnectKeyring) Remove(key string) error

func (OPConnectKeyring) Set added in v1.4.0

func (k OPConnectKeyring) Set(item Item) error

type OPDesktopKeyring added in v1.5.0

type OPDesktopKeyring struct {
	OPStandardKeyring
	DesktopAccountID string
	// contains filtered or unexported fields
}

OPDesktopKeyring implements Keyring interface for 1Password Desktop Integration

func NewOPDesktopKeyring added in v1.5.0

func NewOPDesktopKeyring(cfg *Config) (*OPDesktopKeyring, error)

func (*OPDesktopKeyring) Get added in v1.5.0

func (k *OPDesktopKeyring) Get(key string) (Item, error)

Get retrieves an item by key

func (*OPDesktopKeyring) GetMetadata added in v1.5.0

func (k *OPDesktopKeyring) GetMetadata(key string) (Metadata, error)

GetMetadata returns metadata for a key

func (*OPDesktopKeyring) InitializeClient added in v1.5.0

func (k *OPDesktopKeyring) InitializeClient() error

InitializeClient initializes the Desktop Integration client

func (*OPDesktopKeyring) Keys added in v1.5.0

func (k *OPDesktopKeyring) Keys() ([]string, error)

Keys returns all keys in the keyring

func (*OPDesktopKeyring) Remove added in v1.5.0

func (k *OPDesktopKeyring) Remove(key string) error

Remove deletes an item by key

func (*OPDesktopKeyring) Set added in v1.5.0

func (k *OPDesktopKeyring) Set(item Item) error

Set creates or updates an item

type OPKeyringAPI added in v1.4.0

type OPKeyringAPI interface {
	Keyring
	GetItemFromOPItemFieldValue(opItemFieldValue string) (*Item, error)
	GetKeyFromOPItemTitle(opItemTitle string) string
	GetOPItem(key string) (*onepassword.Item, error)
	GetOPItemFieldValueFromItem(item *Item) (string, error)
	GetOPItems() ([]onepassword.Item, error)
	GetOPItemTitleFromKey(key string) string
	GetOPToken(prompt string) (string, error)
}

type OPSrvAccountKeyring added in v1.5.0

type OPSrvAccountKeyring struct {
	OPStandardKeyring
	// contains filtered or unexported fields
}

OPSrvAccountKeyring implements Keyring interface for 1Password Service Accounts

func NewOPSrvAccountKeyring added in v1.5.0

func NewOPSrvAccountKeyring(cfg *Config) (*OPSrvAccountKeyring, error)

NewOPSrvAccountKeyring creates a new Service Account keyring

func (*OPSrvAccountKeyring) Get added in v1.5.0

func (k *OPSrvAccountKeyring) Get(key string) (Item, error)

Get retrieves an item by key

func (*OPSrvAccountKeyring) GetMetadata added in v1.5.0

func (k *OPSrvAccountKeyring) GetMetadata(key string) (Metadata, error)

GetMetadata returns metadata for a key

func (*OPSrvAccountKeyring) InitializeClient added in v1.5.0

func (k *OPSrvAccountKeyring) InitializeClient() error

InitializeClient initializes the Service Account client

func (*OPSrvAccountKeyring) Keys added in v1.5.0

func (k *OPSrvAccountKeyring) Keys() ([]string, error)

Keys returns all keys in the keyring

func (*OPSrvAccountKeyring) Remove added in v1.5.0

func (k *OPSrvAccountKeyring) Remove(key string) error

Remove deletes an item by key

func (*OPSrvAccountKeyring) Set added in v1.5.0

func (k *OPSrvAccountKeyring) Set(item Item) error

Set creates or updates an item

type OPStandardClientAPI added in v1.4.0

type OPStandardClientAPI interface {
	Create(ctx context.Context, params onepassword.ItemCreateParams) (onepassword.Item, error)
	Delete(ctx context.Context, vaultID string, itemID string) error
	Get(ctx context.Context, vaultID string, itemID string) (onepassword.Item, error)
	List(
		ctx context.Context,
		vaultID string,
		filters ...onepassword.ItemListFilter,
	) ([]onepassword.ItemOverview, error)
	Put(ctx context.Context, item onepassword.Item) (onepassword.Item, error)
}

type OPStandardKeyring added in v1.4.0

type OPStandardKeyring struct {
	OPBaseKeyring
	Timeout time.Duration
	Client  OPStandardClientAPI
}

OPStandardKeyring contains shared logic for all onepassword-sdk-go based backends

func (OPStandardKeyring) Get added in v1.4.0

func (k OPStandardKeyring) Get(key string) (Item, error)

func (OPStandardKeyring) GetMetadata added in v1.4.0

func (k OPStandardKeyring) GetMetadata(key string) (Metadata, error)

func (*OPStandardKeyring) GetOPItem added in v1.4.0

func (k *OPStandardKeyring) GetOPItem(key string) (*onepassword.Item, error)

func (*OPStandardKeyring) GetOPItems added in v1.4.0

func (k *OPStandardKeyring) GetOPItems() ([]onepassword.Item, error)

func (OPStandardKeyring) Keys added in v1.4.0

func (k OPStandardKeyring) Keys() ([]string, error)

func (OPStandardKeyring) Remove added in v1.4.0

func (k OPStandardKeyring) Remove(key string) error

func (OPStandardKeyring) Set added in v1.4.0

func (k OPStandardKeyring) Set(item Item) error

type PromptFunc

type PromptFunc func(string) (string, error)

PromptFunc is a function used to prompt the user for a password.

func FixedStringPrompt

func FixedStringPrompt(value string) PromptFunc

Directories

Path Synopsis
cmd
keyring command

Jump to

Keyboard shortcuts

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