Short answer: if you use Claude Code and push code to GitHub (or any shared remote), spend five minutes checking whether .claude/settings.local.json is tracked or present in your repository's history — and whether it contains anything secret. On 2026-11-09, Ars Technica reported Apiiro research finding the file uploaded to public repos over 100,000 times, with about 1,100 files from 63 organizations containing secrets such as API tokens, database passwords and private keys. The practical sequence is: check → rotate first → remove and prevent → (only then) consider history rewriting. This guide is a sourced explainer, not a product review: we ran no tests against any vendor product; every claim below points to the report or official documentation.
What actually leaked, and how
| Fact | Detail (as reported / documented) | Source |
|---|---|---|
| The file | .claude/settings.local.json — Claude Code's local settings file, meant for personal preferences not checked into source control | Anthropic docs (checked 2026-11-11) |
| The mechanism | Clicking "Yes, and don't ask again" for a shell command stores an allow rule — and the command itself is often written verbatim into the file, including any credentials embedded in it | Ars Technica, 2026-11-09 |
| Scale | 100,000+ uploads of this file to public GitHub repositories; ~1,100 files from 63 organizations contained secrets (public API tokens, database passwords, private keys, root logins) | Apiiro via Ars Technica |
| Why ignores fail | Claude Code configures the developer's global git ignore (core.excludesFile) for this file. That global ignore does apply to every repository on the same machine — its real weaknesses lie elsewhere: it does not travel with clones (a new machine has no such entry), it never untracks a file already in the index (anything committed before the rule existed stays tracked), and it protects nothing on machines without it; in many reported cases Claude Code itself committed the file | Ars Technica + Anthropic docs + git-scm.com/gitignore (checked 2026-11-12) |
| Forks keep it | After removal from the original repo, secrets can persist in forks | Ars Technica |
| Flagged long ago | A Claude Code bug report about this dates to August 2025; related reports closed without action after 60 days of inactivity | Ars Technica |
| Vendor response | Anthropic's Boris Cherny (Hacker News thread): the team is "looking into what we can do to prevent this"; users should essentially never check these files in; he recommends the auto mode and secret scanners, and said secret scanning may be built into Claude Code in the future | Ars Technica |
| Scanner gap | 215 of the ~1,100 public secrets were not flagged by two popular scanners (gitleaks, TruffleHog) | Apiiro via Ars Technica |
Bash(mysql -u admin -pSecret123 ...) keeps the password forever; and the auto-configured protection is a global ignore — it covers every repo on that one machine, but it silently does nothing on clones made from other machines, and it never untracks a file that is already tracked. As of our same-day check (2026-11-11) no shipped Claude Code fix or built-in secret scanning was announced — Cherny also acknowledged auto mode can still save sensitive commands to the file.Five-minute self-check (read-only; safe to run anywhere)
- Is the file tracked right now?. In the repo root run
git ls-files .claude/. Ifsettings.local.jsonappears in the output, it is in version control — what that means for you depends on what is inside it and who can reach the remote: go through step 3 (contents) and the decision table below before acting. Being tracked is not, by itself, proof that a real credential leaked. - Was it ever committed?. Run
git log --all --oneline -- .claude/settings.local.json. Any commit listed means the file's contents are in history, even if deleted today. - Look inside for anything sensitive. Open the file and scan the
permissions.allowentries for commands that embed credentials: passwords in URLs (postgres://user:pass@host),-ppasswords, API keys (sk-...,AKIA...), Bearer tokens, upload strings with logins. The allow rules are meant to be command prefixes likeBash(git diff:*)— anything longer with a literal secret in it is the risk the report describes. - Check the shared file too.
.claude/settings.json(without.local) is designed to be committed and shared with your team — it must never contain secrets in the first place. Give it the same grep treatment. - Not a git user? Check the folder anyway. If the folder ever was zipped, shared or copied into another repo, the file travelled with it. Search your organization's GitHub for
settings.local.json(code search) to find copies you forgot.
Handy grep for step 3 (adjust to your stack): grep -nEi "(password|passwd|token|secret|api[_-]?key|bearer |sk-ant-|sk-|AKIA|BEGIN .*PRIVATE KEY|://[^/]+:[^@]+@)" .claude/settings.local.json. If you want to refine the pattern interactively before running it widely, our regex tester runs entirely in your browser — paste a few sample lines, tune the pattern, then grep your real repos. And since the settings file is JSON, fix invalid JSON helps if your edits break it.
Decision table: what to do in each case
| What you found | Do this, in this order | Why this order |
|---|---|---|
| File is tracked right now, contains secrets | 1) Rotate the exposed credentials. 2) git rm --cached .claude/settings.local.json, add .claude/settings.local.json to the repo's .gitignore, commit. 3) Check git log for older copies (next row) | Revocation works retroactively; deleting the file does not — anyone who cloned already has it |
| Not tracked now, but in history | Rotate the credentials. Then decide on history rewriting (e.g. git filter-repo) only if the repo is widely cloned and rotation is impossible for some credentials | History rewrite is coordination-heavy and cannot reach forks or other people's clones — rotation is the only fix that reaches everywhere |
| Forks or copies exist outside your control | Assume exposed: rotate. Removing things from forks is not reliably possible | The report explicitly notes secrets persisting in forks |
| File only ever lived locally, clean of secrets | Add the repo-level .gitignore line anyway (it travels with every clone), and move credentials out of commands into environment variables or a credential helper | A repo-level .gitignore follows the repo everywhere; the global ignore protects only this machine and never untracks an already-committed file — and future you will paste a secret into a command eventually |
Secrets in the shared .claude/settings.json | Rotate, then move those values into environment variables or a credential helper — the shared file is committed by design, and the local settings file is one accidental commit away from the same leak | The docs describe it as the team-shared file; it must stay secret-free |
Preventing the next leak
- Keep allow rules as command prefixes (
Bash(git status:*),Bash(npm test:*)) — never paste a full command that contains a password or a connection string. - Put credentials in environment variables or a credential helper instead of commands — not into another settings file that can itself be committed or shared (the official docs describe
apiKeyHelperandenvsettings for this). - Use the documented
permissions.denylist to keep Claude Code away from.envand secret directories. - Add
.claude/settings.local.jsonto each repo's.gitignore— the repo file travels with every clone, while the global ignore exists only on one machine and never untracks an already-tracked file. - Run a secret scanner as a habit, but read its limits: the report found 215 of ~1,100 public secrets that two popular scanners missed. A clean scan is evidence, not proof.
- Auto mode reduces permission prompts, but per Anthropic's own comments it can still save sensitive commands to the settings file — the file still deserves the checks above.
Status, and what we did not do
As of 2026-11-11 (same-day check of the sources): Anthropic has publicly acknowledged the issue and is "looking into" prevention; no built-in Claude Code secret scanner was announced as shipped. This page contains no product testing by YYSI — we ran no accounts, no repos and no scans of any vendor product; the check steps above are ordinary git commands you run against your own repository. We deliberately do not guess about region availability, product versions or enterprise plans. If Anthropic ships a change after 2026-11-11, verify against their release notes — the checks in this guide remain useful either way, because they audit your repository, not the tool.
Sources and context: the original YYSI brief (with the Chinese version), the Ars Technica report it is based on, and Anthropic's settings documentation.
Sources & verification
- Ars Technica: Claude Code is accidentally exposing secrets all over GitHub (2026-11-09) — original media report — Sources checked 2026-11-11
- Anthropic official documentation: Claude Code settings files (settings.local.json behavior, git ignore, permissions.deny) — Sources checked 2026-11-11
- Official Git gitignore documentation — core.excludesFile applies to repositories on the same machine; patterns from the global file do not travel with clones and never untrack already-tracked files (DESCRIPTION, core.excludesFile, NOTES); basis for the 2026-11-12 ignore-mechanics correction — Sources checked 2026-11-12
- YYSI brief covering this event (2026-11-09, both languages) — Sources checked 2026-11-11
Sources checked All event facts below were re-verified against the original Ars Technica report and Anthropic's official settings documentation on 2026-11-11 (same day as publication). YYSI performed NO product or account testing for this guide: there are no 'we tested' claims, and every check/remediation step is derived from the sourced facts and official documentation. Quote counts, organization counts and scanner-miss figures are attributed to the report; product behavior statements are attributed to Anthropic's documentation or its staff's public comments as reported. Correction of 2026-11-12: the first version described the global git ignore as "not applying at repo level", which conflated two separate Git behaviors — per the official gitignore documentation, the global ignore (core.excludesFile) does apply to every repository on the same machine; what it does not do is travel with clones to other machines, and it never untracks files already in the index. The ignore rows, decision table and prevention list were rewritten to separate those behaviors, and being tracked is no longer phrased as automatic proof of a real leaked credential. Whether a fix has shipped since 2026-11-11 should be checked against Anthropic's release notes before acting on the status section.
Read our editorial standards or send corrections to [email protected].