GitHub holds Claude Code secrets in 1,122 files
Apiiro found secrets in 1,122 public Claude Code local settings files on GitHub because permanent approvals can save commands containing plaintext credentials. Rotate exposed credentials before removing tracked files and adding .claude/settings.local.json to .gitignore. History, forks, shared settings and release artifacts still need checking.
Summary written with AI from this article, and checked against it.

Affected systems and impact
| Flaw | Affected systems | Impact |
|---|---|---|
| Permanent command approvals save literal credentials in plaintext allow rules | Claude Code .claude/settings.local.json and .claude/settings.json containing approved commands with secrets | Database passwords, server logins and cloud keys can be exposed through public repositories and distributed project files |
| Global Git exclusion does not untrack files or add a project-level ignore rule | Claude Code .claude/settings.local.json already tracked by Git or moved between developers and machines | Local settings containing credentials can remain tracked and be published |
| Secret scanning misses passwords embedded in ordinary commands | gitleaks and TruffleHog scans without verification of public Claude Code settings files | Neither scanner flagged 215 files containing secrets |
Apiiro found Claude Code secrets in 1,122 public copies of its local settings file on GitHub. The credentials were embedded in commands saved after users selected Yes, and don't ask again. If those files are in your project, rotate the credentials before you start cleaning up. The work involves more than deleting a file: you need to check repository history and the approval rules that saved the secrets in the first place.
For anyone approving database or server commands, this can expose rather more than a development preference. The report on Apiiro's research describes database passwords, server logins and cloud keys inside saved rules. One company the researchers notified confirmed that its exposed key had been live. Deleting the file you see today does not remove earlier copies from Git history or from repository forks.
How Claude Code secrets enter local settings
A permanent command approval can leave you with a plaintext record of a credential. Claude Code normally asks before running most shell commands. When a developer chooses the option to stop asking, it can write an allow rule to .claude/settings.local.json. Commands matching that rule can then run in later sessions without another approval.
What gets saved depends on what the permission prompt offered. It might be a pattern, such as npm test *, or it might be one exact command. That second case is the problem here. If the exact command contains a password or token, the credential can become part of the saved rule. The setting preserves both the instruction and the secret typed into it.
Claude Code does try to keep this file out of Git. According to its settings documentation, as described in the report, the first write inside a Git repository adds the path to the user's global Git excludes. That exclusion applies across repositories on that computer. It is still part of that user's local Git configuration, though, rather than something recorded in the project.
The exclusion does not fix a file that Git already tracks, and Claude Code does not add the path to the project's own .gitignore. I'd treat it as a personal safeguard, not a repository policy. When the project moves between developers and machines, that distinction has a practical consequence: the local exclusion does not travel with the project.

