Claude Code stores approved-command secrets in plaintext across 1,122 public GitHub repos
On November 7, 2026, Apiiro revealed that Claude Code’s .claude/settings.local.json file saves approved commands word-for-word — secrets included — and that 1,122 public copies of the file expose at least one secret. Rotate credentials first, then clean git history and add the file to the project’s .gitignore.
November 7, 2026. Apiiro, a software-security vendor, publishes research into a massive, silent secret leak. 1,122. The number of public copies of .claude/settings.local.json that hold at least one secret. 2,539. The total secrets found once old versions and agent logs are counted. Why it matters: when a developer answers “Yes, and don’t ask again” in Claude Code, the assistant saves the approved command word-for-word — password or API key included — in a JSON file inside the project, and nothing stops that file from reaching GitHub.
The mechanism: a “don’t ask again” that copies the secret
By default, Claude Code asks before running most shell commands. When the user picks “Yes, and don’t ask again,” the tool writes an allow rule into .claude/settings.local.json, at the project root. Matching commands then run without confirmation in later sessions.
The rule covers only what the prompt offered. Sometimes that is a pattern — say, npm test *. Sometimes it is one exact command. And when it is the exact command, any password or token typed into it is saved too, in plaintext.
Researchers found saved commands in public files with the secret still inside, and reproduced the behavior with the latest models, Opus 5.5 and Fable 5.1. One company the researchers notified earlier in the week confirmed its key was still live.
Claude Code does try to keep the file out of git. The first time it writes the file in a repository, it adds it to the user’s global git excludes — on that computer only. That protection does not travel with the project: the file is never added to the repository’s own .gitignore, and it does nothing for a file that was already committed. In 539 of the 1,105 repositories traced, a commit listing Claude as co-author changed the file — a sign the assistant sometimes commits the sensitive file itself.
What the researchers found
Apiiro’s scan of public GitHub found 104,185 copies of the file across 103,617 repositories. Roughly 1.1% of them — 1,122 copies — hold at least one secret, totaling 1,379 distinct secrets. A value counted as a secret when it matched a known key format, or when a password sat beside the address of a public server, with an AI reviewer confirming.
More than a third of the secrets open a database directly, including 379 database passwords. The rest break down into 43 SSH logins for public servers, 42 tokens for GitHub, GitLab, and npm, and 23 AWS keys. The owners include 63 organizations, mostly software companies. The strongest cases include an admin-level cloud key belonging to a database vendor and the owner password of a medical-records database.
As of Monday, November 2, every file with a secret was still on its repository’s default branch, and in half of those repositories it had been there for at least 217 days. Older versions hold 734 more secrets, and 211 forks of 74 repositories carry the same secrets as the originals.
The surface goes beyond the local file. Adding the shared .claude/settings.json (committed deliberately by teams), old versions, and agent chat logs brings the total to 2,539 secrets across 1,994 repositories. Of 16 coding agents whose documentation was compared, Claude Code is the only one that saves the full approved command in a project file by default.
Why standard scanners miss it
The most alarming part is not that the secret exists — it is that it is invisible. The researchers ran gitleaks and TruffleHog over every copy, without the verification step. Of the 1,122 files holding a secret, gitleaks flagged 564, TruffleHog 643 — and neither flagged 215.
The reason is simple: most of the misses are passwords typed inside a command. Scanners look for known key formats, but a password after PGPASSWORD=, sshpass -p, or mysql -p reads like an ordinary word in an ordinary command line. That is the Achilles’ heel of pattern-based detection, and it is exactly the kind of secret this file concentrates.
The vulnerability had been reported before. A bug report filed on August 11, 2025 already described approved commands with API keys and tokens stored word-for-word in settings.local.json. A bot closed it as “not planned” on January 3, after 60 days without activity. The four related reports cited by the researchers have all been closed by the same bot, with no reply from Anthropic.
Nor is this a new category of risk. Malware has hunted for secrets on developer machines before — in September 2025, the Shai-Hulud worm ran the TruffleHog scanner over infected computers and flagged more than half the files it touched as holding secrets. A predictable .claude/ folder simply gives that class of malware one more place to look, and it is a place no signature-based scanner currently points at.
What to do — in this order
The order of operations is the critical part of the report, because deleting the file repairs nothing: old versions remain in git history and in forks. The hard rule is to rotate credentials first, then clean up.
# 1. Find the file, including in history (every repo, every branch)
git log --all -- .claude/settings.local.json .claude/settings.json
# 2. Untrack the file without deleting the local copy
git rm --cached .claude/settings.local.json
# 3. Add it to the PROJECT's .gitignore (not just global excludes)
echo ".claude/settings.local.json" >> .gitignore For developers, the researchers recommend keeping secrets out of commands — reference a variable from a secrets manager, like $DB_URL, so the saved rule holds the variable name, not the value — and approving patterns (Bash(npm run:*)) rather than single commands. Even copies that never reach GitHub count: the file is plain JSON in the project folder, and can end up inside an npm package, a Docker image, a zip archive, or a synced folder.
For security teams, the instruction is to treat agent folders — .claude/, .cursor/, .gemini/, .specstory/ — and agent memory files as secrets, like .env files, on laptops as well as in repositories. Add them to pre-commit and CI secret scanning, git history included, and make sure the scanner catches passwords inside commands, not only known key formats. Check credentials paired with a public server first — those are the ones that grant access.
Verdict
This is not a classic Anthropic vulnerability — it is a design flaw in the “don’t ask again” feature, combined with a git protection that does not travel. The file does what it is asked to do (remember the command), but remembering the whole command means remembering the secret, and the .gitignore protection stays nailed to a single machine.
If your organization uses Claude Code, run a search for .claude/settings.local.json and .claude/settings.json across every repository tonight — branches and history included — then rotate any credential those files may have held, before cleaning up. Rotating first is not a comfort precaution: with files in place for 217 days on average, the risk of prior compromise is real. If you maintain a secrets policy, extend it explicitly to agent folders and conversation logs — they hold the same material as .env, but nobody scans them. If you build or ship a coding agent, never persist the full approved command — persist the pattern, never the value.
References
- Apiiro — “Claude Code’s ’Don’t Ask Again’ file exposes secrets in public repos” (November 6, 2026)
- The Hacker News — “Claude Code’s ’Don’t Ask Again’ File Exposes Passwords and Keys in 1,122 Public Copies on GitHub” (Swati Khandelwal, November 7, 2026)
- Claude Code documentation — permissions and allow rules (Anthropic)