In this guide
- What “Don’t Ask Again” saves—and who needs to check
- Check your settings files, tracked paths and Git history
- Rotate exposed passwords, tokens and API keys first
- Stop tracking local settings and share a repo ignore rule
- Decide whether Git history needs rewriting
- Prevent a repeat with secret scanning and safer approvals
TL;DR: When you choose “Yes, and don’t ask again” on a Claude Code Bash prompt, Claude Code can save an allow rule in .claude/settings.local.json. If that rule is an exact command, any password, token, or API key that was in the command can be stored verbatim. Check whether the file (or shared .claude/settings.json) is in your repositories and Git history; rotate any real secret that reached a public repo or public history first; then untrack the local file, add a portable .gitignore rule, and only then decide whether history needs rewriting. We found no CVE, no GHSA, and no stated general fixed Claude Code version for this permission-file exposure in the sources we read. Switching to auto mode is not a fix for this leak.
What “Don’t Ask Again” saves—and who needs to check
Claude Code asks before it runs most shell commands. Anthropic’s permissions documentation says that if you choose “Yes, and don’t ask again” for a Bash command, the approval is permanent per repository and command, and Claude Code saves the rule to .claude/settings.local.json at the git repository root (in a worktree, at the main checkout’s root). The same docs list exceptions, including Windows, a non-git directory, a repository whose root is your home directory, and some ownership cases, where the file is kept with the session’s .claude/settings.json instead of at the repository root.
This prompt wording is not the same as the dontAsk permission mode. In Anthropic’s table of modes, dontAsk auto-denies calls that would otherwise prompt. Do not treat a dontAsk setting as the “Don’t Ask Again” save path.
Anthropic’s settings documentation distinguishes two project files:
.claude/settings.local.json— project-local. Personal overrides, and the file Claude Code writes when you give a standing Bash approval. Claude Code is meant to keep this file out of git when it creates it..claude/settings.json— the shared team file. Anthropic tells teams to commit it so everyone gets the same permissions, hooks, and plugin settings. Do not blanket-ignore all of.claude/or delete a legitimate shared team file.
A rule with no * matches one exact command; a rule with * is a pattern (Anthropic’s permissions docs). An exact-command rule is not automatically redacted. The original report in GitHub issue #5544 (filed August 11, 2025) says approved commands that contain API keys, tokens, or authorization headers are stored verbatim in permissions.allow. The Hacker News, citing Apiiro, describes the same exact-command path.
A local file’s existence is not evidence of a leak, and a tracked file does not by itself prove it contains credentials. Inspect permissions.allow and any env block privately. Public Git history that still contains a real credential is an exposure even if the latest copy of the file is clean.
Who should check: anyone who has used Claude Code and clicked “Yes, and don’t ask again,” anyone who maintains a public GitHub repository or org that might have committed .claude/settings.local.json or a shared .claude/settings.json, and anyone who started Claude Code in a subdirectory before v2.1.211. Anthropic’s settings docs say that before v2.1.211 the local file was kept in the starting directory; later versions still read a file an earlier version left there, alongside the root file. That version change is a location change. It is not documented as a secret-scrubbing fix. Search nested and renamed copies too.
This is a separate issue from the Claude Code marketplace backdoor in Cursor, versions 2.1.312 and 2.1.313. That story is about a tampered extension. This guide is about secrets saved in permission files.
The Hacker News (THN), in an article dated November 7, 2026, citing research by Apiiro, reports 104,185 local-settings copies in 103,617 public repositories, 1,122 files with at least one secret, and 1,379 distinct secrets in those current copies. THN, still citing Apiiro, also gives a broader total of 2,539 secrets in 1,994 repositories when shared settings, older history, and saved transcripts are included. Those are different populations, not interchangeable counts of breached users. THN says Apiiro did not test whether credentials still worked, that one notified company confirmed a key had been live, and that neither Gitleaks nor TruffleHog flagged 215 of the 1,122 files. That account does not establish confirmed exploitation. We could not read Apiiro’s original write-up: the URL resolved today to a short marketing page without the report text (see Method). Until that primary page can be re-read, treat the figures as THN’s secondary account.
We did not find a CVE or GHSA for this permission-file exposure, and we did not find a changelog entry that states a general Claude Code version now scrubs secrets from saved allow rules. Do not read “fixed in the latest release” or “every release is vulnerable” into that gap.
Related security checks for builders are collected on our security hub.
Check your settings files, tracked paths and Git history
Run these checks only in repositories you own or administer, from the repository root, in a trusted local terminal. Do not paste real keys into search engines, screenshots, issues, AI chats, or shell search patterns. Do not test anyone else’s exposed credentials. If a command prints a secret, keep that output local.
# Filenames only: are these currently tracked?
git ls-files -- .claude/settings.local.json .claude/settings.json
# Includes deleted-file history reachable from refs in this clone:
git log --all --full-history --name-status -- .claude/settings.local.json .claude/settings.json
# Triage current tracked files without printing matched secret lines:
git grep -l -i -E 'PGPASSWORD=|sshpass|Authorization|api[_-]?key|token|password' -- .claude/settings.local.json .claude/settings.json
# Show which ignore source matches, even if the file is tracked:
git check-ignore -v --no-index .claude/settings.local.json
The git grep pattern is a heuristic, not an Apiiro detector and not proof that a file is clean. No match means only that those current tracked paths had no match to that pattern. It skips untracked or ignored local copies and it does not search historical file contents. Open the settings files in a private editor, including permissions.allow and env. Review every relevant historical revision locally with Git’s own history or diff tools. git log --all sees only the refs and history present in this clone. Shallow clones, missing branches, forks, moved or nested paths, and caches need a separate look. A clean log in a partial clone cannot certify that nothing was exposed.
If you started Claude Code in a subdirectory before v2.1.211, repeat the same filename checks for nested .claude/settings.local.json copies, not only the repository root.
Optional organization inventory, if you use an authorized GitHub CLI account (filenames and URLs only; do not run a global harvest of other people’s file contents):
gh search code --owner YOUR_ORG --filename settings.local.json --limit 100 --json path,url
gh search code --owner YOUR_ORG --filename settings.json --limit 100 --json path,url
Then filter the returned paths for .claude/. The query is broader than the Claude path on purpose. Results are capped and use GitHub’s code search; this is not a complete audit and it is not a history search.
Rotate exposed passwords, tokens and API keys first
If a real credential reached a public repository or public Git history, revoke or rotate it with its issuer before you tidy Git. Deleting the file, deleting the repository, or rewriting history does not make a live credential unusable.
There is no single rotation command that covers every issuer. Typical categories in this file are database passwords, cloud and API keys, and repository or package tokens. Create a replacement, update every app or workflow that used the old value, then revoke the old credential. Review the provider’s access or audit logs for use you cannot explain.
GitHub’s guide to removing sensitive data from a repository says that if the sensitive data is a secret, you need to revoke or rotate it as a first step, and that rewriting history may not be warranted once the secret can no longer be used.
For a broader rotation order after other kinds of leak, see these separate incidents: Railway environment-variable exposure and key rotation and the LiteLLM master and provider key leak. Those are different events; they are not a fix for this Claude Code file.
On your own machine, open .claude/settings.local.json and delete permission rules that contain a secret, keeping the file valid JSON. Anthropic’s permissions docs say /permissions can list rules and which settings.json file each one comes from, and that you can remove a rule there.
Stop tracking local settings and share a repo ignore rule
Claude Code’s first write of the local file in an eligible git repository adds **/.claude/settings.local.json to the user’s global git excludes (core.excludesFile if that is set to an absolute or ~-prefixed path; otherwise $XDG_CONFIG_HOME/git/ignore, or ~/.config/git/ignore when XDG_CONFIG_HOME is unset). That ignore stays on that computer. It is not a portable repository .gitignore. Anthropic says that if you created the file by hand and Claude Code has not written to it yet, you need to add it to .gitignore yourself. Git’s own documentation says ignore rules do not untrack a file that is already in the index.
After you have rotated any exposed secret, add this exact entry to the repository’s .gitignore (it also covers nested legacy copies):
**/.claude/settings.local.json
If the root local file is currently tracked:
git rm --cached -- .claude/settings.local.json
git check-ignore -v .claude/settings.local.json
Commit the .gitignore change and the cached removal through your team’s normal review. This stops new commits of the file. It does not erase historical commits. Review shared .claude/settings.json for secrets in permissions.allow or env before you change it; do not remove legitimate team configuration indiscriminately.
Decide whether Git history needs rewriting
Rotation is required for an exposed credential. Rewriting Git history is a separate, disruptive cleanup. It changes commit hashes, can invalidate signatures, and can break pull requests and other clones. Coordinate with teammates and with branch protections first. Do not treat a force-push as a one-line fix, and do not run an automated force-push script from this guide.
If you decide a history rewrite is warranted, follow GitHub’s complete procedure in Removing sensitive data from a repository. GitHub documents a local transformation, on a dedicated fresh cleanup clone, using git-filter-repo 2.47 or later (the version that adds --sensitive-data-removal). For this file, the documented file-removal shape is:
git-filter-repo --sensitive-data-removal --invert-paths --path .claude/settings.local.json
Add every historical, renamed, or nested path as an extra --path. If you need to keep a sanitized shared .claude/settings.json rather than deleting that file wholesale, GitHub documents a --replace-text route instead of invert-paths. Local rewriting is not server cleanup: existing clones, forks, pull-request refs, and cached views can still hold the data. GitHub Support removal has eligibility limits, and GitHub says it will only assist where the risk cannot be mitigated by rotating the credentials.
Prevent a repeat with secret scanning and safer approvals
Public GitHub repositories have automatic free secret scanning. Push protection for users is on by default for pushes to public repositories on GitHub.com. Repository-level push protection is off by default and has to be enabled by someone with the right repository, organization, or enterprise role. These tools catch many known key formats; they do not promise to catch every inline database password. THN, citing Apiiro, reported that common scanners missed passwords typed inside commands.
Push protection for AI-detected secrets is in public preview and is subject to change. GitHub’s push-protection documentation points to GitHub Advanced Security license billing for that feature. This guide does not ask you to buy a paid feature. Use the free scanning that already applies to public repositories, enable repository push protection where you can, add pre-commit or CI scanning, and keep reviewing the files yourself.
Keep real secrets out of the command text you approve. GitHub recommends environment variables or a secret manager rather than a hardcoded value. A variable name in a saved rule is still not a blanket guarantee: the value can be expanded or logged elsewhere. Prefer narrow, secret-free allow rules where you still need them. Do not add Bash(*), a broad interpreter grant, or bypassPermissions as a workaround. Anthropic warns that bypassPermissions skips permission prompts, including for writes to protected paths such as .git and .claude, and says to use that mode only in isolated environments.
On an HN thread about this exposure, bcherny, identifying himself as Boris from the Claude Code team, said Claude Code historically has not done secret scrubbing, that .claude/settings.local.json should not be committed, and that he recommends auto mode and secret scanning. In a follow-up to a comment that auto mode can still present a sensitive-command approval and save an “always allow” rule, he wrote: “Yeah good catch. Thinking through what we can do to improve this.” Do not treat switching to auto mode as a remediation for this leak, or as a guarantee that a secret will not be saved.
A short closing checklist:
- Exposed credentials revoked or rotated, and dependent apps updated
- Local allow rules that contained secrets removed, JSON still valid
- Current tracked copies of the local file untracked, and a portable
**/.claude/settings.local.jsonignore committed - Shared
.claude/settings.jsonreviewed, not blindly deleted - Known history, forks, and stale clones assessed; rewrite only if you still need it after rotation
- Available secret scanning and push protection turned on; no paid feature required for this guide
- Future approvals use secret-free command text
For other Claude product limits, not this security issue, see our Claude and Codex usage limits guide. To verify agent tool outputs before acting, see that hygiene guide.
Sources
- Anthropic, Claude Code settings (including “Yes, and don’t ask again,”
.claude/settings.local.json, global git excludes, and the v2.1.211 location change) - https://code.claude.com/docs/en/settings - Anthropic, Claude Code permissions (permanent Bash approvals, exact vs pattern rules,
/permissions, permission modes includingauto,dontAsk, andbypassPermissions) - https://code.claude.com/docs/en/permissions - GitHub issue #5544, “approved bash commands containing credentials are stored as is…” (opened August 11, 2025; bot-closed January 3, 2026 for inactivity) - https://github.com/anthropics/claude-code/issues/5544
- Claude Code official changelog (raw; latest heading we read was 2.1.322) - https://raw.githubusercontent.com/anthropics/claude-code/main/CHANGELOG.md
- Hacker News thread, including comments by
bcherny- https://news.ycombinator.com/item?id=50407882 - The Hacker News, “Claude Code’s ‘Don’t Ask Again’ File Exposes Passwords and Keys in 1,122 Public Copies on GitHub” (November 7, 2026, Swati Khandelwal) - https://thehackernews.com/2026/11/claude-codes-dont-ask-again-file.html
- Apiiro URL as cited (report text not recovered from the page we received) - https://apiiro.com/blog/coding-agents-leaking-secrets-github-dont-ask-again
- GitHub: Removing sensitive data from a repository - https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/removing-sensitive-data-from-a-repository
- GitHub: About secret scanning - https://docs.github.com/en/code-security/concepts/secret-security/secret-scanning
- GitHub: Push protection - https://docs.github.com/en/code-security/concepts/secret-security/push-protection
- Git documentation: gitignore, git ls-files, git log, git grep, git check-ignore - https://git-scm.com/docs/gitignore
- GitHub CLI:
gh search code- https://cli.github.com/manual/gh_search_code
Last checked: Nov 10, 2026, 1:23 p.m. Manila (UTC+8). Method: We read Anthropic’s settings and permissions pages as Markdown (HTTP 200 from https://code.claude.com/docs/en/settings.md and permissions.md, same paths as the HTML docs). We read GitHub issue #5544 and its comments via the GitHub API (HTTP 200): opened 2025-08-11 by asherfeldmangit; the CLI version field in the report was left blank; github-actions[bot] closed it on 2026-01-03 with a 60-day inactivity housekeeping note (state_reason: not_planned). We fetched the official changelog (https://raw.githubusercontent.com/anthropics/claude-code/main/CHANGELOG.md, HTTP 200, latest heading 2.1.322). The 2.1.211 entry changes “always allow” rules so they save at the repository root; we did not find a changelog statement that saved allow rules are now secret-scrubbed. A later 2.1.307 note about a self-hosted runner committing a leftover .claude/settings.local.json is a different path, not a general scrubbing fix. This is a search of the changelog, not a line-by-line audit of every note. We opened The Hacker News article (HTTP 200, dated November 7, 2026) and the HN thread (item 50407882, HTTP 200), including bcherny’s November 7, 2026 21:13 UTC comment and the 21:30 UTC “Yeah good catch” reply to bluebands. The Apiiro URL returned HTTP 200 today, but the body was a short homepage shell (“Apiiro: Secure your agentic development,” no report title, no counts, no settings.local.json); we therefore attribute exposure counts only to THN, citing Apiiro, and we do not treat Apiiro’s primary write-up as verified this pass. We also read GitHub’s sensitive-data, secret-scanning, and push-protection docs, and the git-scm pages for the commands above. Thumbnail is an original One Signal Desk topic graphic. No affiliate links. How we work.



