Files
suaveplan/openspec/archive/2026-05-26-api-secrets-bun/proposal.md
2026-05-27 23:29:53 +01:00

46 lines
2.7 KiB
Markdown

# `@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 abstract `secrets` capability from `api-secrets`. Reads from `Bun.secrets.get({ service, name })`; writes via `Bun.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 raise `SECRETS_BUN_NOT_ALLOWED`.
- ADDED: Capability `secrets.bun` declared so plugins that specifically require the Bun-keystore backend (e.g. for desktop runtimes) can require it via `requiredCapabilities`.
- ADDED: Conformance — passes `runSecretsConformance` from `api-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`, future `api-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 fixture `Bun.secrets` namespace; allowlist enforcement (read of un-manifested name raises `SECRETS_BUN_NOT_ALLOWED`).
- `src/adapter/adapter.spec-conformance.test.ts` — runs `runSecretsConformance` from `api-secrets/testing` against 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"`.