Bun.secrets — OS keychain-backed dev secrets
Accept, scoped tightly to dev. Resolves the "where do my dev secrets live" gap in spec 08.
Review verdict (2026-05-24)
Accept, scoped tightly to dev. Resolves the "where do my dev secrets live" gap in spec 08.
Scope pins:
- Source order in dev:
Bun.secrets>Bun.env. A key present in both wins viaBun.secrets. - Source order in prod (
PATTIES_ENV=prodorNODE_ENV=production):Bun.secretsis bypassed entirely. Only runtime-injectedBun.env/ vendor bindings are read. - Linux without libsecret: a missing keychain backend logs a one-line warning at boot and silently falls through to
Bun.env. Not a boot error — CI on bare Linux must keep working. - Service name (open question): use
package.json#nameif present, else"patties". Pin this so dev secrets are per-project, not shared across all Patties apps on the dev box.
CLI surface (patties secret set <key> etc.) is encoded into CLI specs separately.
Summary
Bun.secrets.get(service) / .set(service, value) reads and writes credentials via the OS keychain (macOS Keychain, Windows Credential Manager, libsecret on Linux). Patties should support Bun.secrets as an alternative source for dev-time secrets, so .env.local is no longer the only path and contributors don't accidentally commit credentials.
Motivation
08-config validates env vars at boot but offers no recommendation for where secrets live in development. Today every contributor either keeps .env.local (commit risk) or pastes secrets into their shell. Bun.secrets is zero-dep, OS-integrated, and never touches disk in the repo.
Proposal
- 08-config: add a
secrets:field to the config schema that lists keys to load fromBun.secretsat boot: ``ts export default defineConfig({ secrets: ["ANTHROPIC_API_KEY", "DATABASE_URL"], });`These overlayBun.envat boot; missing entries fall back toBun.env`. - 15-scaffold:
patties secret set <key>writes viaBun.secrets.set. - 13-conventions: in production (NODE_ENV=production or PATTIES_ENV=prod),
Bun.secretsis bypassed — onlyBun.env(vendor-injected) is read.
Trade-offs
- Linux CI without libsecret will fail — must gate on dev-only.
- Encourages "set once, forget" — rotation is harder than editing
.env.
Open questions
- Service name: hardcode
"patties"or derive frompackage.json#name? - Do we want a
patties doctorcommand (15) that lists which keys are sourced from where?