Claude Code's "Don't Ask Again" Leaked 2,539 Secrets to GitHub
Apiiro found 2,539 secrets across 1,994 public GitHub repositories, saved there by Claude Code's "Yes, and don't ask again" prompt. Why gitignore failed, why scanners missed 215 files, and the six-step fix.
The Button That Committed Your Password
On the fifth of November, Apiiro, an application security company, published research that should make anyone who has ever clicked "Yes, and don't ask again" in Claude Code stop and check a file. The toggle that saves you from approving the same shell command twice also writes that command, word for word, into a project settings file. If the command carried a password, so does the file.
The numbers are not abstract. Apiiro scanned public GitHub and found 2,539 distinct secrets across 1,994 repositories belonging to 63 organizations, most of them software companies. One organization confirmed that its exposed key had still been live. The mechanism has been reported in GitHub issues since August 2025 (#5544, #11982, #13106, #91270), and as of November 7, 2026, there is no shipped fix.
This is less a bug in a specific model and more a collision between how coding agents are designed and how humans behave.
How a password ends up in a committed file
Claude Code asks before it runs most shell commands. When you choose "Yes, and don't ask again," it writes a permission rule into .claude/settings.local.json at the repository root. Matching commands run without prompting in later sessions.
The rule is the command string itself. Depending on what the prompt offered, that is either:
- a pattern, such as
npm test *, or - one exact command, such as
psql postgres://admin:P@ssw0rd@prod-db:5432/app
In the second case, the credential is stored in plain text. Apiiro reproduced the behaviour with the latest models, Opus 5.5 and Fable 5.1, which means upgrading your model does not fix it. This lives in the harness, not the model.
The scale, measured
Apiiro collected data between November 1 and November 3, 2026:
- 104,185 public copies of
.claude/settings.local.jsonacross 103,617 repositories - 1,122 copies (about 1.1%) holding at least one real secret
- 1,379 distinct secrets in those files
- 636 keys in a known provider format
- 743 passwords or tokens sitting next to a public host
- 734 more secrets only in older file versions, across 509 repositories
- 211 forks of 74 repositories carrying identical secrets
- 298 secrets in 76,011 copies of the shared
.claude/settings.json - 2,539 total across 1,994 repositories at 63 organizations
The breakdown is unkind. There were 398 service API tokens, 379 database passwords, 149 AI model API keys, 122 Supabase service-role keys, 110 Google API keys, 103 Supabase account tokens, 43 SSH server logins, 42 GitHub/GitLab/npm tokens and 23 AWS keys. Among the worst findings: an admin-level cloud key for a database vendor, a Square production token, and the owner password for a medical-records database.
Half of the affected repositories had kept the file on their default branch for at least 217 days.
Why gitignore did not save anyone
This is the part worth understanding rather than just remediating. Claude Code adds the file to the developer's global git ignore. That protection collapses in three common situations:
.gitignore, so it does not travel with the code.So both humans and the agent commit the file. In 539 of the 1,105 traced repositories, commits co-authored by Claude modified the secret-bearing file. The agent was not merely a passive victim of a configuration mistake; it committed the evidence.
Your secret scanner probably missed it
Apiiro compared against existing tooling. gitleaks flagged 564 of the affected files, TruffleHog detected 643, and 215 were caught by neither. A clean scan is not a clean repository.
The researchers also compared documentation for 16 coding agents. Claude Code is the only one confirmed to save the full approved command in a project file by default.
What to do, in the right order
Order matters here. Rotate before you delete anything, because deleting the file does not clear git history, forks or clones.
1. Search your organisation, including history
Search every repository for .claude/settings.local.json and .claude/settings.json. Check the git history of repositories even where the file is gone from the current tree.
2. Rotate every credential the file has ever held
This comes first, before cleanup. Any password, token or key that has passed through an allow rule should be treated as public.
3. Untrack the file
git rm --cached .claude/settings.local.json
Then add the path to the repository's own .gitignore, not just your global one, so the rule travels with the project.
4. Read your local copy
Even if it was never committed, open the file and delete every allow rule containing a secret. Old commands from earlier sessions may still be sitting there.
5. Keep secrets out of commands
Reference credentials as variables from a secrets manager, such as $DB_URL. The saved rule then contains the variable name, and the value stays out of the file.
6. Approve patterns, not single commands
Prefer Bash(npm run:*) over an exact command containing arguments. Before clicking the convenience option, read what the prompt is offering to save.
The lesson is about defaults, not models
The same week, a separate report described Claude Code sending users' email addresses to websites. Both stories point the same direction: what leaves your machine is decided by the harness and its defaults, not by how capable the model is.
Three things worth carrying forward:
- Understand what a convenience button writes before you press it. "Don't ask again" is a permission rule with a file on the other end.
- Rotate first, clean second. Git history is not a place where deletions happen.
- Treat secret scanners as a supplement. Missing 215 files is enough to show that passing a scan is not the same as being safe.
As agentic development becomes the default, the interesting question in a security review is shifting. It is no longer only "what did the AI write?" but "what did the AI write down, and where?" Teams that do not ask the second question will keep rediscovering this leak, one tool at a time.