secret

package
v0.4.2 Latest Latest
Warning

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

Go to latest
Published: Jun 28, 2026 License: Apache-2.0 Imports: 18 Imported by: 0

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

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.

func NewAgent

func NewAgent(r Refresher, timeout time.Duration, log *slog.Logger) *Agent

NewAgent builds the agent. timeout bounds a single re-resolve (and therefore how long a last-candidate request can park). Defaults: 5s, slog.Default().

func (*Agent) OnFailure

func (a *Agent) OnFailure(ctx context.Context, keyID string, kind keypool.FailureKind, moreCandidates bool) (pipeline.Verdict, string)

OnFailure implements pipeline.KeyAgent.

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 NewStore

func NewStore(q *gen.Queries, pool *pgxpool.Pool) *Store

NewStore constructs the store over the shared query set + pool.

func (*Store) Delete

func (s *Store) Delete(ctx context.Context, id string) error

Delete removes a stored secret. Called when a HostKey switches away from stored mode or is deleted.

func (*Store) Get

func (s *Store) Get(ctx context.Context, id string) (ciphertext, nonce []byte, keyVersion int32, err error)

func (*Store) MaxKeyVersion

func (s *Store) MaxKeyVersion(ctx context.Context) (int32, error)

func (*Store) Put

func (s *Store) Put(ctx context.Context, id string, ciphertext, nonce []byte, keyVersion int32) error

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.

Jump to

Keyboard shortcuts

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