Documentation

Overview

    Package secrets provides an interface for a simple secret store: you ask it for a secret (a byte blob, identifies by some key), and it returns it to you (current version, as well as a bunch of previous versions). Caller are supposed to use the secret for an operation and then forget it (e.g. do not try to store it elsewhere).

    Secure storage, retrieval and rotation of secrets is outside of the scope of this interface: it's the responsibility of the implementation.

    Index

    Constants

    This section is empty.

    Variables

    View Source
    var (
    	// ErrNoStoreConfigured is returned by GetSecret if secret store is not in
    	// the context.
    	ErrNoStoreConfigured = errors.New("secrets.Store is not in the context")
    )
    View Source
    var (
    	// ErrNoSuchSecret is returned by Store.GetSecret if it can't find a secret.
    	ErrNoSuchSecret = errors.New("secret not found")
    )
    View Source
    var ModuleName = module.RegisterName("go.chromium.org/luci/server/secrets")

      ModuleName can be used to refer to this module when declaring dependencies.

      Functions

      func NewModule

      func NewModule(opts *ModuleOptions) module.Module

        NewModule returns a server module that adds a secret store to the global server context.

        Uses a DerivedStore with the root secret populated based on the supplied options. When the server starts, the module reads the initial root secret (if provided) and launches a job to periodically reread it.

        An error to read the secret during the startup is fatal. But if the server managed to start successfully and can't re-read the secret later (e.g. the file disappeared), it logs the error and keeps using the cached secret.

        func NewModuleFromFlags

        func NewModuleFromFlags() module.Module

          NewModuleFromFlags is a variant of NewModule that initializes options through command line flags.

          Calling this function registers flags in flag.CommandLine. They are usually parsed in server.Main(...).

          func Set

            Set injects the Store object in the context to be returned by Get as is.

            func SetFactory

            func SetFactory(c context.Context, f Factory) context.Context

              SetFactory sets the function to produce Store instances when Get(c) is used.

              Types

              type DerivedStore

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

                DerivedStore implements Store by deriving secrets from some single master secret using HKDF.

                Caches all derived secrets internally forever. Assumes the set of possible key names is limited.

                func NewDerivedStore

                func NewDerivedStore(root Secret) *DerivedStore

                  NewDerivedStore returns a store that derives secrets from the given root key.

                  func (*DerivedStore) GetSecret

                  func (d *DerivedStore) GetSecret(name string) (Secret, error)

                    GetSecret returns a generated secret given its key.

                    func (*DerivedStore) SetRoot

                    func (d *DerivedStore) SetRoot(root Secret)

                      SetRoot replaces the root key used to derive secrets.

                      type Factory

                      type Factory func(context.Context) Store

                        Factory knows how to make a new Store.

                        type FileSource

                        type FileSource struct {
                        	Path string
                        }

                          FileSource reads the secret from a JSON file on disk.

                          func (*FileSource) Close

                          func (s *FileSource) Close() error

                            Close is part of Source interface.

                            func (*FileSource) ReadSecret

                            func (s *FileSource) ReadSecret(context.Context) (*Secret, error)

                              ReadSecret is part of Source interface.

                              type ModuleOptions

                              type ModuleOptions struct {
                              	// RootSecret points to the root secret key used to derive all other secrets.
                              	//
                              	// It can be either a local file system path, a reference to a Google Secret
                              	// Manager secret (in a form "sm://<project>/<secret>"), or a literal secret
                              	// value (in a form "devsecret://<base64-encoded secret>"). The latter is
                              	// supposed to be used **only** during development (e.g. locally or in
                              	// development deployments).
                              	//
                              	// When it is a local file system path, it should point to a JSON file with
                              	// the following structure (see Secret struct):
                              	//
                              	//   {
                              	//     "current": <base64-encoded blob>,
                              	//     "previous": [<base64-encoded blob>, <base64-encoded blob>, ...]
                              	//   }
                              	//
                              	// When using Google Secret Manager, the secret version "latest" is used to
                              	// get the current value of the secret, and a single immediately preceding
                              	// previous version (if it is still enabled) is used to get the previous
                              	// version of the secret. This allows graceful rotation of secrets.
                              	RootSecret string
                              
                              	// Source produces the root secret to use by the module.
                              	//
                              	// If given, overrides RootSecret. This is useful when the secrets module
                              	// is initialized programmatically rather than through flags.
                              	//
                              	// The module will periodically use Source's ReadSecret to refresh the root
                              	// secret it stores in memory. This allows the secret to be rotated without
                              	// restarting all servers that use it.
                              	Source Source
                              }

                                ModuleOptions contain configuration of the secrets server module.

                                func (*ModuleOptions) Register

                                func (o *ModuleOptions) Register(f *flag.FlagSet)

                                  Register registers the command line flags.

                                  type Secret

                                  type Secret struct {
                                  	Current  []byte   `json:"current"`            // current value of the secret, always set
                                  	Previous [][]byte `json:"previous,omitempty"` // optional list of previous values, most recent first
                                  }

                                    Secret represents a current value of a secret as well as a set of few previous values. Previous values are important when key is being rotated: there may be valid outstanding derivatives of previous values of the secret.

                                    func GetSecret

                                    func GetSecret(c context.Context, key string) (Secret, error)

                                      GetSecret is a shortcut for grabbing a Store from the context and using its GetSecret method.

                                      If the context doesn't have Store set, returns ErrNoStoreConfigured.

                                      func (Secret) Blobs

                                      func (s Secret) Blobs() [][]byte

                                        Blobs returns current blob and all previous blobs as one array.

                                        func (Secret) Equal

                                        func (s Secret) Equal(a Secret) bool

                                          Equal returns true if secrets are equal.

                                          Does *not* run in constant time. Shouldn't be used in a cryptographic context due to susceptibility to timing attacks.

                                          type SecretManagerSource

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

                                            SecretManagerSource is a Source that uses Google Secret Manager.

                                            Construct it with NewSecretManagerSource.

                                            func NewSecretManagerSource

                                            func NewSecretManagerSource(ctx context.Context, secretURL string, ts oauth2.TokenSource) (*SecretManagerSource, error)

                                              NewSecretManagerSource parses "sm://<project>/<name>" and sets up the source that fetches the latest two versions of this GSM secret as a single *Secret.

                                              Uses the given TokenSource for authentication.

                                              func (*SecretManagerSource) Close

                                              func (s *SecretManagerSource) Close() error

                                                Close is part of Source interface.

                                                func (*SecretManagerSource) ReadSecret

                                                func (s *SecretManagerSource) ReadSecret(ctx context.Context) (*Secret, error)

                                                  ReadSecret is part of Source interface.

                                                  type Source

                                                  type Source interface {
                                                  	// ReadSecret returns the most recent value of the secret in the source.
                                                  	ReadSecret(context.Context) (*Secret, error)
                                                  	// Close releases any allocated resources.
                                                  	Close() error
                                                  }

                                                    Source knows how to fetch (and refetch) a secret from some fixed location.

                                                    type StaticSource

                                                    type StaticSource struct {
                                                    	Secret *Secret
                                                    }

                                                      StaticSource is a Source that returns the same static secret all the time.

                                                      func (*StaticSource) Close

                                                      func (s *StaticSource) Close() error

                                                        Close is part of Source interface.

                                                        func (*StaticSource) ReadSecret

                                                        func (s *StaticSource) ReadSecret(context.Context) (*Secret, error)

                                                          ReadSecret is part of Source interface.

                                                          type StaticStore

                                                          type StaticStore map[string]Secret

                                                            StaticStore is Store with predefined secrets.

                                                            func (StaticStore) GetSecret

                                                            func (s StaticStore) GetSecret(k string) (Secret, error)

                                                              GetSecret returns a secret given its key or ErrNoSuchSecret if no such secret exists.

                                                              The caller must not mutate the secret.

                                                              type Store

                                                              type Store interface {
                                                              	// GetSecret returns a secret given its key.
                                                              	//
                                                              	// Store may choose to autogenerate a secret if there's no existing one, or it
                                                              	// may choose to treat it as a error and return ErrNoSuchSecret.
                                                              	GetSecret(name string) (Secret, error)
                                                              }

                                                                Store knows how to retrieve (or autogenerate) a secret given its key.

                                                                func Get

                                                                func Get(c context.Context) Store

                                                                  Get grabs a Store by calling Factory stored in the context. If one hasn't been set, it returns nil.

                                                                  Directories

                                                                  Path Synopsis
                                                                  Package testsecrets provides a dumb in-memory secret store to use in unit tests.
                                                                  Package testsecrets provides a dumb in-memory secret store to use in unit tests.