Secretus logo
newsapiiroclaude-codecoding-agents

Apiiro: Over 1,100 Public Claude Code Settings Files Hold Secrets Typed Into Approved Commands

Apiiro reports passwords and keys saved in plain text in .claude/settings.local.json files on public GitHub. How a command approval stores a secret, what is unproven, and how to rotate, clean up and stop it recurring.

·9 min read·Secretus Editorial

You typed a database password into a command once, approved it, and told your coding assistant not to ask again. The assistant remembered the whole command, password included, in a file in your project folder. Security company Apiiro reports that this has put secrets into public GitHub repositories at scale: of 104,185 public copies of Claude Code's local settings file that it found, 1,122 held at least one secret. Apiiro says it did not test whether any of them still work.

This is research, not a breach. Nobody has reported that the exposed values were used. But attackers are already hunting public repositories for exactly this kind of value, and we coveredMicrosoft's report of AI agents going from a GitHub search to Azure Key Vault in five minutesonly days ago. A secret that sits in a public repository should be assumed found.

What Apiiro reports

The research is a vendor's own, and Apiiro sells application and agent security products. We could not open Apiiro's write-up; the figures below come from The Hacker News and iTWire, which report them, and both outlets say the researchers did not test the credentials. The numbers are Apiiro's and have not been independently reproduced, as far as we can see.

  • The sample. 104,185 public copies of .claude/settings.local.json in 103,617 repositories, collected from public GitHub search in early November.
  • The hits. 1,122 of those copies, about 1.1%, contain at least one secret, 1,379 different values in all. A value counted when it matched a known key format, or when a password or token sat next to a public server's address, and an AI reviewer agreed.
  • What they were. 379 database passwords, 43 SSH logins for public servers, 42 tokens for GitHub, GitLab and npm, and 23 AWS keys, with more than a third of the secrets opening a database directly. The files belong to 63 organisations, mostly software companies.
  • Older versions and other files. A further 734 secrets sit in earlier versions of the file in 509 repositories, and 298 of 76,011 copies of the deliberately shared .claude/settings.json contain secrets. Counting those, older versions and saved agent chat logs, the total is 2,539 secrets in 1,994 repositories.
  • How long they have been there. As of the Monday after publication, every file with a secret was still on its default branch, and in half of those repositories it had been there for at least 217 days.
  • Scanners miss many. On the 1,122 files, gitleaks flagged 564 and TruffleHog 643, and neither flagged 215, mostly passwords typed inside commands, since they lack a recognisable key format.

How a secret ends up in the file

Anthropic's own documentation confirms the mechanism's first half. When a user chooses “Yes, and don't ask again” for something like a Bash command, Claude Code saves the rule to .claude/settings.local.json at the root of the git repository. The rule can be a pattern, or one exact command. When it is the exact command, anything typed into it is saved too, in plain text, which is what the researchers found in public files.

The documentation also says what protects the file. The first time Claude Code writes it in a repository, it adds the file to the user's global git excludes, so it stays out of that user's commits. That is a setting on one computer. It does not travel with the project, and it does nothing for a file someone has already committed, or created by hand and not ignored. Apiiro's researchers also say Claude Code never adds the file to the project's own.gitignore. In 539 of 1,105 repositories they traced, a commit listing Claude as a co-author changed the file, which they read as Claude often committing it. iTWire notes that this does not establish that Claude introduced every exposed credential.

The problem was reported publicly before. A GitHub issue opened in August 2025 described approved commands with credentials stored in plain text in this file, and was closed as “not planned” in January 2026. We have not seen a statement from Anthropic on the new research.

What is not established

  • That the secrets still work or were used. Apiiro did not test them. One notified company, according to The Hacker News, confirmed that its key had been live.
  • The exact count. Outlets differ on whether 2,539 means distinct values, and we could not compare against Apiiro's own text.
  • That other tools are safe. Apiiro compared documentation for 16 coding agents and says Claude Code is the only one confirmed to save the full approved command in a project file by default. That is a statement about defaults and documentation. Other agents keep their own folders, chat logs and memory files, and those can hold secrets too.
  • How these files were exposed. A developer committing a file that was meant to stay local is a human step. The research does not say how often it was deliberate.

What to do

  1. Rotate first. Find every secret that any version of the file has held and change it before cleaning up. Removing the file does not remove it from git history, forks or copies.
  2. Search your organisation. Look for .claude/settings.local.json and .claude/settings.json in every repository, including history, and in forks. Include the folders other agents create, such as .cursor/, .gemini/ and .specstory/, and any saved agent transcripts.
  3. Stop tracking and ignore. Remove the local file from the index and add it to the repository's own .gitignore, and to your organisation's template, so it does not depend on one person's git settings.
  4. Check the file on your own machine, even if it was never committed. Delete every rule that contains a secret. Copies can also end up in an npm package, a Docker image, a zip archive or a synced folder.
  5. Keep secrets out of commands. Refer to them by variable name from a secrets manager instead of typing the value, so the saved rule holds the name and not the secret. Putting the password in an inline assignment still puts it in the command text.
  6. Approve patterns, not single commands, and read what the prompt will save before choosing “don't ask again”.
  7. Scan for what scanners miss. Add pre-commit and CI scanning that covers history and includes passwords inside commands, not only known key formats, and treat agent folders like .env files on laptops as well as in repositories.
  8. Prioritise the dangerous ones. Start with credentials paired with a public server address, since those give direct access.

The handover after a rotation

Replacing a database password or an access token means the new value has to reach the people and pipelines that need it. The easy route is to paste it into the same chat, the same ticket, or the same agent session that held the old one. Send each new value once, to the one person who needs it, over a channel that does not keep it. Then put it where it is read at run time, not where it is typed into a command.

Where Secretus fits, and where it does not

Secretus covers that handover: a person encrypts a short text secret in the browser and shares a link that stops working after the expiry they set or the first successful open. Team Split can require several holders to reconstruct a high-value text secret.

It is not a code-scanning, git or secrets-management product. It cannot search your repositories, clean git history, change a coding agent's settings or revoke a database password. Use your scanner and secrets manager for that, and a one-time link for the moment one person gives another a credential.

Sources