Your Secrets Are in the Output
Claude Code can run env. When it does, every API key and token in your shell environment appears in the conversation context. The model sees them. They get logged.
The same thing happens with printenv, export -p, and set -x. Any command that dumps environment variables or enables debug tracing will surface secrets that are supposed to stay hidden.
How it happens
Three patterns show up in practice:
Environment dumps. Claude runs env or printenv to “check what’s available.” This is usually benign intent, but the side effect is that DATABASE_URL, AWS_SECRET_ACCESS_KEY, ANTHROPIC_API_KEY, and everything else in the environment get printed into the conversation.
Debug tracing. bash -x deploy.sh or set -x before running commands prints every line with variables expanded. If the script references $API_KEY or $DB_PASSWORD, the actual values appear in the trace output. This is one of the patterns reported in claude-code#37599.
Export listing. export -p lists every exported variable with its value. Same effect as env, just a different command.
What to do about it
bash-guard now blocks these patterns. Install it:
curl -sL https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/bash-guard/install.sh | bash
It intercepts env, printenv (without a specific variable name), export -p, bash -x, sh -x, and set -x. Safe variants pass through: printenv HOME, env FOO=bar command, set -euo pipefail.
If you actually need these commands, add the allow key to .bash-guard:
allow: env-dump
allow: debug-trace
The broader pattern
Credential exposure in AI coding tools is not a hypothetical risk. Check Point published research in February documenting how malicious project files could exfiltrate API tokens (Anthropic patched those specific vectors). But the pattern is broader: any command that dumps your environment puts secrets into the conversation context, and that surface area is hard to close from the platform side.
A PreToolUse hook blocks the command before the tool executes. The secrets never reach the model because the command never runs.
117 tests now cover all of bash-guard’s blocked patterns, including the new credential exposure checks.