secretstore

package
v0.0.4 Latest Latest
Warning

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

Go to latest
Published: Sep 27, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package secretstore backs the secret broker with SQLite.

It is a type-converting adapter, in the same shape and for the same reasons as pkg/executorstore: pkg/statedb owns the rows and the SQL, pkg/secretbroker owns the policy and the crypto, and this package joins them. Keeping the broker free of a SQLite dependency is what lets its constraint-enforcement logic — the part worth testing exhaustively — be tested against an in-memory store with no database file in sight.

The payload crosses this boundary sealed in both directions. Nothing here holds a key or decrypts anything.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Auditor

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

Auditor writes broker decisions into the hash-chained audit_events table.

Every mint, grant, lease, renew, revoke, and denial lands here with the subject, the secret ID, and the reason. Payloads never do — see the redaction note on Audit.

func NewAuditor

func NewAuditor(db *statedb.DB) *Auditor

NewAuditor wraps a database handle as a broker audit sink. A nil db yields a sink that drops events, so a caller that could not open the database still gets a working broker rather than a nil-pointer panic on the first decision.

func (*Auditor) Audit

func (a *Auditor) Audit(ev secretbroker.Event)

Audit persists one brokered-operation event.

Redact is called again here even though the broker already redacts on emission. That is not redundancy for its own sake: this is the last function before a credential-shaped string would become a permanent, hash-chained, deliberately-immutable row. An audit log is the worst place in the system to discover a leak, because the tamper-evidence that makes it valuable is also what makes it awkward to clean up. Redacting at the boundary means a future caller who constructs an Event by hand, or a broker change that adds a new emission path, cannot write plaintext here by omission.

Best-effort, matching pkg/statedb's other audit emitters: a full or read-only database must not stop a workload from getting its credentials. The chain verifier surfaces the resulting gap.

type EgressStore

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

EgressStore implements egressbroker.Store over a *statedb.DB.

func NewEgressStore

func NewEgressStore(db *statedb.DB) (*EgressStore, error)

NewEgressStore wraps a database handle.

func (*EgressStore) GetGrant

func (s *EgressStore) GetGrant(id string) (egressbroker.Grant, error)

GetGrant returns one grant by ID.

func (*EgressStore) ListGrants

func (s *EgressStore) ListGrants() ([]egressbroker.Grant, error)

ListGrants returns every grant.

A row whose policy or subject cannot be decoded is skipped, and skipped in the deny direction: a grant the broker cannot read is a grant it will not honour, so a corrupt row silently loses access rather than silently keeping it. This mirrors Store.ListGrants exactly, and for the same reason.

func (*EgressStore) PutGrant

func (s *EgressStore) PutGrant(g egressbroker.Grant) error

PutGrant persists an egress grant.

func (*EgressStore) RevokeGrant

func (s *EgressStore) RevokeGrant(id string, at time.Time) error

RevokeGrant stamps a grant revoked.

type Store

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

Store implements secretbroker.Store over a *statedb.DB.

func New

func New(db *statedb.DB) (*Store, error)

New wraps a database handle.

func (*Store) CountSealedByKey

func (s *Store) CountSealedByKey() (map[string]int, error)

CountSealedByKey groups stored secrets by the key sealing them.

func (*Store) DeleteSecret

func (s *Store) DeleteSecret(id string) error

DeleteSecret removes a secret.

func (*Store) ExpireAccessRequests added in v0.0.2

func (s *Store) ExpireAccessRequests(now time.Time) ([]secretbroker.AccessRequest, error)

ExpireAccessRequests moves lapsed pending requests to expired.

A row that cannot be decoded is still expired — the UPDATE ran against it — but is dropped from the returned slice, so it produces no audit event. That is the honest outcome: the broker cannot say what lapsed if it cannot read the request, and inventing a partial event would put a subject the store could not parse into the permanent trail.

func (*Store) GetAccessRequest added in v0.0.2

func (s *Store) GetAccessRequest(id string) (secretbroker.AccessRequest, error)

GetAccessRequest returns one request by ID.

func (*Store) GetGrant

func (s *Store) GetGrant(id string) (secretbroker.Grant, error)

GetGrant returns one grant by ID.

func (*Store) GetSecret

func (s *Store) GetSecret(id string) (secretbroker.Secret, error)

GetSecret returns one secret by ID, translating the storage sentinel into the broker's so callers can use a single errors.Is target.

func (*Store) ListAccessRequests added in v0.0.2

