Documentation
¶
Overview ¶
Package vault stores the credentials agents need, encrypted at rest, with every reveal audited.
Two design choices are deliberate departures from cabrain's vault, which was the obvious thing to reuse:
- Reveal is its own grant. cabrain requires WRITE access on a brain to reveal a secret, so a read-only agent cannot read a credential — the permission is backwards. Here can_reveal is separate from can_list and from any write capability.
- Every reveal writes an audit row in the same transaction as the decrypt, or the reveal does not happen. cabrain emits only a transient event, so there is no durable answer to "who read this key?".
Index ¶
Constants ¶
const KeySize = 32
KeySize is the AES-256 key length in bytes.
Variables ¶
var ErrNoKey = errors.New("BUILDER_VAULT_KEY is not set")
ErrNoKey is returned when BUILDER_VAULT_KEY is absent.
Functions ¶
func ValidateVaultKey ¶
ValidateVaultKey reports whether raw is a usable 32-byte key.
Accepts standard or URL-safe base64, with or without padding, or 64 hex characters — because operators generate these with whichever of `openssl rand -base64 32` or `openssl rand -hex 32` they remember.
Types ¶
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service is the vault.
func New ¶
New builds the vault from BUILDER_VAULT_KEY.
A missing or malformed key is fatal at boot rather than at first use: an app that starts with a broken vault fails later, inside an agent run, where the cause is far harder to see.
func (*Service) Open ¶
Open decrypts a stored ciphertext. aad must match exactly what Seal was given.
func (*Service) Seal ¶
Seal encrypts plaintext under the row's identity.
aad binds the ciphertext to the row it belongs to (scope:agent_slug:name). AES-GCM authenticates it, so a ciphertext copied into a different row fails to decrypt — which makes row-swapping a non-attack rather than a privilege escalation.