Products & Services · · Team LATENT
Claude Code's "Don't ask again" and secrets in public repositories: inside 1,122 files, and the 19% two scanners missed
Security firm Apiiro examined 104,185 Claude Code settings files on public GitHub and found 1,379 secrets in 1,122 of them. Choosing "Don't ask again" at an approval prompt saves the command, password included, as a permission rule. We checked the mechanism against the original report, Claude Code's documentation and changelog, and GitHub issues, and calculated the kinds of secrets, how the share rises with file size, what the scanners missed and how many secrets remain in history. We also include steps to check your own repositories.
Ask Claude Code to check what is in a database, and it may propose a psql command that includes the connection password. Choose "Yes, and don't ask again" at the approval prompt, and Claude Code runs the command and writes the command string to .claude/settings.local.json as a permission rule. The password stays there in plain text, inside the project folder.
On November 5, security firm Apiiro published a report on these files in public GitHub repositories. Of 104,185 files, 1,122 contained 1,379 secrets, such as passwords and API keys. A figure of 2,539 also spread in the coverage, but that number combines other files and history. This article separates what each number counts and calculates the kinds of secrets, how the share relates to file size, what detection tools missed and how many secrets remain in history. At the end, it lists steps for checking your own repositories.
We checked the figures on November 8 against Apiiro's original report (published November 5, updated November 8), Claude Code's official documentation and changelog, and GitHub issues. Apiiro did not test any of the credentials it found. Its "real secrets" were judged by format and pairing with a public host, not confirmed as valid. The ratios are LATENT's calculations. This article does not cover how to find secrets in other people's repositories.
Apiiro report / Claude Code settings documentation / Claude Code permissions documentation
Key takeaways
- Apiiro examined 104,185
.claude/settings.local.jsonfiles on public GitHub and found 1,379 secrets in 1,122 of them (1.08%). Of those secrets, 36.3% were passwords or keys that open a database directly. Files over 8KB are 2.6% of all files but 24.3% of the files containing secrets. The more approvals a file accumulates, the more likely it holds a secret. - The scanner gitleaks detected 50.3% of the 1,122 files and TruffleHog 57.3%. Even used together, they missed 215 files, or 19.2%. Passwords written inside commands are hard for scanners that look for key formats to catch.
- The first time Claude Code writes this file, it registers it in that machine's git exclude settings. That registration does nothing on another machine or container, in a copied folder, or for a file already tracked. In 48.8% of repositories with secrets, a commit recording Claude as co-author had changed this file. Another 734 secrets survive only in past commits, so rotating keys comes first.
How Apiiro counted, and what each number means
The report's authors are Shmulik Cohen and Matan Giladi of Apiiro. From November 1 to 3, 2026, Apiiro read the default branches of public repositories using GitHub's code search and commit search. It collected all 104,185 .claude/settings.local.json files (in 103,617 repositories) and all 76,011 shared .claude/settings.json files. It also examined file history in 43,120 repositories.
Secrets were counted in two kinds. One is keys matching a provider's format, such as OpenAI, Anthropic, AWS, GitHub and Supabase. The other is passwords and tokens with no fixed format, counted only when a public host appears on the same line. Placeholders, common default passwords, local hosts and keys meant to be public were excluded. Apiiro also had an LLM reviewer judge the remaining 2,774 distinct values in redacted form, and counted only values that both the rules and the reviewer judged real. Apiiro writes that it shared the research with Anthropic before publication and contacted affected organizations on November 2 and 3.
The numbers in the coverage each count something different. Table 1 sorts them out.
| Number | What it counts |
|---|---|
| 104,185 | .claude/settings.local.json files on public GitHub |
| 1,122 | Of those, files containing at least one real secret (1.08%) |
| 1,379 | Distinct secrets in those 1,122 files |
| 734 | Secrets found only in past commits of the file, not in any current file (509 repositories) |
| 1,160 | Additional secrets found in history, shared settings files and chat transcripts |
| 2,539 | Distinct secrets across everything examined (1,994 repositories) |
Subtracting 1,379 from 2,539 gives 1,160, matching the report. Subtracting the 734 from history leaves 426, which appears to be the shared settings files and chat transcripts, though the breakdown is not published. That works out to 1.23 secrets per file on average.
How approved commands end up in a settings file
According to Claude Code's permissions documentation, choosing "Yes, and don't ask again" when approving a Bash command makes the approval permanent per repository and command. It is saved as a permissions.allow rule in .claude/settings.local.json at the repository root. The prompt shows the form of the rule to be saved, as in "Yes, and don't ask again for: npm test *". For a command joined with &&, up to five rules can be saved, one for each part that needs approval.
File-edit approvals last only until the session ends. Approvals that persist are those for Bash commands, WebFetch domains and web search.
A figure in Apiiro's report shows the shapes of the leaked rules: a psql command passing a password through an environment variable, an ssh command passing a password to sshpass with -p, a curl command with a token in the Authorization header, and a psql command whose connection string includes a username and password. Its example of a safe rule takes arguments with *, as in npm run, and contains no secret.
Apiiro reproduced the behavior with Opus 5.5 and Fable 5.1 and concluded that it is Claude Code's behavior, not the model's. It also compared the documentation of 16 coding agents and writes that Claude Code was the only one it could confirm writes the full text of approved commands to a project file by default. The report does not name the 16 tools or include the comparison table.
Where the rule is saved depends on where you use Claude Code. According to the settings documentation, the CLI writes only to your own .claude/settings.local.json. In the VS Code extension, the approval prompt lets you pick the destination file, including the team's shared .claude/settings.json. Issues #77530 in July 2026 and #91270 in September reported approvals in the VS Code extension being written to the shared settings file.
Claude Code permissions documentation / Claude Code settings documentation / Issue #77530 / Issue #91270
When the git exclude registration does not help
According to the settings documentation, the first time Claude Code writes this file in a git repository, it adds **/.claude/settings.local.json to the global git excludes file. That file is the path set in core.excludesFile, or ~/.config/git/ignore if none is set. The registration keeps the file out of commits in every repository on that machine. A file you create by hand is not covered, and the documentation says to add it to .gitignore yourself.
The registration goes into that machine's settings, not the repository's .gitignore. On Hacker News, Apiiro's author listed three cases where it does not help: a new machine or container without the global exclude, a copied project folder, and a file that has already been committed. Git does not apply exclude rules to tracked files, so once committed, later changes to the file are recorded too. Apiiro's report also lists folders that became git repositories later.
Claude Code's changelog contains related fixes. Version 2.1.307 fixed self-hosted runner sessions committing a .claude/settings.local.json left by an earlier session. Version 2.1.271 made the VS Code extension's hooks dialog register the file as ignored before the save returns. Among GitHub issues, #11982 from November 2025 reported that creating the file in 2.0.46 did not add it to the excludes.
Of the 1,105 repositories with secrets that Apiiro tracked, 539 (48.8%) had a commit recording Claude as co-author that changed this file. The models recorded ranged from Sonnet 4.5 to Opus 5.5.
Claude Code settings documentation / Claude Code changelog / Apiiro author's comment on Hacker News / Issue #11982
The kinds of the 1,379 secrets
Table 2 breaks down the 1,379 secrets. There are 636 keys in provider formats and 743 passwords or tokens used with public hosts.
| Kind | Count |
|---|---|
| Service API tokens | 398 |
| Database passwords | 379 |
| AI model API keys | 149 |
| Supabase service-role keys | 122 |
| Google API keys | 110 |
| Supabase account tokens | 103 |
| SSH logins to public servers | 43 |
| GitHub, GitLab and npm tokens | 42 |
| AWS keys | 23 |
| App and account passwords | 9 |
| Private keys | 6 |
.claude/settings.local.json files. Source: figure in Apiiro's reportDatabase passwords and Supabase service-role keys together, 501 secrets, open a database directly. That is 36.3% of the 1,379. Supabase account tokens can operate every project in the account; adding them gives 604, or 43.8%. AI model API keys number 149, or 10.8%. The 11 kinds add up to 1,384, five more than the total. The report does not explain the difference.
Apiiro counted 63 organizations with real secrets in public allow lists. One confirmed that its key had been valid. Examples include an admin API key from a database provider, the production Azure Postgres password of a B2B startup, and the database owner password of an IT company that builds a medical records app. There were 43 SSH credentials for public servers, some of them root passwords passed to sshpass.
File size and the share with secrets
Apiiro also showed the share of files containing secrets by file size (Table 3). Each approval adds a rule, so the file grows as approvals accumulate.
| File size | Files | Share with real secrets | Estimated files with secrets |
|---|---|---|---|
| Under 500B | 55,453 | 0.17% | About 94 |
| 500B–1KB | 19,770 | 0.51% | About 101 |
| 1–2KB | 13,474 | 1.3% | About 175 |
| 2–4KB | 8,449 | 2.8% | About 237 |
| 4–8KB | 4,284 | 5.6% | About 240 |
| Over 8KB | 2,755 | 9.9% | About 273 |
The estimate column is LATENT's calculation, multiplying the file count by the share. The total is about 1,120, close to the report's 1,122.
At 9.9%, the share for files over 8KB is about 58 times the 0.17% for files under 500B. By file count, files under 1KB make up 72.2% of all files but only 17.4% of files with secrets. Files over 8KB are 2.6% of all files yet 24.3% of files with secrets.
The more approvals a file holds, the more times a command containing a secret has likely been approved. It is efficient to start checking with large files that hold many rules.
The 215 files two scanners missed
Apiiro ran two open-source scanners, gitleaks and TruffleHog, over the 1,122 files. Gitleaks detected 564 and TruffleHog 643, and 215 were detected by neither. From these, both detected 300, gitleaks alone 264 and TruffleHog alone 343 (Figure 3).
The detection rate is 50.3% for gitleaks and 57.3% for TruffleHog. Together they reach 80.8%, leaving 19.2%. About one file in five is not found even with both scanners.
According to Apiiro, the misses come from passwords inside commands. The two scanners look for key formats, such as provider prefixes and long random strings. A password after PGPASSWORD=, sshpass -p or mysql -p, or a curl Bearer header, looks like an ordinary word in an ordinary command. Gitleaks searches with per-rule regular expressions and entropy, and TruffleHog with per-detector regular expressions and keywords. Apiiro recommends extending scanning rules to catch passwords inside commands. The two tools were run without their verification features, and their versions and settings are not given.
GitHub's push protection stops secrets at push time. According to GitHub, 0.47% of public pushes in April to June 2026 contained secrets. Push protection stops about 30% of new secrets before they enter history, it says. Since October 13, it has blocked Anthropic API keys by default, including in free public repositories. This system, too, mainly targets keys in provider formats.
On October 28, GitHub added a classifier for secrets without fixed formats to push protection and opened a public preview. In early results, the number of pushes where it stopped secrets more than doubled. It is off by default and requires the paid GitHub Secret Protection or Advanced Security. How well it catches passwords inside commands has not been published.
gitleaks / TruffleHog / GitHub changelog
History and forks that survive deletion
In the median repository with secrets, the file had existed for 217 days as of November 2, 2026. In 118 repositories, the first commit was more than a year earlier. There are 734 secrets found only in past commits of the file and not in any current file (509 repositories). Removing a rule from the file leaves it in git history. There are also 211 forks holding the same secrets, from 74 original repositories.
Exposed keys get used quickly. In a 2023 experiment, Palo Alto Networks' Unit 42 reported attackers finding and using AWS credentials exposed on GitHub within five minutes. In Comparitech's honeypot, abuse of an AWS key began within a minute. The median of 217 days is about 310,000 minutes, more than 60,000 times five minutes. Given how long the files were public, secrets that are gone now still need to be rotated.
Keys that are not rotated stay valid for a long time. GitGuardian's 2026 report says 64% of secrets confirmed valid in 2022 were still valid in January 2026. GitHub writes that manual revocation takes about 40 days on average, and one in five takes more than 90 days.
GitHub's documentation says to revoke or rotate a secret before removing it from history. Rewriting history with git-filter-repo does not remove it from other people's clones or forks. In views GitHub has cached, the commit may still be visible by its hash.
Unit 42 / Comparitech / GitGuardian, "The State of Secrets Sprawl 2026" / GitHub blog / GitHub documentation
Files that never reach GitHub
According to Apiiro, most of these files never reach GitHub and stay on developers' machines, as plain-text JSON inside project folders. The 1,122 found in public repositories are only part of the files of this kind on developers' machines.
Attacks on files on developer machines have been reported. The npm worm Shai-Hulud, which spread in September 2025, downloaded TruffleHog onto infected machines and searched their files for secrets. In Apiiro's study, TruffleHog detected 57.3% of the 1,122 files. About three weeks earlier, malicious Nx packages had made Claude Code and Gemini CLI on developers' machines search the disk for secrets.
Some routes bypass git entirely. Apiiro lists published npm packages, Docker images built by copying whole folders, zip files and synced folders. The global git exclude that Claude Code registers has no effect on routes outside git. For an npm package, .claude/ needs to be excluded with files or .npmignore, and for Docker with .dockerignore.
Comparison with other files
Apiiro also examined other files where agents leave records. Table 4 lists those where a share can be calculated by file count.
| File | Examined | Files with real secrets | Share |
|---|---|---|---|
| Chat transcripts (.specstory, aider, Cursor exports) | 2,523 | 120 | 4.8% |
| Handoff and deploy notes | 2,095 | 33 | 1.6% |
.claude/settings.local.json |
104,185 | 1,122 | 1.08% |
Shared .claude/settings.json |
76,011 | 298 | 0.39% |
The share for the personal settings file is about 2.7 times that of the shared settings file. Most secrets in the shared settings files, too, sat in allow rules containing full commands. Chat transcripts, at 4.8%, have a higher share than the settings files. A third of the handoff notes containing secrets were written by agents themselves.
Compared with public repositories as a whole, this is a narrow slice. GitGuardian detected 28,649,024 secrets in public GitHub commits in 2025. Apiiro's 2,539 are 0.009% of that. GitGuardian puts the leak rate for commits involving Claude Code at 3.2%, against 1.5% for all public commits. We could not confirm the denominator of that comparison from the report. In a chart in the same report, leaks in commits involving Claude Code peaked at 31 per 1,000 commits in August 2025 and fell to 13 by December, roughly the same as human commits.
Apiiro report / GitGuardian report
Postman Desktop rewriting agent settings
Around the same time, another company's app was found rewriting agent settings files. On October 25, a Postman Desktop user reported on GitHub that in version 12.33.4, during an update for existing users, Postman plugins for Codex and Claude Code were installed without confirmation.
According to the report, enabling the plugin and a trust record for a startup hook were added to Codex's ~/.codex/config.toml. In Claude Code's ~/.claude/settings.json, the Postman plugin was enabled. The installer included code that tried to mark its own hook as approved. The reporter noted that this does not prove who created the trust record.
On November 5, a member of the Postman organization wrote that the change would be rolled back for now, and the founder's account closed and locked the issue. We could not find a desktop release note that explicitly mentions the rollback. Version 12.35.5 on November 6 says only "Some critical bug fixes."
This case has a different cause from Apiiro's. What they share is that agent settings files decide permissions and startup behavior. Developers need to check these files on the assumption that other apps may write to them.
Anthropic's response
On November 7, Boris Cherny of the Claude Code team responded in the Hacker News thread. He wrote that Claude Code has not historically scrubbed secrets but that the team is looking into ways to prevent this. He explained that .claude/settings.local.json is meant to stay local, that Claude automatically adds it to the ignore list when it creates the file, and that in this case the files were created and committed by hand. Apiiro's author replied that in 539 of 1,105 repositories, a commit recording Claude as co-author had changed the file.
Cherny also wrote that permission rules are "old hat" and that everyone should use auto mode, which he said is on by default and included in all plans. He recommended enabling secret scanning whatever agent you use. In follow-up comments, he listed ideas such as having auto mode catch this and building in basic secret scanning, and said the team would prototype before shipping. To the point that auto mode still shows a prompt for sensitive commands, where the default choice "always allow" saves the approval, he replied that he was thinking about how to improve it.
As of November 8, the latest version in Claude Code's changelog is 2.1.319. Searching the changelog, we found no change that redacts secrets in approved commands before saving them.
The problem had been reported on GitHub before. Table 5 lists the main issues; none has a reply from Anthropic staff.
| Issue | Opened | Report | Closed and why |
|---|---|---|---|
| #5544 | August 11, 2025 | Approved commands containing credentials are saved in plain text | January 3, 2026, closed by a bot after 60 days of inactivity |
| #11982 | November 19, 2025 | Creating the file in 2.0.46 does not add it to the excludes | March 5, 2026, closed by a bot for inactivity |
| #13106 | December 4, 2025 | Keys in the file were pushed to a public repository | December 8, 2025, closed by a bot as a duplicate of #11982 |
| #77530 | July 14, 2026 | VS Code writes approvals to the shared settings file | September 3, 2026, closed by a bot for inactivity |
| #91270 | September 1, 2026 | VS Code writes approvals to a tracked shared settings file | November 5, 2026, closed by a bot for inactivity |
Issue #91270 was closed on the day Apiiro published its report. There is earlier research outside the issues as well. In February 2026, security firm ironPeak reported finding the same file in its own repositories. Examining repositories with AI settings folders, it found secrets in history in 2.4%. It counted only secrets TruffleHog verified as valid, and the sample was small, at 100.
Boris Cherny's comment on Hacker News / Follow-up comment / Issue #5544 / Claude Code changelog / ironPeak research
Checking and fixing your own repositories
Based on Apiiro's recommendations and GitHub's documentation, here are steps for checking your own repositories. Running these commands at the project root shows the state of the settings files.
git ls-files .claude
git check-ignore -v .claude/settings.local.json
git log --all --oneline -- .claude/settings.local.json .claude/settings.json
git config --global core.excludesFile
The first line lists tracked files in .claude. If settings.local.json appears, the file has been committed. The second line shows which exclude setting keeps the file out. If nothing appears, the file is either not excluded or already tracked. The third line lists past commits that changed either settings file. The fourth shows where the global exclude file is.
The surest way to check whether permission rules contain passwords is to open the file and read it. The command shapes Apiiro listed can be found with this command.
grep -nE 'PGPASSWORD=|sshpass -p|mysql .*-p|[Bb]earer |://[^/:@ ]+:[^@ ]+@' .claude/settings.local.json .claude/settings.json
The last pattern looks for passwords in connection strings, as in postgres://user:password@host. Even if this command finds nothing, secrets without a fixed format may remain.
If you find something, deal with it in this order. First, revoke or rotate the key or password with each service. If the file was ever public, rotate even what is no longer there. Next, delete the rule lines from the file. If the file is tracked, stop tracking it with git rm --cached .claude/settings.local.json and add .claude/settings.local.json to the repository's .gitignore. To remove it from history, use git-filter-repo as GitHub's documentation recommends. Copies in forks and other people's clones remain.
Table 6 summarizes rotation steps for major services.
| Service | Key steps |
|---|---|
| AWS | Create a second access key, switch the app to it, deactivate the old key, then delete it |
| GitHub | Personal access tokens and similar tokens pushed to a public repository are revoked automatically |
| OpenAI | Rotate the key on the API keys page and update production values |
| Anthropic | Delete the key in the Console. As a GitHub secret scanning partner, keys found in public repositories are disabled automatically |
| Stripe | Create a new key with "Rotate key," set an expiration on the old key and delete it |
| Supabase | If a service_role key or similar leaks, fix the cause, then follow the rotation guide |
| npm | Delete it on the Access Tokens page or with npm token delete. Revocation can take up to an hour |
Database passwords and SSH passwords do not expire automatically when exposed. In Apiiro's count, 36.3% of secrets open a database directly, and rotating them is manual work for operators.
Apiiro's recommendations and the official documentation also cover prevention. If secrets are referenced through environment variables, such as $DB_URL, instead of written into commands, the rule records only the variable name. Approve patterns such as Bash(npm run test *) rather than literal commands. Add rules for passwords inside commands, such as PGPASSWORD= and sshpass -p, to pre-commit and CI secret scanning. Treat .claude/ and chat transcript folders like .env, as files that contain secrets. To keep Claude from reading .env, add Read(./.env) to permissions.deny in your settings.
GitHub: Removing sensitive data from a repository / AWS / GitHub: Token expiration and revocation / OpenAI / Anthropic / Stripe / Supabase / npm
What we will check next
There are three things LATENT will check next.
The first is a fix in Claude Code. When a version with the secret scanning Cherny mentioned ships, we will check which forms of passwords it redacts before saving. We will also check whether the VS Code extension keeps the option to write to the shared settings file.
The second is Apiiro's comparison of 16 tools. Knowing how and where other agents save approvals would show whether this type of problem is limited to Claude Code.
The third is GitHub's new classifier. Once public preview results are available, we can compare how far it reduces missed passwords inside commands against Apiiro's 19.2%.
Sources and scope
We read Apiiro's original report on November 8. The report was updated on November 8, but it does not say what changed. The report does not give the date Apiiro shared the research with Anthropic. We could not confirm why the totals by kind exceed the overall count by five, or the breakdown of the 426. The versions and settings of gitleaks and TruffleHog are not given.
Claude Code's mechanism was checked on November 8 against the official settings and permissions documentation and the changelog. Anthropic's response was checked against Boris Cherny's original comments on Hacker News through its API. We found no statement issued to the press. For GitHub issues, we checked the opening date, state and reason for closing.
The Postman case was checked against the GitHub issue, Postman's plugin repository and the release notes. For GitGuardian's 3.2% and 1.5%, we could not confirm the denominator in the report. Times until exposed keys were used come from figures published by Unit 42 and Comparitech.
Ratios, the scanner breakdown, composition and estimates by file size, and the conversion to minutes were calculated by LATENT from the figures in the sources. The checking commands were tested on sample files.
- Apiiro, "Coding Agents Copy Your Secrets to a Hidden File. Thousands Are on GitHub"
- Claude Code, "Settings files and precedence"
- Claude Code, "Configure permissions"
- Claude Code changelog
- Hacker News thread
- anthropics/claude-code issue #5544
- postmanlabs/postman-app-support issue #14370
- GitGuardian, "The State of Secrets Sprawl 2026"
- GitHub, "Secret protection must scale with software"
- GitHub, "Push protection beyond predefined secret patterns"
- GitHub, "Removing sensitive data from a repository"
- Unit 42, "EleKtra-Leak"