2.7 KiB
2.7 KiB
@suaveplan/api-secrets-bun — Bun.secrets-backed secrets adapter
Package: @suaveplan/api-secrets-bun
Status: PROPOSED
Type: new-package
Stage: 8 — see umbrella openspec/changes/api-plugin-foundation/
Why
Per design doc §3 (secrets[] manifest block) and §13.2 (the secrets capability slot), plugins read configured secrets via the secrets capability. Bun.secrets exposes the OS keystore (macOS Keychain, Linux libsecret, Windows Credential Manager) which is the right default for local-dev and single-host operator setups — secrets never touch disk in plaintext and rotate via the OS UI.
What changes
- ADDED:
createBunSecretsAdapter({ service, allowlist })— implements the abstractsecretscapability fromapi-secrets. Reads fromBun.secrets.get({ service, name }); writes viaBun.secrets.set({ service, name, value }). - ADDED: Per-plugin scoping — adapter is instantiated per plugin with its manifest's
secrets[]as the allowlist. Reads outside the allowlist raiseSECRETS_BUN_NOT_ALLOWED. - ADDED: Capability
secrets.bundeclared so plugins that specifically require the Bun-keystore backend (e.g. for desktop runtimes) can require it viarequiredCapabilities. - ADDED: Conformance — passes
runSecretsConformancefromapi-secrets/testing. - ADDED: Error codes (
SECRETS_BUN_*):NOT_FOUND,NOT_ALLOWED,KEYSTORE_UNAVAILABLE,KEYSTORE_LOCKED,WRITE_FAILED.
Out of scope
- Other secret backends — sibling packages (
api-secrets-vault, futureapi-secrets-aws-sm, etc.). - Migrating existing OS keychain entries between machines — operator concern.
- Plaintext fallback when the OS keystore is unavailable — adapter refuses to start; another adapter must be selected.
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 |
secrets.bun capability declarable in manifest |
§3 (requiredCapabilities) |
Per-plugin allowlist from manifest secrets[] |
§3 |
Verification approach
src/adapter/adapter.test.ts— read / write / list against a fixtureBun.secretsnamespace; allowlist enforcement (read of un-manifested name raisesSECRETS_BUN_NOT_ALLOWED).src/adapter/adapter.spec-conformance.test.ts— runsrunSecretsConformancefromapi-secrets/testingagainst the Bun adapter.src/error-codes.ts— every code listed.tests/dep-graph.test.ts— runtime deps (api-types,api-secrets,error,logger).
Migration impact
None — additive only. api-host registers this when host.secrets.backend = "bun".