func (s *Store) ListAccessRequests() ([]secretbroker.AccessRequest, error)

ListAccessRequests returns every request.

A row whose subject or constraints cannot be decoded is skipped, matching ListGrants — and skipped in the same direction, which here means the request becomes invisible and therefore unapprovable. That is the safe failure: a corrupt row cannot be turned into a grant whose scope nobody can read.

func (*Store) ListGrants

func (s *Store) ListGrants() ([]secretbroker.Grant, error)

ListGrants returns every grant.

A row whose constraints or subject cannot be decoded is skipped rather than failing the whole listing, but it is skipped in the deny direction: a grant the broker cannot read is a grant the broker will not honour, so a corrupt row silently loses access rather than silently keeping it.

func (*Store) ListKEKs

func (s *Store) ListKEKs() ([]secretbroker.KEKRecord, error)

ListKEKs returns every KEK, retired ones included.

func (*Store) ListRequestUses added in v0.0.2

func (s *Store) ListRequestUses(requestID string) ([]secretbroker.RequestUse, error)

ListRequestUses returns the leases recorded against one request.

It reconciles task attribution first. That write-during-a-read is deliberate and is explained in statedb.AttributeRequestUseTasks: a lease is issued before the workload that holds it is dispatched, so the task can only be learned afterwards, and only while the dispatched handle is still live. Doing it here means an approver opening the panel captures attributions that would otherwise be lost when the workload ends. A failure is ignored rather than surfaced — the uses themselves are still the answer, just with one column short.

func (*Store) ListRotations

func (s *Store) ListRotations(limit int) ([]secretbroker.RotationRecord, error)

ListRotations returns rotation history, newest first.

func (*Store) ListSealedNotUnder

func (s *Store) ListSealedNotUnder(keyID string, limit int) ([]secretbroker.SealedRow, error)

ListSealedNotUnder returns secrets still sealed under some other key.

A secret's associated data is its own ID, matching what Broker.Mint sealed it with. Getting this wrong would not silently weaken anything — the rewrap would fail authentication and the row would be reported as stuck — which is the property AAD binding is supposed to have.

func (*Store) ListSecrets

func (s *Store) ListSecrets() ([]secretbroker.Secret, error)

ListSecrets returns every stored secret.

func (*Store) Meta

func (s *Store) Meta(key string) (string, bool, error)

Meta reads a broker-scoped metadata value.

func (*Store) PrimaryKEK

func (s *Store) PrimaryKEK() (secretbroker.KEKRecord, bool, error)

PrimaryKEK returns the current primary, if any.

func (*Store) PromoteKEK

func (s *Store) PromoteKEK(id string, at time.Time) error

PromoteKEK makes a key the sole primary.

func (*Store) PutAccessRequest added in v0.0.2

func (s *Store) PutAccessRequest(r secretbroker.AccessRequest) error

PutAccessRequest persists a request.

func (*Store) PutGrant

func (s *Store) PutGrant(g secretbroker.Grant) error

PutGrant persists a grant.

func (*Store) PutKEK

func (s *Store) PutKEK(k secretbroker.KEKRecord) error

PutKEK persists a key-encryption key record.

func (*Store) PutRotation

func (s *Store) PutRotation(r secretbroker.RotationRecord) error

PutRotation records rotation progress.

func (*Store) PutSecret

func (s *Store) PutSecret(sec secretbroker.Secret) error

PutSecret persists a sealed secret.

func (*Store) RecordRequestUse added in v0.0.2

func (s *Store) RecordRequestUse(u secretbroker.RequestUse) error

RecordRequestUse notes one lease that redeemed an approved request's grant.

func (*Store) ReplaceSealed

func (s *Store) ReplaceSealed(id string, expect, next secretbroker.Envelope) (bool, error)

ReplaceSealed swaps a secret's envelope under compare-and-swap.

func (*Store) RetireKEK

func (s *Store) RetireKEK(id string, at time.Time) error

RetireKEK destroys a key's salt, refusing while rows still reference it.

func (*Store) RevokeGrant

func (s *Store) RevokeGrant(id string, at time.Time) error

RevokeGrant stamps a grant revoked.

func (*Store) SealedSetName

func (s *Store) SealedSetName() string

SealedSetName identifies this population in rotation reports and, more importantly, namespaces every envelope's associated data.

func (*Store) SetMeta

func (s *Store) SetMeta(key, value string) error

SetMeta writes a broker-scoped metadata value.

Jump to

Keyboard shortcuts

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