2.0 KiB
| summary | tags | scope | type | source | date | last_updated | ||||
|---|---|---|---|---|---|---|---|---|---|---|
| How to keep secret values out of AI agent session transcripts — use shell command substitution for consumption, and never echo secrets in agent-driven CLI success output. |
|
global | convention | credvault envelope-leak incident, 2026-07-12 | 2026-07-12 | 2026-07-12 |
Secrets out of agent transcripts
The rule
In AI-agent sessions, the transcript is the leak surface, not git. Anything printed to
stdout becomes durable text: session logs, memory summaries, handoff documents, cached
context. A gitignored file does not protect a secret the agent cats; a vault does not
protect a secret the CLI echoes back.
Two patterns that generalize to any credential tooling an agent drives:
- Consume via shell command substitution.
ENV_VAR=$(secret-fetch-cmd) target-cmdnever exposes the value — the transcript records the command text, not the substituted output. This is the default way an agent should use a credential in any command. - Agent-driven CLIs must not echo secrets in success envelopes. Return
null/omit the secret by default (the caller supplied it or will fetch it deliberately); offer an explicit opt-in flag (e.g.--show-secret) for the rare case a human wants to see it.
Corollary: a fancier exec-style env-injection wrapper or local cache is usually
overengineering — command substitution gets ~90% of the value with zero new surface area.
Why
Discovered when credvault's ensure success envelope echoed a caller-supplied bot password
back into a session transcript. Fixed 2026-07-12: envelope nulling + --show-secret
(credvault eb51e4c), consumption pattern tracked in credvault issue #11.
How to apply
- When an agent needs a credential in a command: inline it via
$( … ), never fetch-then-paste. - When building or reviewing any CLI agents will drive: audit every success path for secret echo; default to redaction with an opt-in display flag.