Breakdown: Claude Code's "don't ask again" file left 1,379 secrets in public GitHub repos
By Pritesh Ghodge, security engineer · Published 14 November 2026
Did a secret make it all the way into your live app?
The Abbi Labs quick check tests your live, public site as an anonymous visitor: secret-looking keys in your JavaScript, exposed .env and .git files, Supabase tables readable with your public key. It does not search GitHub or read your repos, so do the repo checks below yourself. No sign-up.
No sign-up. Read-only public-resource and protocol metadata checks. No model prompts or tool execution. Scan only sites you own or are allowed to test.
Run on every deploy or use from Cursor / Claude Code via MCP →
Weekly AI-app security checklist
One short email a week: a practical check for apps built with Supabase, Next.js and AI tools (RLS, leaked keys, headers and more). Unsubscribe anytime.
If you use Claude Code, you've seen the prompt. It wants to run a shell command and offers "Yes", "No", or "Yes, and don't ask again". Picking the last one is what most of us do after the tenth prompt in an hour. Security company Apiiro has now shown where that choice can end up. When the approved command had a password or token typed into it, Claude Code can save the whole command, secret included, in .claude/settings.local.json inside the project. And a lot of those files are sitting in public GitHub repos.
Everything below comes from The Hacker News write-up of Apiiro's research (7 November 2026) and Ars Technica's coverage (9 November 2026). I couldn't load Apiiro's own post when writing this, so the numbers are as THN reported them.
What happened
- The click. By default Claude Code asks before running most shell commands. "Yes, and don't ask again" saves an allow rule in
.claude/settings.local.jsonin the project, so matching commands run without asking next time. - The secret goes with it. Sometimes the saved rule is a pattern like
npm test *. Sometimes it's the exact command. If that command was something likePGPASSWORD=... psqlorsshpass -p ..., the password is now in a plain JSON file. - The gitignore gap. The first time Claude Code writes the file in a git repo, it adds it to your global git excludes on that one computer. It never adds it to the project's own
.gitignore. Clone the repo on another machine, or turn a folder into a repo later, and nothing stops the file being committed (Ars Technica). - Claude often commits it. In 539 of the 1,105 repos Apiiro traced, a commit listing Claude as co-author changed the file (THN).
- It's been reported before. A Claude Code bug report from 11 August 2025 described approved commands with keys and tokens being stored word for word. It and the related reports were closed by a bot after 60 days without activity (THN, Ars Technica).
The numbers
All from The Hacker News, citing Apiiro's research:
- 104,185 public copies of
.claude/settings.local.jsonin 103,617 GitHub repos. - 1,122 of them (about 1.1%) hold at least one secret, 1,379 different secrets in total.
- More than a third open a database directly, including 379 database passwords. Also 43 SSH logins for public servers, 42 GitHub, GitLab and npm tokens and 23 AWS keys.
- 63 organisations own some of these files, mostly software companies.
- Every file with a secret was still on its default branch when checked. In half of those repos it had been there at least 217 days.
- Deleted isn't gone: older versions hold 734 more secrets across 509 repos, and 211 forks of 74 repos carry the same secrets.
- Counting the shared
.claude/settings.json, git history and saved agent chat logs, the total is 2,539 secrets across 1,994 repos. - Secret scanners miss a lot of these. Of the 1,122 files, gitleaks flagged 564, TruffleHog 643, and neither flagged 215. Passwords inside a command line look like ordinary words.
What's confirmed and what we don't know
- Not tested. Apiiro did not test whether the secrets still work, and doesn't say whether anyone has used them. One company it notified confirmed its key had been live (THN).
- Anthropic's side. Boris Cherny of Anthropic's Claude Code team said in a Hacker News thread the team is "looking into what we can do to prevent this", suggested auto mode and secret scanners, and said built-in secret scanning is being considered. When someone pointed out that auto mode can still save sensitive commands, he called it a "good catch" (Ars Technica).
- Why only Claude Code. Of 16 coding agents whose docs Apiiro compared, Claude Code is the only one confirmed to save the full approved command in a project file by default (THN). Other agents' folders can still hold secrets, so treat
.cursor/,.gemini/and the like the same way.
How to check your own repos
Only check repos and machines you own or are responsible for.
- Search your GitHub org. In GitHub code search, try
org:YOUR_ORG path:.claude/settings.local.json, then the same for.claude/settings.json. - Check history in every repo, even where the file is gone.
git log --all --oneline -- .claude/settings.local.json .claude/settings.json git log --all -p -- .claude/settings.local.json | grep -nEi "password|passwd|token|secret|key|-p |PGPASSWORD|sshpass" - Open the file on your own laptop, committed or not. It's plain JSON in the project folder and can end up in an npm package, a Docker image, a zip or a synced folder.
- Check forks. If a public repo had the file, look at its forks. Deleting your copy doesn't touch theirs.
Check the other end too
A leaked repo is one way out. A secret shipped in your live site is another. Paste your URL and Abbi Labs checks what a signed-out stranger can see on your public site: secret-looking keys in your JavaScript, exposed .env and .git, open Supabase tables. Read-only. It doesn't look at GitHub.
Fix steps
- Rotate first. Change every password, token and key the file has ever held, in any version, before you clean anything up. Once it's been public, assume someone has it. If it was a Supabase service_role key, follow the service_role key exposed guide.
- Stop tracking it and ignore it in the project.
git rm --cached .claude/settings.local.json echo ".claude/settings.local.json" >> .gitignore git commit -m "stop tracking Claude Code local settings" - Purge history, after rotating. Deleting the file in a new commit leaves every old version readable. Use
git filter-repo --path .claude/settings.local.json --invert-paths(or BFG), force-push, and tell collaborators to re-clone. Forks and caches may still have it, which is why rotation comes first. More in secret keys in git history. - Clean the local file. Delete every allow rule that contains a secret, even if the file never left your laptop.
- Keep secrets out of commands. Use a variable from your secrets manager, like
$DB_URL, so the saved rule holds the name and not the value. Approve patterns such asBash(npm run:*)instead of one-off commands. - Scan agent folders like .env files. Add
.claude/,.cursor/and similar folders to pre-commit and CI secret scanning, including history, and make sure the scanner catches passwords inside commands, not just known key formats. Add.claude/settings.local.jsonto your org's .gitignore templates.
Same family of mistake, different file: API keys in mcp.json covers keeping secrets out of Cursor MCP config. And if a .env or .git folder got deployed with your site, see .env and .git folder exposure.
My take
Nobody did anything reckless here. People clicked the button that makes the prompts stop, and a safety net that only lives on one laptop didn't follow the project. The bit that worries me most is the 215 files neither scanner caught. If your plan was "the scanner will flag it", a password typed after -p slips straight past. Spend ten minutes on the history search above, and rotate anything you find before you touch git.
Sources
- The Hacker News, Claude Code's "Don't Ask Again" File Exposes Passwords and Keys in 1,122 Public Copies on GitHub, 7 November 2026 (source of all figures)
- Ars Technica, Claude Code is accidentally exposing secrets all over GitHub, 9 November 2026
- Apiiro, research write-up (primary; the page returned an error when I tried to load it on 14 November)