Documentation
¶
Overview ¶
Package secretstore holds the secrets a request references by placeholder (#2051): the record an administrator writes, the rules it is held to, its PostgreSQL store with the value encrypted, and the lookup the api gateway fills a placeholder through.
The value is write-only. No method returns it except the lookup, which the gateway calls as it sends a request, and the lookup reads it from the database on every call, so a rotated value is used from the next call on.
A secret is one of two kinds (#2065): a value, sent where {{secret:<name>}} is written, or an authenticator seed, never sent, whose current one-time code is sent where {{totp:<name>}} is written.
Index ¶
- Constants
- Variables
- func Allowed(sec Secret, connection, persona string) error
- func ConnectionAllowed(sec Secret, connection string) error
- func Validate(w Write, creating bool) error
- type CurrentCode
- type Encryptor
- type Secret
- type Source
- type Store
- func (s *Store) Code(ctx context.Context, name string) (CurrentCode, error)
- func (s *Store) ConnectionValue(ctx context.Context, name, connection string) (string, error)
- func (s *Store) Delete(ctx context.Context, name string) error
- func (s *Store) Get(ctx context.Context, name string) (Secret, error)
- func (s *Store) List(ctx context.Context) ([]Secret, error)
- func (s *Store) Lookup(ctx context.Context, connection, persona string) secretref.Lookup
- func (s *Store) Put(ctx context.Context, w Write) (Secret, bool, error)
- func (s *Store) WithAdmin(persona string) *Store
- func (s *Store) WithClock(now func() time.Time, sleep func(ctx context.Context, d time.Duration) error) *Store
- type Write
Constants ¶
const ( // KindValue is sent as written where {{secret:<name>}} is. KindValue = "value" // KindTOTP is an authenticator seed (RFC 6238): never sent, and its // current code is sent where {{totp:<name>}} is (#2065). KindTOTP = "totp" )
The kinds a secret may be.
const ( MaxValueBytes = 64 * 1024 MaxDescriptionBytes = 1000 )
Limits on what a write may carry.
Variables ¶
var ErrInvalid = errors.New("invalid secret")
ErrInvalid is wrapped by every refusal of a write.
var ErrNotFound = errors.New("secret not found")
ErrNotFound is returned for a name no secret is stored under.
var ErrNotTOTP = errors.New("not an authenticator seed")
ErrNotTOTP is returned for a current code of a value secret.
Functions ¶
func ConnectionAllowed ¶ added in v1.142.0
ConnectionAllowed refuses sec to the configuration of a connection it may not be used by: one its allow_connections does not list, or any connection at all while it names personas, since a connection's credential serves every persona that uses the connection. The admin API asks it when a connection configuration naming the secret is saved (#2066), and the read at send time asks it again, so a secret rescoped afterwards is refused from the next request on.
Types ¶
type CurrentCode ¶ added in v1.142.0
type CurrentCode struct {
Code string `json:"code" example:"287082"`
SecondsLeft int `json:"seconds_left" example:"17"`
Params totp.Params `json:"totp"`
}
CurrentCode is a totp secret's code for this moment and how many seconds of its period are left, for an administrator to compare with the phone app before an automation depends on the secret. Showing it issues nothing: the next fill may send the same code.
type Encryptor ¶
type Encryptor interface {
Encrypt(plaintext string) (string, error)
Decrypt(ciphertext string) (string, error)
}
Encryptor encrypts and decrypts one value. fieldcrypt.RestFieldEncryptor satisfies it; a nil one stores values as written.
type Secret ¶
type Secret struct {
Name string `json:"name"`
Description string `json:"description"`
// Kind is "value" or "totp".
Kind string `json:"kind" enums:"value,totp"`
// TOTP is a totp secret's code parameters, read from the otpauth URI it
// was saved as; absent for a value secret. The seed is never returned.
TOTP *totp.Params `json:"totp,omitempty"`
AllowConnections []string `json:"allow_connections"`
AllowPersonas []string `json:"allow_personas"`
CreatedBy string `json:"created_by"`
UpdatedBy string `json:"updated_by"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
Secret is a stored secret as every reader but the gateway sees it: what it is for and where it may go, never its value.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store persists secrets in gateway_secrets.
func (*Store) ConnectionValue ¶ added in v1.142.0
ConnectionValue reads a secret a connection's own configuration names, rather than a call's placeholder: the key file of a Google service account (#2061), or a {{secret:<name>}} in a credential field (#2066). The value is the connection's credential for every caller, so allow_connections must list the connection, and allow_personas must be empty: the token one key mints is cached and served to every persona the connection serves, so a key cannot be limited to some of them.
func (*Store) Lookup ¶
Lookup returns the lookup one call fills its placeholders through: a secret is answered only when connection is in its allow_connections and, when it names personas, persona is one of them or the administrator persona. allow_connections holds for every caller: it is where the value may go, not who may ask. Every refusal names the secret and says what would allow it. A name is read once per call however many placeholders name it.
A {{totp:<name>}} placeholder is asked for as secretref.TOTPName(name) and answered with a one-time code (#2065): the seed is recorded on ctx's Redactor so a response that echoes it is redacted, and the code is issued once per period (issueCode). Every placeholder naming the same secret in one call gets the same code.
func (*Store) Put ¶
Put creates or updates a secret and returns it as stored, and whether it was created.
func (*Store) WithAdmin ¶
WithAdmin names the administrator persona the lookup lets through allow_personas, and returns the store.
func (*Store) WithClock ¶ added in v1.142.0
func (s *Store) WithClock(now func() time.Time, sleep func(ctx context.Context, d time.Duration) error) *Store
WithClock replaces the clock and the wait a one-time code is issued by, and returns the store. A test passes a clock it moves itself, so no test waits out a period.
type Write ¶
type Write struct {
Name string
Description string
Kind string
Value *string
AllowConnections []string
AllowPersonas []string
Actor string
}
Write is one create or update. Value nil on an update keeps the stored value, so an administrator can rescope a secret without retyping it. Kind empty is a value secret on a create and the stored kind on an update; a totp secret's Value is an otpauth://totp URI or a bare base32 seed.