You know that little prompt Claude Code throws at you before it runs a shell command? The one with “Yes, and don’t ask again” that you click without reading because you’ve got better things to do? Yeah. That button has been quietly writing your passwords into a JSON file, and for a few thousand developers, that file ended up on public GitHub.
The Claude Code secrets leak is the kind of story I love and hate at the same time. Nobody got hacked. There’s no zero-day, no evil maid, no nation-state. Just a convenience feature doing exactly what it says on the tin, and humans being humans.
How the Claude Code secrets leak works
Here’s the mechanism. When you approve a command and tick “don’t ask again”, Claude Code saves an allow rule in .claude/settings.local.json inside your project. Sometimes that rule is a pattern like npm test *. Fine. But sometimes it’s the exact command you just approved, character for character. And if that command was PGPASSWORD=hunter2 psql -h db.prod.example.com, well, congratulations, hunter2 now lives in a plaintext file in your repo folder.
Anthropic did think about this. The first time Claude Code writes that file in a git repo, it adds it to your global git excludes. Which is great for you, on that machine. It does nothing for your colleague who cloned the repo, nothing for CI, and nothing for a file that was already committed. The tool never touches the project’s own .gitignore, so the protection doesn’t travel. And in roughly half of the affected repos, the commit that touched the file lists Claude as a co-author. The agent committed its own leak. Poetic.
What Apiiro actually found
Security firm Apiiro went hunting on public GitHub and, as The Hacker News reported, found 104,185 copies of that settings file across 103,617 repositories. About 1.1% of them, 1,122 files, contained at least one secret. In total, 1,379 distinct secrets: 379 database passwords, 43 SSH logins to public servers, 42 GitHub, GitLab and npm tokens, 23 AWS keys. Sixty-three organizations are among the owners. The researchers mention a database vendor’s own admin-level cloud key and the owner password of a medical-records database. Not test fixtures. The real thing.
Apiiro didn’t test whether the secrets still work (that would be a crime, not research), but one company they notified confirmed its key was live. And in half of the affected repos, the file had been sitting on the default branch for at least 217 days. Seven months of “nobody noticed”.
Add the deleted versions still lurking in git history, the forks, the shared .claude/settings.json files teams commit on purpose, and saved chat logs, and the count climbs to 2,539 secrets across 1,994 repositories. Of the 16 coding agents Apiiro compared, Claude Code is the only one confirmed to store the full approved command in a project file by default.
The bit that worries me most, though, is this: the usual secret scanners miss a lot of it. Gitleaks caught 564 of the 1,122 files, TruffleHog 643, and 215 files slipped past both. Why? Because a password after sshpass -p or mysql -p doesn’t look like a key. It looks like a word. Scanners hunt for AKIA-prefixed strings, not for your cat’s name.
What I’d do right now
If you use Claude Code, open .claude/settings.local.json in every project today and read it. Actually read it. Delete any rule with a credential in it. Then grep your GitHub org for that filename, including in git history, because deleting the file last month fixed nothing. Anything that was ever in there gets rotated first, cleaned up second. Rotate first, always.
Going forward, stop typing secrets into commands at all. Use $DB_URL from a secrets manager so the saved rule contains the variable name, not the value. And approve patterns, like Bash(npm run:*), instead of one-off exact commands. It’s the same hygiene we’ve preached for years with shell history; the AI agent just added a second, stickier history file nobody told you about.
This is the second time in a few weeks the Claude Code ecosystem has bitten people in ways that have nothing to do with the model itself. Last time it was a backdoored extension handing out SSH keys. This time it’s a settings file. The common thread is that the tooling around these agents is moving faster than our habits.
Don’t ask again is a great feature. Don’t read again is the problem.
Discover more from TechPassion
Subscribe to get the latest posts sent to your email.






