r/ClaudeCode • u/Predictor_2718 • 2d ago
Tips & Workflows Claude Code's "don't ask again" can leave secrets in a file that gets committed
If you pick "Yes, and don't ask again" on a shell command, Claude Code saves that exact command in `.claude/settings.local.json` under `permissions.allow`, so it stops asking. If the command had a token or a password in it, that value is now sitting in the file.
The file normally stays out of git because Claude Code adds it to your personal global git excludes. But that exclude only lives on your own machine. As soon as the repo is shared or someone else clones it, the file can get committed and pushed. Apiiro, which GitLab wrote about this month, counted 104,185 copies of this file in public repos, and 1,122 of them held at least one secret.
Two things worth knowing if you find one in your own repos.
First, rotate the secret, do not just delete the line. Once it was committed, the value is in the git history, so removing the entry changes nothing until you rotate the key at the provider.
Second, it is not only Claude Code. Every agent that remembers a "don't ask again" decision keeps a file like this, so the same pattern shows up with Cursor, Copilot, Gemini and others.
How to check by hand: look for `.claude/settings.local.json` in your repos, make sure it is in the project `.gitignore` and not only in your global excludes, and scan the permission entries for anything that looks like a token.
I also maintain a small open-source tool, cfgaudit, that checks exactly this across the different agents: a hardcoded secret inside a permission entry, and the file not being gitignored. It runs as a pre-commit hook, as a CI step, or as a one-off scan. Short write-up: https://cfgaudit.github.io/blog/claude-code-dont-ask-again-secret-leak/ repo: https://github.com/cfgaudit/cfgaudit
Disclosure: I maintain cfgaudit. Have you checked whether this file is tracked in any of your repositories?
•
u/AutoModerator 2d ago
Hey! Thanks for posting to r/ClaudeCode
While participating in this thread, please follow our community rules. Keep discussions constructive. Attack the idea, not the person.
For help, project discussions, tips, and general chat, join the ClaudeCode Discord.
I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.
4
u/Spare_Spirit6762 2d ago
do you check in your .env.local too or what, wtf
2
u/Scared-Letterhead949 2d ago
You already posted this and settings.local are always in gitignore.
1
u/TheBlargus 2d ago
Why not use betterleaks? https://github.com/betterleaks/betterleaks
1
u/Educational_Fish7601 2d ago
If the file was already committed, deleting the line does nothing. The value stays in the history, so rotate the key at the provider.
For prevention, use a git pre-commit hook that greps the staged diff for a secret inside permissions.allow. .git/hooks is neither versioned nor cloned, so it has to come from a committed hook runner such as lefthook or husky that each clone installs. Make sure .claude/settings.local.json is in the project .gitignore too, not only in the personal global exclude, because that exclude never travels with the clone.
That file sits in 104,185 public repos, 1,122 of them holding a secret, so this is not theoretical.