Claude Code "Don't Ask Again" Saved My Password to settings.local.json: Find It and Fix It#
Published by Alex Sorokoletov
"Yes, and don't ask again" saves the approved command as a permission rule in .claude/settings.local.json. If the command held a password or token, the rule holds it too. Run git ls-files '*settings.local.json'; if it lists a file, rotate the secret, untrack the file, and add .claude/settings.local.json to the repository's .gitignore.
Why the password ends up in a committed file#
A Bash permission prompt offers Yes, and don't ask again for <command> commands in <project>. That choice writes a Bash(...) permission rule to .claude/settings.local.json in the project. The rule records the command text it covers. When that text includes a password, a token or a connection string with credentials, the rule includes it.
Claude Code keeps the file out of git by adding **/.claude/settings.local.json to your global git excludes file (core.excludesFile, by default ~/.config/git/ignore). It does not add a line to the repository's .gitignore. The rule has no effect in three cases:
| Case | Result |
|---|---|
| The file was already tracked by git | Excludes do not apply to tracked files. Each new rule is committed with the next git add. |
| Another machine, CI job or container without the same global rule | The file shows as untracked, and git add . commits it. |
| The file was created by hand, or by the Write or Edit tool | No excludes rule is written at all. |
On November 7, 2026, Apiiro reported 1,122 such files in public GitHub repositories, across 1,105 repositories. In 539 of them, a commit co-authored by Claude changed the file. A Claude Code team member replied that settings.local.json is meant to stay local and that the team is looking at ways to prevent this.
Check your repositories#
In one repository, see whether git tracks the file and whether it was ever committed:
git ls-files '*settings.local.json'
git log --all --oneline -- '.claude/settings.local.json'
Look for secrets in the rules you saved:
jq -r '.permissions.allow[]?' .claude/settings.local.json \
| grep -iE 'pass|secret|token|key|bearer|authorization|://[^/ ]+:[^@ ]+@'
Across a GitHub organization, search the code index (it covers the default branch only, not history):
gh search code --owner <your-org> --filename settings.local.json
Also check .claude/settings.json. It is meant to be committed, so a rule saved there is shared by design.
Fix a leaked file#
- Rotate the secret first. Removing the file does not remove it from git history, forks or clones.
- Stop tracking the file and ignore it in the repository:
git rm --cached .claude/settings.local.json
printf '\n.claude/settings.local.json\n' >> .gitignore
git commit -m "chore: stop tracking Claude Code local settings"
- Delete the rule with the secret from your local copy, or replace it with a rule that has no secret in it.
- To remove the secret from history as well, rewrite it with
git filter-repoand force-push. Rotation still comes first, because copies already exist.
Stop it from happening again#
- Add
.claude/settings.local.jsonto every repository's.gitignore. The repository rule works on every machine and in CI; the global rule works on one machine only. - Keep secrets out of commands. Put them in environment variables or a
.envfile the command reads, so the approved rule holds$PGPASSWORD, not the value. - Answer "Yes" without "don't ask again" for any command that shows a secret. "Yes" approves one run and saves nothing.
- Scan before commit and push. A
gitleaksorgit-secretspre-commit hook, plus GitHub push protection, catch a rule with a known token format. - Deny reads of secret files so Claude does not copy them into commands:
{
"permissions": {
"deny": ["Read(./.env)", "Read(./.env.*)", "Read(./secrets/**)"]
}
}
Timeline#
| Date | Event |
|---|---|
| 2026-11-07 | Apiiro publishes the scan: 1,122 settings.local.json files with secrets in public repositories. |
| 2026-11-07 | The Hacker News thread reaches 596 points. A Claude Code team member says the file is meant to stay local and that the team is looking at prevention. |
| 2026-11-06 (v2.1.319) | Current release: "don't ask again" still saves the command to .claude/settings.local.json, and the excludes rule is still global only. |
Should you stop using "don't ask again"?#
No. For commands with no secret in them, such as npm test or git status, a saved rule removes prompts at no risk. The risk comes from one combination: a secret in the command text plus a tracked file. Remove either one and the rule is safe. The repository .gitignore line removes the second for everyone on the project.
FAQ#
Q: Does "don't ask again" in Claude Code save my password?
A: It saves the approved command as a permission rule in .claude/settings.local.json. If the password was part of the command text, the rule contains it.
Q: Isn't settings.local.json gitignored automatically?
A: Only through your global git excludes file, on the machine where Claude Code wrote the file. It is not added to the repository's .gitignore, and the rule does nothing for a file git already tracks.
Q: How do I check whether I committed it?
A: Run git ls-files '*settings.local.json' and git log --all -- .claude/settings.local.json in each repository. Any output means the file is, or was, in git.
Q: I removed the file. Am I safe?
A: No. The secret stays in git history and in every clone and fork. Rotate it first, then untrack the file and add it to .gitignore.
Q: How do I approve a command with a secret without saving it?
A: Choose "Yes", not "Yes, and don't ask again". Better, pass the secret through an environment variable so the command text never holds it.
Sources: Apiiro: coding agents leaking secrets through "Don't Ask Again" | Hacker News discussion | Claude Code settings documentation | Claude Code changelog
Related: Why Claude Code put your email in a User-Agent header | Claude Code SELF_SIGNED_CERT_IN_CHAIN and CA certificates | Claude Code productivity tips: settings and permissions | Claude Code env-var glossary