Breaking
AI & MLDeveloping Story

Claude Code's Saved-Command File Leaks Secrets

Apiiro found 1,122 public copies of a Claude Code settings file holding plaintext secrets, with nothing fixed for files already in git history.

··3 hours ago·6 min read
computer source code
Photo by Fahrul Razi on Unsplash

A settings file that Anthropic's Claude Code writes whenever a developer approves a shell command has turned into an accidental secret store on public GitHub. According to software security firm Apiiro, 1,122 public copies of the file contain at least one credential typed into a command that a user chose never to be asked about again.

The file carries the name .claude/settings.local.json, and its contents are plain JSON sitting inside a project folder. Deleting it after the fact does not erase what has already been pushed: older versions survive in git history and in forks.

How a secret lands in the file

Claude Code asks for confirmation before running most shell commands. When the person at the keyboard selects "Yes, and don't ask again," the assistant stores an allow rule in .claude/settings.local.json inside the project, as described in its permissions documentation. Commands matching that rule then run without a prompt in later sessions.

The rule captures only whatever the prompt offered at the time. Sometimes that is a pattern such as npm test *, but other times it is one exact command. In the second case, any password or token typed into that command is written down alongside it, in plain text.

Apiiro's researchers reported finding saved commands with the secret still embedded in public files, and they reproduced the behavior using the latest models, Opus 5.5 and Fable 5.1.

Anthropic does take one step to keep the file out of version control. The first time Claude Code writes the file inside a git repository, it adds the file to the user's global git excludes, according to its settings documentation. Git on that machine then ignores the file in every repository the user works in.

That protection lives in one person's git configuration on one computer. It does nothing for a file that has already been committed, and Claude Code never adds the file to the project's own .gitignore, so the exclusion does not travel with the codebase. In 539 of the 1,105 repositories the researchers traced, a commit listing Claude as a co-author changed the file, which they read as a sign that Claude frequently commits the file itself.

What Apiiro found on GitHub

Apiiro's sweep of public GitHub turned up 104,185 copies of the file across 103,617 repositories, as detailed in its research write-up. Roughly 1.1% of those copies, or 1,122 files, hold at least one secret. Between them, those files contain 1,379 distinct secrets.

A value qualified as a secret when it matched a known key format, or when a password or token appeared next to the address of a public server. An AI reviewer also had to concur. The researchers do not state whether any of the credentials have been used by anyone.

More than a third of the secrets open a database directly, including 379 database passwords. The rest include 43 SSH logins for public servers, 42 tokens for GitHub, GitLab and npm, and 23 AWS keys.

Among the owners of the affected files are 63 organizations, mostly software companies of varying size. The researchers describe the most serious cases as a database vendor's own admin-level cloud key and the owner password of a medical-records database.

As of Monday, every file containing a secret was still present on its repository's default branch, and in half of those repositories the file had been there for at least 217 days.

Current copies are not the whole picture. Older versions of the file hold 734 additional secrets across 509 repositories that do not appear in any current copy, usually because the file was later deleted. Forks carry the exposure further: 211 forks of 74 repositories contain the same secrets as the originals.

Secrets also appear in 298 of 76,011 copies of the shared .claude/settings.json file, which teams commit deliberately, mostly inside allow rules. Counting those, the older versions, and saved agent chat logs, the total reaches 2,539 secrets across 1,994 repositories.

Apiiro compared the documentation of 16 coding agents. Claude Code was the only one it confirmed saves the full approved command into a project file by default.

The numbers behind the leak

  • 1,122 public copies of .claude/settings.local.json contain at least one secret, out of 104,185 copies found across 103,617 repositories
  • 1,379 distinct secrets sit in those 1,122 files; more than a third open databases, including 379 database passwords
  • 43 SSH logins, 42 GitHub/GitLab/npm tokens and 23 AWS keys were also identified
  • 63 organizations own affected files; in half the affected repositories the file had been public for at least 217 days
  • Older file versions hold 734 more secrets across 509 repositories; 211 forks of 74 repositories carry identical secrets
  • Counting shared settings files and chat logs, Apiiro totals 2,539 secrets across 1,994 repositories

What developers should do first

Apiiro's guidance puts rotation ahead of cleanup, because removing the file does not reverse the exposure. Its recommended steps for developers:

  • Search your GitHub organization for .claude/settings.local.json and .claude/settings.json, and check each repository's git history for them, even where the files are no longer present.
  • Rotate every password, token and key the files have ever held before doing any tidying up.
  • Untrack the local file with git rm --cached .claude/settings.local.json and add it to the repository's own .gitignore.
  • Open the file on your own machine, even if it was never committed, and delete every rule containing a secret.
  • Keep secrets out of commands by referring to variables from a secrets manager, such as $DB_URL, so the saved rule records the variable name rather than the credential.
  • Approve patterns such as Bash(npm run:*) instead of single exact commands.

Copies that never reach GitHub still matter. The file is plain JSON in the project directory, and it can also end up inside an npm package, a Docker image, a zip archive, or a synced folder.

Malware has gone after developer machines for secrets before. In September 2025, the Shai-Hulud worm ran the TruffleHog secret scanner across infected computers, and the scanner flagged more than half of the files it examined as secret-bearing.

Why scanners miss these files

Common secret scanners struggle with this particular pattern. The researchers ran gitleaks and TruffleHog over every copy without the tools' verification step. Of the 1,122 files containing a secret, gitleaks flagged 564 and TruffleHog flagged 643, and 215 were flagged by neither.

Most of the misses are passwords typed inside commands. Scanners look for known key formats, and a password following PGPASSWORD=, sshpass -p, or mysql -p reads like an ordinary word on an ordinary command line.

Guidance for security teams

For security teams, Apiiro recommends treating agent folders such as .claude/, .cursor/, .gemini/ and .specstory/, along with agent memory files, as secret-bearing in the same way as .env files, both on laptops and in repositories. Those paths should be added to pre-commit and CI secret scanning, including coverage of git history, and scanners need to catch passwords inside commands rather than only known key formats.

The firm also suggests adding .claude/settings.local.json to an organization's .gitignore templates, and checking credentials paired with a public server first, because those are the ones that grant access.

Earlier reports went unanswered

This behavior has been reported before. An earlier bug report, filed on August 11, 2025, stated that approved commands containing API keys and tokens were being stored word for word in settings.local.json. An automated bot closed that report as "not planned" on January 3, after 60 days without activity.

As of the article's publication, the four related reports the researchers cite had all been closed by the same bot, the most recent the day before. None of them received a reply from Anthropic, according to the researchers.

What this means for teams

The practical consequence is that a convenience feature quietly turns routine approvals into a credential audit problem. Any organization that has run Claude Code against infrastructure — databases, cloud accounts, remote servers — now has to assume a file it may never have thought about holds live credentials, and that deleting the file is not the same as revoking them. This suggests incident response for many teams will start with a git history search rather than a scanner alert, and that the scanners themselves, tuned to recognizable key formats, may leave a meaningful share of command-line passwords untouched. The exposure is not confined to the repositories Apiiro counted: forks, npm packages, Docker images and synced folders can carry the same plaintext further than a single default branch.

#claude code#secrets exposure#github#developer security#anthropic#api keys

Sources

Iliyas

Founder & Editor, Xploitwire

This article was written and reviewed against the sources listed above before publication, under editorial policies set by Iliyas. Read our Editorial Policy →

← Back to all stories