Build1 distinct publisher3 min readUpdated
A developer leaked live keys into agent transcripts three times before replacing a polite memory note with a hook that denies the read outright.
The Engineer · Build desk

Compiled by The EngineerSomething wrong?How this is made
A developer writing on dev.to reports that three separate Claude Code sessions read files of live credentials straight into their own conversation transcripts, each time because someone (the author, or the agent acting on its own initiative) reached for `cat` or `grep` to check a value [1] [2]. The consequence is not an abstract risk surface: each incident meant rotating every credential in the file, one dashboard at a time, while everything depending on those keys kept running on borrowed time [3].
The mechanism is boring, which is why it keeps working. `cat`, `cat -A`, and a plain `grep PATTERN file` all print the matched line in full, so a line reading `ANTHROPIC_API_KEY=sk-ant-...` lands in both the context window and the transcript [4]. The author notes the transcript is a log whose retention they will never fully control [2].
The first response was the one most teams reach for: a memory note saying do not `cat` .env files, use `cut -d= -f1` to list key names, use `grep -c` for presence checks [5]. It failed twice. The second leak came through a `.toml` file the author had not thought to add to the list [6]. The third came from a different session that used the `Read` tool rather than a shell command, which the rule did not cover at all [7]. The author's diagnosis is that they had written a "do not run these commands" rule when the actual requirement was "do not touch these files, by any means" [8], and that a memory note is advice the model re-derives probabilistically each time, covering only the tools and patterns you happened to imagine, and only in sessions that loaded it [9].
The replacement is a `PreToolUse` hook: shell commands the harness runs at defined lifecycle points, deterministically, every time, with the ability to return a decision that blocks the call before it executes [10] [11]. The script reads the pending tool call as JSON on stdin, tests the target path against twelve regexes covering .env variants (while exempting example, sample, template and dist), `id_rsa` and `id_ed25519` private keys but not their `.pub` counterparts, `.pem`, `credentials.json`, `secrets.*`, `.key`, `frp*.toml`, and the shell dotfiles [12] [13] [14]. For `Read`, the path match is the entire check [15]. For `Bash`, it requires two conditions, a secret-looking path plus a command that would actually print contents (`cat`, `head`, `tail`, `sed`, `less`, `awk`, or a bare `grep` without `-c`), so `ls -la .env` and `chmod 600 .env` still pass [16]. Denial is JSON on stdout with `permissionDecision: deny` and a reason that names the safe alternative, and it is wired into `settings.json` under both the `Bash` and `Read` matchers [17] [18].
Two limits are worth stating plainly. The hook is still an enumerated list, so a credential file matching none of the twelve patterns is not blocked; the gain is enforcement, not completeness [19]. And it is scoped to two matchers, so any other path to file contents, whether an edit tool, an MCP server, or a subagent, is ungated until someone adds it [20]. The author's own history is the argument for checking: the failure mode each time was a tool nobody had listed [6] [7].
Worth noting for anyone citing the post: the headline describes rotating the same five keys twice, while the body describes three incidents [21] [1].
Follow any of these and your For You feed starts watching them — no settings page required.
Ranked by verification strength, evidence, and original report placement.
The author states that three times a Claude Code session read a file full of live credentials into its own conversation transcript, not maliciously and not on request.
In each incident the agent ran cat or grep on something to 'check a value', and the whole file including secrets ended up in plaintext in a log whose retention the author says he will never fully control.
Each incident cost the author rotating every credential in the affected file, one dashboard at a time, while whatever depended on them kept running on borrowed time.
cat, cat -A and a plain grep PATTERN file all print the matched line in full, so a line such as ANTHROPIC_API_KEY=sk-ant-... becomes part of both the context window and the transcript.
After the first incident the author wrote a memory note: do not cat .env files, use cut -d= -f1 to list keys instead, use grep -c for presence checks.
The second leak happened on a .toml file the author had not thought to add to the mental list of protected files.
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Detailed but single-source and self-reported
The technical artifact is unusually well exposed for a blog post: the full regex list, the Read and Bash branch logic, the deny JSON payload and the settings.json wiring are all published, and the author volunteers two failure cases from his own pre-deployment testing. Against that, every factual anchor comes from one first-person account on one publisher, with no transcripts, logs, timestamps or third-party confirmation of the three leaks and no independent verification that the hook blocks in practice.
One self-reported personal install
The only usage evidence is the author wiring the hook into his own settings.json for two matchers. There are no other deployments, no repository, stars, downloads or team rollout, and no indication that anyone else has adopted the pattern, so adoption is real but minimal in scope.
Headline overshoots the control's own limits
The title promises never having to rotate those keys again, while the body establishes that the gate matches a hand-written list of twelve path patterns and is registered for only Bash and Read, so unlisted files and other tool routes remain unblocked. The author's own testing found that the exact file from the triggering incident would have passed through, which is a meaningful discount on the headline. The overstatement is modest rather than severe precisely because the post surfaces those gaps itself.
Self-promotional developer post, no disclosed commercial stake
This is a personal engineering write-up on a developer publishing platform with an attention-seeking headline, so there is a reputational and engagement incentive to present the fix as decisive. No vendor sponsorship, product being sold, affiliation with the harness vendor, or paid placement is disclosed or implied, and the post argues against its own earlier approach and documents its own testing failures, which cuts against a purely promotional reading.
Internally consistent, externally unverified
The mechanism claims are specific, self-consistent and independently inspectable from the published code, which supports moderate confidence in what the hook does. Confidence is capped by the cluster having a single publisher, no corroboration of the leak incidents or of harness behaviour, and adoption limited to the author's own machine.
build
The control point for coding agents is the deny list, not the diff1 distinct publisher
build
A guard that only speaks in exit codes cannot tell you it stopped guarding1 distinct publisher
build
The prompt never arrived: a Windows batch shim was worth 15 of 24 runs in an agent eval1 distinct publisher
build
Force the tool call, then hand Lightsail a long-lived key1 distinct publisher
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 16, 2026