A small shell guard that blocks any command from printing the raw contents of a secret-store
file (fnox.toml or any *.env) to stdout. Agent transcripts and shell histories persist, so
even an age-encrypted fnox.toml should never be echoed.
It catches the file-read vector: cat/grep/sed/awk/head/tail/less/xxd/..., language
one-liners like open(".env"), input redirection < .env, and git diff/show/blame/log of
the file.
It deliberately does not block:
fnox exec -- <cmd>— consumes a secret without printing itgit add/commit/restore— reference the file without printing its contents
The detection logic is identical across all three — only the input/output contract differs, so the same script drops into different setups.
secret-read-guard.sh '<command>' # exit 0 = safe, exit 1 = would leak (reason on stderr)Use it as a building block anywhere — a git pre-commit hook, a Makefile target, a shell
precmd, or any agent harness that runs a command and honors the exit code.
Pipe Claude Code's hook JSON in on stdin; on a match it emits a deny decision, otherwise it
stays silent.
// ~/.claude/settings.json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{ "type": "command", "command": "$HOME/.claude/hooks/secret-read-guard.sh" }
]
}
]
}
}printf '%s' '<command>' | secret-read-guard.sh # exit-code semantics, like mode 1curl -o secret-read-guard.sh <raw-gist-url>
chmod +x secret-read-guard.shModes 1 and 3 need only a POSIX shell + grep. Mode 2 also needs jq (to parse the JSON).
secret-read-guard.sh 'cat .env' # exit 1 (blocked)
secret-read-guard.sh 'fnox exec -- env' # exit 0 (allowed)
secret-read-guard.sh 'git add .env' # exit 0 (referenced, not printed)The detection is portable; the enforcement is only as good as the trigger. Something has to call this before a command runs. Modes 1 and 3 cover anything that checks an exit code; mode 2 covers Claude Code. A harness with no pre-execution hook of any kind can't be protected by this (or anything else) — there's nothing to intercept.