Documentation
¶
Overview ¶
agent.go implements pipeline.KeyAgent: the out-of-band handler for failed upstream keys. The request loop calls OnFailure and obeys the verdict; all the secret-shaped concerns — re-resolution, single-flight de-duplication, park-and-wait, healing the snapshot, alerting — live here, off the request's import graph. The pipeline imports only the KeyAgent interface, never this.
Package secret is the Postgres-backed implementation of pkg/secret's storage seam: the secret_values table holding AES-GCM ciphertext for the "stored" backend. It satisfies pkg/secret.Store (Get/Put), .Rotator (transactional re-encryption), and .MaxVersioner, so the pure pkg/secret.StoredResolver can drive resolution, creation, and rotation without importing storage.
Index ¶
- func Wire(q *gen.Queries, pool *pgxpool.Pool, masterKey []byte) (*pkgsecret.Registry, *pkgsecret.StoredResolver)
- type Agent
- type Refresher
- type Store
- func (s *Store) Delete(ctx context.Context, id string) error
- func (s *Store) Get(ctx context.Context, id string) (ciphertext, nonce []byte, keyVersion int32, err error)
- func (s *Store) MaxKeyVersion(ctx context.Context) (int32, error)
- func (s *Store) Put(ctx context.Context, id string, ciphertext, nonce []byte, keyVersion int32) error
- func (s *Store) Rotate(ctx context.Context, newKeyVersion int32, ...) (int, error)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Wire ¶
func Wire(q *gen.Queries, pool *pgxpool.Pool, masterKey []byte) (*pkgsecret.Registry, *pkgsecret.StoredResolver)
Wire builds the relay's secret-resolution stack over Postgres: the secret_values store, a StoredResolver (AES-GCM, master-key holder), and a Registry wiring the built-in env + stored backends. The returned StoredResolver is the rotation/version authority; the Registry is the resolve entry point. Both share one StoredResolver instance, so a rotation swaps the live key for every consumer.
masterKey may be nil for env-only deployments — stored resolution then errors loudly, which is the intended behavior when no key is configured. Optional external backends (Bitwarden, AWS SM, GCP SM, …) register here when their env config is present.
Types ¶
type Agent ¶
type Agent struct {
// contains filtered or unexported fields
}
Agent implements pipeline.KeyAgent. On an auth failure it single-flights a secret re-resolve: when other candidates remain it heals in the background and tells the request to fail over (never waits); when this was the last candidate it parks on the re-resolve and retries the same key if the secret had rotated.
type Refresher ¶
type Refresher interface {
Refresh(ctx context.Context, keyID string) (value string, changed bool, err error)
}
Refresher re-resolves a host key's secret from its backend and persists the fresh value (so later requests see it), returning the value and whether it changed. Implemented at composition over the hostkey store + catalog.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store persists stored-secret ciphertext in the secret_values table. The pool is required for Rotate's transaction; pass nil only in tests that don't rotate.
func (*Store) Delete ¶
Delete removes a stored secret. Called when a HostKey switches away from stored mode or is deleted.
func (*Store) Rotate ¶
func (s *Store) Rotate(ctx context.Context, newKeyVersion int32, reencrypt func(ct, nonce []byte) (newCt, newNonce []byte, err error)) (int, error)
Rotate re-encrypts every secret_values row within one transaction, stamping newKeyVersion. reencrypt (supplied by pkg/secret, holding the key material) maps old ciphertext → new. All-or-nothing: a failure rolls back, leaving every row on the old key.