2.5 KiB
2.5 KiB
@suaveplan/api-secrets-vault — @suaveplan/vault-backed secrets adapter
Package: @suaveplan/api-secrets-vault
Status: PROPOSED
Type: new-package
Stage: 8 — see umbrella openspec/changes/api-plugin-foundation/
Why
For multi-host / cloud deployments, secrets need to live in an encrypted, replicated container with a controlled unlock flow. @suaveplan/vault already implements that container (BIP39 + Argon2id + 2SKD + HKDF + SRP-6a + SecureBuffer). Wrapping it as the secrets capability gives the host a production-grade backend that sits alongside its own DB without depending on a third-party vault service.
What changes
- ADDED:
createVaultSecretsAdapter({ vault, allowlist })— implements the abstractsecretscapability over a@suaveplan/vaultinstance.vaultis passed in unlocked by the host's startup sequence; the adapter never sees the master key. - ADDED: Per-plugin scoping — same allowlist contract as
api-secrets-bun; reads outside the allowlist raiseSECRETS_VAULT_NOT_ALLOWED. - ADDED: Watcher support — when the vault publishes a
secret.updatedevent for a name in the allowlist, the adapter emits asecret.changedevent on the host event bus so plugins that cached the value can refresh. - ADDED: Conformance — passes
runSecretsConformancefromapi-secrets/testing. - ADDED: Error codes (
SECRETS_VAULT_*):NOT_FOUND,NOT_ALLOWED,VAULT_LOCKED,VAULT_UNAVAILABLE,WRITE_FAILED.
Out of scope
- Vault unlock UX — host owns the unlock flow (interactive prompt, KMS-derived key, etc.).
- Vault snapshot / restore —
@suaveplan/vaultowns it. - Cross-region vault replication — operator concern.
Source mapping
Genesis-original. Source of design intent: docs/superpowers/specs/2026-05-13-api-plugin-foundation-design.md.
| Requirement | Design doc section |
|---|---|
secrets capability |
§3, §5, §13.2 |
| Per-plugin allowlist | §3 |
Verification approach
src/adapter/adapter.test.ts— read / write / list against a real in-memory vault; locked vault raisesSECRETS_VAULT_LOCKED.src/adapter/adapter.spec-conformance.test.ts—runSecretsConformancepasses.src/watcher/watcher.test.ts—secret.updatedfrom vault →secret.changedon host bus, only for names in allowlist.tests/dep-graph.test.ts— runtime deps (api-types,api-secrets,vault,error,logger,events).
Migration impact
None — additive only. api-host registers this when host.secrets.backend = "vault".