Yaamlabs
AI security

Claude Code "don't ask again" left secrets on GitHub

Apiiro found 1,122 public Claude Code settings files holding passwords and keys. How approvals end up in git, why counts differ, and how to clean up.

By Yaali. November 9, 2026, 6 min read, AI security, DevOps, Supply chain.

Navy cover with the Yaamlabs logo and the text: Claude Code approvals left secrets on public GitHub, 2,539 distinct secrets in 1,994 repositories

On November 5, researchers Shmulik Cohen and Matan Giladi at Apiiro published a study of a small Claude Code file that ends up in public repositories. When a developer answers a Bash permission prompt with "Yes, and don't ask again", Claude Code saves the exact command as an allow rule in .claude/settings.local.json. If that command had a password or token typed into it, the secret is now stored in plain text inside the project folder. Apiiro found 1,122 public copies of the file that hold at least one real secret.

This affects any team that uses Claude Code in a repository that is public, will become public, or gets copied around as a folder. At least one notified company confirmed its exposed key still worked. Rotating the credential matters more than deleting the file, because forks and git history keep a copy.

Funnel from 104,185 public settings files in 103,617 repositories, to 1,122 files with a secret holding 1,379 distinct values, to 2,539 distinct secrets across 1,994 repositories and 63 organisations once git history, shared settings and transcripts are added, with a breakdown of secret types

How the secret gets into the file

The shared .claude/settings.json is meant to be committed. The local .claude/settings.local.json is meant to stay on one machine, and it is where Claude Code writes every standing approval. Approve mysql -u admin -pS3cret prod_db with "don't ask again" and that whole string becomes a permanent entry under permissions.allow.

Anthropic's documentation says that the first time Claude Code writes this file in a git repository, it adds **/.claude/settings.local.json to the user's global git excludes file (core.excludesFile, or ~/.config/git/ignore by default). That keeps the file out of commits on that machine. It does not add the file to the project's own .gitignore, so the protection does not travel with the repository.

On Hacker News, the submitter from Apiiro first said a fresh clone would commit the file, then accepted that was wrong. The cases that do leak are a new machine or container without the global ignore, a project folder copied rather than cloned, a forced git add -f, and any repository where the file was committed once, since ignore rules never apply to files git already tracks. In 539 of the 1,105 repositories Apiiro traced, a commit with Claude listed as co-author changed the file. Apiiro presents that as an inference; it does not show Claude added each secret.

Why the numbers differ between reports

Headlines quote 1,122, 1,379 and 2,539. They measure different scopes of the same study, run on public GitHub from November 1 to 3:

  • 104,185 public copies of .claude/settings.local.json in 103,617 repositories were examined.
  • 1,122 of those current files (about 1.1%) held at least one secret, adding up to 1,379 distinct values.
  • Widening the search to git history, the shared .claude/settings.json and saved agent chat transcripts gave 2,539 distinct secrets across 1,994 repositories, owned by 63 organisations.

The widened figure includes 734 secrets in 509 repositories that appear only in history, where the current file is already clean, and secrets in 298 of 76,011 public shared settings files. 211 forks of 74 repositories carried the same secrets. In the median repository the file had been committed 217 days before Apiiro looked. The largest groups were 379 database passwords and 122 Supabase service-role keys, together more than a third of the 1,379 values, followed by 43 SSH logins, 42 GitHub, GitLab and npm tokens and 23 AWS keys.

"Real secret" means a value that passed detectors and a manual review. Apiiro did not test whether the credentials work, so these numbers measure exposure. No abuse of the credentials has been reported. Of 16 coding agents Apiiro compared, Claude Code was the only one confirmed to write the full approved command to a project file by default. The team reproduced it with Opus 5.5 and Fable 5.1 and attributes it to Claude Code, not to the model.

Why scanners missed a fifth of them

Gitleaks flagged 564 of the 1,122 files and TruffleHog flagged 643. 215 files were flagged by neither. Both tools find most provider tokens by their prefix, such as ghp_ for GitHub or AKIA for AWS. A database password passed as -pHunter2 or inside a connection string like postgres://app:pw@host/db has no prefix to match, and database passwords were the largest group Apiiro found.

What Anthropic has said

Users reported the behaviour in GitHub issues from August 2025. According to i10x and idlen, those reports were closed automatically as inactive or duplicates without a reply from Anthropic. On November 7, Boris Cherny of the Claude Code team replied in the Hacker News thread that "Historically Claude Code has not done secret scrubbing" and that the team is "looking into what we can do to prevent this". Cherny said the file is meant to stay local and that leaked copies were committed by hand, recommended auto mode and host-side secret scanning, and listed options the team will prototype: making auto mode catch such commands and adding basic secret scanning. When a commenter noted auto mode can still save approvals, he replied "Yeah good catch". No fix has been announced yet.

What to do

Five ordered steps: find every copy with gh, git log and scanners; rotate every credential the file ever held; stop tracking the file and purge history; add it to the project .gitignore; replace literal secrets with environment variables and pattern rules, reviewed in /permissions

Find every copy. For an organisation, gh search code --filename settings.local.json --owner <your-org> lists tracked copies. In each repository, git log --all --oneline -- .claude/settings.local.json .claude/settings.json shows whether the files were ever committed, even if they are gone now.

Scan with more than one tool, then read the rules yourself. Run trufflehog git file://. for history and trufflehog filesystem .claude/ for the working tree. With gitleaks 8.19 or later, use gitleaks git -v and gitleaks dir .claude -v. Because 215 files beat both tools, also print the allow rules and grep them:

jq -r '.permissions.allow[]?' .claude/settings.local.json \
  | grep -Ei 'pass|token|secret|key|-p[^ ]|://[^/@ ]+:[^/@ ]+@'

Rotate first. Treat every password, token and key the file has ever held as exposed, including values only present in old commits. Rewriting history does not reach forks, clones or anything already scraped. Then check provider logs for use of the old credential: AWS CloudTrail for the access key ID, the GitHub audit log for the token, database logs for logins from unfamiliar addresses.

Stop tracking it and purge history. Run git rm --cached .claude/settings.local.json, commit, then rewrite history with git filter-repo --invert-paths --path .claude/settings.local.json and force-push. Ask GitHub support to clear cached views if the repository is public.

Add it to the project. Put .claude/settings.local.json in each repository's .gitignore and in your organisation's repository templates, so the rule holds on every machine and container. A pre-commit hook running gitleaks git --pre-commit --staged catches the next one.

Keep secrets out of commands. Export credentials as environment variables or pull them from a secret manager, and let Claude Code run psql "$DATABASE_URL" rather than a literal connection string. Approve patterns such as Bash(npm run *) instead of one-off literal commands. Open /permissions to see every allow rule and the file it came from, and delete any rule containing a credential.

Coding agents write configuration for the developer, and that configuration can carry secrets. Treat .claude/ and similar agent folders as sensitive paths in secret scanning and code review, and enable push protection on the hosting side.

We review agent setups and leaked-credential exposure in our red team code review and safeguarding and hardening work. To check your repositories, open the chat and Yaali, our AI agent, will pass your question to an engineer.


Sources: Apiiro, iTnews, i10x, RuntimeWire, Idlen, Hacker News discussion, Claude Code settings documentation, ComputingForGeeks.

Read next

Back to the blog, or tell us about your system in the chat. Yaali, our AI agent, answers first and brings in an engineer.