Claude Code Writes Your Passwords Down. 1,122 Copies Are Public.
Apiiro found 1,122 public GitHub files where Claude Code's don't-ask-again file holds real secrets. In 539 repos, a Claude-co-authored commit touched the leaky file.
Security researchers at Apiiro scanned GitHub for copies of .claude/settings.local.json, the file Claude Code writes when you click "Yes, and don't ask again" on a shell command. Of 104,185 public copies, 1,122 hold a real secret. The findings: database passwords, production cloud keys, an npm token, a Square production token, 43 SSH logins to public servers, and the owner password of a medical-records database. 63 organizations are affected, and one confirmed its key had been live.
The mechanism takes one click. Ask Claude Code to check why staging login fails and the command it proposes carries the password, because the command cannot run without it. Approve it with "Yes, and don't ask again" and the exact command string, password included, gets saved as an allow rule in .claude/settings.local.json in the project folder. From there the leak is a git accident. Claude Code adds the file to your global git ignore, which covers the machine you are on and nothing else. The rule never lands in the repo's own .gitignore, so it does not travel with the project. A fresh clone, a new laptop, or a teammate commits the file like any other file.
The co-author counts are the uncomfortable part. Apiiro traced 1,105 repos holding a real secret in the file, and in 539 of them a commit co-authored by Claude itself changed the file. Those commits name Sonnet 4.5 through Opus 5.5. The model did not invent the leak. The approval flow wrote the secret to disk, and the agent then treated the file as work to commit. The agent was the courier for a leak its own approval dialog created.
Scan rates tell you where this is heading. One in ten files over 8 KB holds a real secret, against fewer than one in 500 under 500 bytes. The allowlist only grows. Every secret you ever approved stays until someone deletes the rule, and the median leaky file was first committed 217 days before the scan. 211 forks of 74 repos carry the same secrets. Deleting the file today leaves 734 secrets in git history across 509 repos.
The scanner gap makes it worse. Apiiro ran gitleaks and TruffleHog over all 104,185 files. gitleaks flagged 564 of the 1,122 leaky files, TruffleHog 643, and 215 were flagged by neither. A provider key has a recognizable format. A password typed after PGPASSWORD= or sshpass -p is an ordinary word in an ordinary command line, and both scanners mostly let it through. Apiiro reproduced the approval behavior with Opus 5.5 and Fable 5.1, so this is Claude Code's approval flow, not a model quirk. The pattern also lives in other agent-written files: 120 agent chat transcripts in 87 repos, 33 handoff notes, agent memory files. A third of the handoff notes holding a secret were written by the agent itself. Memory files, transcripts, handoff notes: wherever an agent records what it ran, the password-in-a-command pattern can appear, and format-based scanners miss it.
There is prior art and a paper trail. Claude Code users have reported this mechanism in GitHub issues since August 2025, starting with issue #5544: approved bash commands containing credentials get stored as-is in settings.local.json. More followed, and none got a reply from Anthropic; three closed automatically as inactive or duplicates. ironPeak measured 2.4% of repos with AI config folders carrying secrets in history, on a sample of 100, in February 2026. Lakera found credentials in 33 such files across 30 npm packages in April.
The fix list is short and ordered. First, rotate anything the file has ever held, because removal does not clear git history, forks, or clones. Second, untrack the file with git rm --cached .claude/settings.local.json and add it to the repo's own .gitignore. Third, open your local copy and delete every rule containing a secret. Fourth, stop typing secrets into commands at all: reference them as $VAR so the rule records $DB_URL instead of the credential, and approve patterns like Bash(npm run:*) instead of literal commands.
The comparison with other agents matters for anyone choosing tooling. Apiiro compared how 16 coding agents store approvals. Claude Code is the only one confirmed to write the full approved command to a project file by default. Malware is already priced into this file: the Shai-Hulud npm worm ran TruffleHog over victims' machines, and that scanner flags 643 of the 1,122 files. The Nx packages that hit developers three weeks before Shai-Hulud, in August 2025, went further and told the victim's own Claude Code and Gemini CLI to search the disk for secrets. 2,539 distinct real secrets sat in 1,994 repos when you add the shared settings file, git history, and agent transcripts. The threat model is not hypothetical.
The discipline is one sentence: never type a secret into a command an agent can record. The checklist in two minutes: search your org for .claude/settings.local.json, check git history for it, rotate what you find, and move secrets behind $VAR references before the next "don't ask again" click does the filing for you.
Sources: Coding Agents Copy Your Secrets to a Hidden File. Thousands Are on GitHub (Apiiro, Nov 5), HN discussion, and Claude Code issue #5544, Aug 2025.
Comments ()