Apiiro: Claude Code saved passwords to a permissions file, and copies are public on GitHub
Claude Code’s ‘Yes, and don’t ask again’ option can save an approved command, password included, to a file in the project folder, the security company Apiiro said. If the file has ever been pushed to GitHub, Apiiro advises rotating the secrets before cleaning up.
The security company Apiiro published its research on 5 November.
Anthropic’s coding agent Claude Code asks for permission before most command-line commands. When the user selects ‘Yes, and don’t ask again’, Claude Code saves an allow rule to the file .claude/settings.local.json in the project folder and stops asking about that command. Sometimes the rule is a pattern, sometimes a single exact command. An exact command is saved together with any password or token typed into it, in plain text. Apiiro said the fault lies in Claude Code rather than the model: the company reproduced the behaviour with Opus 5.5 and Fable 5.1.
When Claude Code creates the file in a git repository, it adds the file to the user’s global git ignore list, but that setting applies only on that machine. It does not protect a project cloned to another machine, a folder later turned into a repository or a file that has already been committed. Claude Code does not add the rule to the project’s own .gitignore.
Apiiro traced 1,105 repositories containing a real secret, and in 539 of them the file was changed by a commit that listed Claude as a co-author. Apiiro concludes from this that Claude often committed the file itself. Agentbeam’s blog, however, says the co-author listing shows only that Claude took part in the commit.
More than a thousand public files
From 1 to 3 November, Apiiro examined 104,185 public copies of the file on GitHub. By the company’s classification, 1,122 of them, or 1.1 per cent, held a real secret, 1,379 distinct secrets in all. More than a third of these give direct access to a database. Counting older versions of the file, the .claude/settings.json file that teams share on purpose and saved agent transcripts, the total comes to 2,539 secrets in 1,994 repositories.
For Apiiro, a real secret is a value matching a known key format, or a password next to the address of a public server, not a credential confirmed to work. A language-model judge checked the values in addition to the rules. Apiiro did not test the credentials, but one company it notified confirmed that its key had been valid. An analysis by P.K. Sharma points out that Apiiro sells secrets-protection products and that no one else has reproduced the count.
Neither of the secret scanners, gitleaks or TruffleHog, flagged 215 of the files that contained secrets. Apiiro said the reason is that a password typed into a command does not look like a known key format.
Rotate first, then clean up
Apiiro advises searching your GitHub organisation for the files .claude/settings.local.json and .claude/settings.json, and checking each repository’s git history even where the file no longer exists. Enzo Soler’s site gives the command git log --all -- .claude/settings.local.json for checking the history. In any files you find, it is worth reading the allow rules and looking for passwords, tokens and connection strings.
Apiiro advises rotating the secrets first and cleaning up only afterwards. Deleting the file is not enough, because older versions remain in git history, forks and clones. The history held 734 secrets that no longer appeared in any current copy. If git tracks the file, remove it from version control with git rm --cached .claude/settings.local.json and add the path to the project’s own .gitignore.
It is also worth removing rules that contain a secret from the copy left on your machine, because malware has harvested credentials from developers’ machines. Apiiro advises referring to secrets through variables fetched from a secrets manager, such as $DB_URL, so that the rule holds only the variable name, and approving patterns rather than individual commands.
Read more: How an agent works · Agent map