Audit Claude Code files and rotate before cleanup
The researchers recommend checking current files and historical copies. Then deal with the credentials before turning to repository housekeeping.
Search your GitHub organization for
.claude/settings.local.jsonand.claude/settings.json. Inspect each repository's Git history for both paths, including repositories where the files have disappeared. The shared settings file is part of this search for a reason: Apiiro found secrets there too, mostly inside allow rules. A review limited to the local-settings filename would leave those findings out.Rotate every password, token and key the files have held before cleaning up. I'd prioritise credentials paired with public server addresses, following the researchers' advice, because those combinations provide access. Include historical credentials rather than checking only what the latest file contains. Removing a saved command changes the file; it does not change the password or revoke the token that was embedded in that command.
To stop Git tracking the local settings file, run the command recommended by the researchers from the repository:
git rm --cached .claude/settings.local.jsonThis stops tracking the local file. It does not replace credential rotation, and it does not settle the question of which copies remain elsewhere. Keep that investigation separate from this change to Git tracking.
Add the local settings path to the repository's own
.gitignore, rather than depending only on a developer's global exclusion:.claude/settings.local.jsonKeep the rule specific to this local file. The report distinguishes it from
.claude/settings.json, which teams deliberately commit. That shared file still needs inspection for rules containing secrets; it is not the file this ignore rule addresses.Open the local settings file on your own computer and remove every rule containing a secret. Do this even if the file was never committed. Keep the history and fork findings in the cleanup scope, too: the disappearance of the current file is not the end of the work.
Keep literal credentials out of future commands. The researchers recommend references supplied through a secrets manager, such as
$DB_URL, so that the saved rule contains the variable name rather than its value. For repeatable tasks, they give this example of an approval pattern:Bash(npm run:*)Check what scope the permission prompt actually offers before accepting it. Permanent approval does not necessarily mean approval of a pattern. It can still save one exact command, including whatever that command contains.
History and forks widen the credential search
A clean current directory does not tell you what was exposed before it was cleaned. Apiiro found additional Claude Code secrets only in older file versions, usually after someone had deleted the file. Forks also retained copies of secrets from their original repositories. Both findings matter even when the current file looks harmless or is gone.
Apiiro reported the following counts across current settings, historical content and the broader investigation. These scopes overlap; the figures are not separate totals to add together.
| Search scope | Apiiro's reported finding |
|---|---|
| Current local settings files | 1,122 copies containing 1,379 different secrets |
| Current shared settings files | 298 copies containing secrets |
| Secrets absent from current copies | 734 additional secrets across 509 repositories |
| Forks retaining the originals' secrets | 211 forks of 74 repositories |
| Combined scope, including saved agent chat logs | 2,539 secrets across 1,994 repositories |
The local-settings search covered 104,185 public copies across 103,617 repositories, according to Apiiro. Keep that denominator alongside the finding. The researchers did not claim that every published settings file held a credential. They found that some did, and that a single file could retain more than one secret.
At the researchers' Monday checkpoint, every file containing a secret was still on its repository's default branch. In half of those repositories, the file had been there for at least 217 days.
The shared settings file and saved agent chat logs belong in that investigation as well. Correcting the local-file ignore rule addresses one part of the reported exposure, but it leaves those other places to check.
Secret scanners miss command-line passwords
A negative scanner result is not enough to clear these files. Apiiro ran gitleaks and TruffleHog against every copy without the tools' verification step. Of the 1,122 files the researchers identified as containing secrets, gitleaks flagged 564 and TruffleHog flagged 643. There were 215 files that neither tool flagged.
The report attributes many of the misses to passwords sitting inside otherwise ordinary commands. A value after PGPASSWORD= or mysql -p may not look like a recognisable service token. Looking for known key formats and checking whether a saved command contains a password are different tasks. The former does not settle the latter.
I would use scanner findings to support the review, not to dismiss a credential visible in an allow rule. Apiiro's own identification process combined known key formats or credentials beside public-server addresses with agreement from an AI reviewer. Its reported counts were not simply the output of gitleaks or TruffleHog, and the scanner results need to be read with that distinction intact.
The findings also have a clear limit. Apiiro did not test whether the collected secrets still worked, and the researchers did not say that anyone had used them. The research demonstrates exposure, not widespread credential abuse. One company confirmed that one key had been live; that confirmation does not establish that every credential in the collection remains usable.
Keep agent state out of release artifacts
A file does not have to reach GitHub to need attention here. The researchers note that the local settings file is plain JSON in the project folder. It can also end up in an npm package, a Docker image, a zip archive or a synced folder. Keeping it out of the repository does not, by itself, address any of those distribution paths.
For security teams, the researchers recommend applying existing secret-handling controls to agent state as well. Their recommendations cover both where these files live and what the scanning checks:
Treat folders such as
.claude/,.cursor/,.gemini/and.specstory/, along with agent memory files, as potentially secret-bearing material, just as you would.envfiles. Apply that treatment on developer laptops as well as in repositories; the repository is not the only place these files need attention.Include those files and Git history in pre-commit and continuous integration secret scanning. Check that scanning catches passwords inside commands, rather than only familiar key formats. Add
.claude/settings.local.jsonto the organization's repository-ignore templates as part of those controls.
I'd keep approval shortcuts for commands that contain no credentials. For any Claude Code secrets already found, treat the credential problem first and the Git problem second: rotate, clean up tracking and ignore rules, then change how commands receive secrets. After rotation and repository cleanup, check the next command you approve: it should receive a secret reference, not contain the literal credential.
Frequently asked questions
Which models did Apiiro use to reproduce the command-saving behavior?
The report says Apiiro reproduced the behavior with Opus 5.5 and Fable 5.1. That reproduction concerns saving approved commands containing secrets; it does not establish whether the publicly collected credentials were still valid.
Did Apiiro compare Claude Code with other coding agents?
Apiiro compared documentation for 16 coding agents. Within that comparison, Claude Code was the only one confirmed to save the full approved command in a project file by default. That is a scoped finding, not a claim about every possible agent or configuration.
Had users reported this behavior before?
An earlier bug report filed on August 11, 2025 described approved commands containing API keys and tokens being stored verbatim in settings.local.json. Apiiro says all four related reports it cited had been closed by an automated bot, and none had received a reply from Anthropic.
Source
- News reportClaude Code's “Don't Ask Again” File Exposes Passwords and Keys in 1,122 Public Copies on GitHub · thehackernews.com
