Commit Graph

1 Commits

Author SHA1 Message Date
marfrit e4b818b0e9 secrets: vault loader + scrub/rehydrate + autodetect (#13 commit 1)
Standalone module — no wiring yet. Lands the substrate for issue #13:

  secrets.load(path)            — vault file loader; refuses non-0600
  secrets.make_session(vault)   — per-conversation scrub/rehydrate state
  session:scrub(text, mode)     — substitute literals (+ autodetect)
  session:rehydrate(text)       — restore placeholders
  secrets.streaming_rehydrator  — chunk-boundary-tolerant streaming wrapper

Mode semantics (chosen per call by the caller):
  "off"               — identity, no mapping
  "vault"             — vault literals only, placeholders, rehydratable
  "vault+autodetect"  — + heuristic regexes, placeholders, rehydratable
  "stealth"           — + heuristic regexes, opaque decoys, one-way

Placeholders are stable across the session: the same literal always
maps to the same $AISH_SECRET_NNN slot, so re-scrubbing the same
context is idempotent and the model sees a consistent vocabulary.

AUTODETECT_PATTERNS (ordered; longer prefixes first):
  sk-or-v<N>-...  OpenRouter
  ghp_/gho_/ghs_  GitHub PATs
  AKIA<16>        AWS access keys
  eyJ...x.y.z     JWTs
  sk-...          OpenAI (generic; matched after openrouter)
  -----BEGIN ... PRIVATE KEY-----  SSH/GPG key headers

Streaming rehydrator: tolerates a placeholder split across SSE chunks
($AISH_SE then CRET_001). It holds back the trailing partial-match
in a buffer, emits the rest, and resolves on the next push or flush.
Verified with 20 unit cases (vault sub, stable mapping, autodetect
across all label kinds, stealth decoys, mode=off, streaming with
mid-placeholder splits, non-placeholder $-prose pass-through).

Vault file mode enforcement: 0600 only — matches ssh's behavior for
~/.ssh/id_rsa. Loud failure (status + skip) if mode is wider.

Next commit (issue #13 follow-up): wire into broker / tool dispatch
/ display, add per-broker `redact` policy, :secrets meta, config
example block.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 21:36:39 +00:00