Latest in AI
Claude Code settings.local.json: How to Check for Committed Secrets
A local permission file can become a repository problem, and adding it to gitignore only fixes part of the exposure.
If you are worried that Claude Code's .claude/settings.local.json contains a password or API key, check whether Git tracks it before you push anything else. If a credential has already been shared, revoke or rotate it first. Deleting the file does not make that credential safe again.
The useful question is whether a sensitive value moved from a command into a saved configuration, then into a commit. Each step needs a different check. A clean working directory, an ignore rule and an uncompromised credential are three separate things, and treating them as interchangeable is how an incomplete cleanup looks finished.
What Claude Code saves in settings.local.json
Anthropic's settings documentation says that choosing “Yes, and don't ask again” for a Bash command saves an allow rule in the project-local settings file. That makes the file worth reviewing whenever approved commands involved credentials. A remembered permission should describe what may run without becoming a place to store the password needed to run it.
The current documentation also says Claude Code adds an exclusion for this file to the global Git ignore configuration when it first writes it in a repository that does not already ignore it. Manually created files need their own ignore rule. Existing checkouts deserve inspection rather than assumptions about which behavior originally created them.
Keep .claude/settings.json separate in your thinking. That is the shared project configuration, which teams can intentionally commit. Blanket-ignoring the entire .claude directory can hide useful team settings without addressing anything already committed.
Check tracking without printing file contents
Run these commands yourself from the repository root, in a private terminal. They report paths and ignore metadata rather than displaying configuration values:
git ls-files -- .claude/settings.local.json
git check-ignore -v --no-index -- .claude/settings.local.json
If the first command prints the path, the file is in Git's index. It might be newly staged or already committed; either way, an ignore rule alone will not protect it. No output means this exact path is not currently tracked, not that every past copy is clean.
The second command explains which ignore rule matches. The --no-index option deliberately checks the rules even when the path is tracked. Read its pattern carefully: a matching pattern beginning with ! is a negation, not protection. Git documents that distinction.
For example, a tracked file and a matching global exclusion can appear together. That result is entirely possible because ignore rules do not remove tracked files. This is the case where “but it is in gitignore” is a particularly misleading answer.
Repeat the tracking check for any older or nested copies you know about. The root-path command does not search every directory, linked worktree, submodule or renamed file.
Review the content privately, then check history
Open the local file in a trusted local editor and inspect its saved rules and other values. Look for literal credentials, connection strings and authorization headers. Do not paste the file into a chat, public issue or online validator to ask whether it contains secrets. That can create another disclosure while you are investigating the first.
Check whether this path exists in the history available in your clone:
git log --all --format='%h %ad' --date=short -- .claude/settings.local.json
This prints commit identifiers and dates, not patches or commit messages. Results establish that the path appears in the history being examined. They do not establish that a secret was present, that a commit reached a public remote, or that someone used a credential.
A shallow clone or incomplete set of local refs limits the result. So do path changes. For a serious incident, have the repository owner review the relevant remote branches, historical filenames and existing secret-scanning findings through the team's approved tools. Avoid putting the suspected secret itself into a search command or shell history.
Revoke exposed credentials before tidying Git
When a real credential has reached a shared repository, prioritize invalidating it with its issuer. Replace it in the systems that need access and confirm the old credential no longer works through the provider's approved process. Review relevant access logs and alert the service owner if the credential protected production resources.
GitHub's cleanup guidance puts revocation or rotation first. A history rewrite can change repository visibility, but it cannot recall copies someone already downloaded. Depending on the secret and your obligations, rotation may resolve the access risk without requiring a rewrite.
This ordering matters operationally. Spending an hour perfecting Git history while a live key remains exposed leaves the most important problem untouched.
Stop tracking the local file without deleting it
After handling any exposed credential, add this pattern to the repository's .gitignore if your team wants the exclusion to travel with the project:
**/.claude/settings.local.json
For the root file, if the earlier tracking check returned a path, remove it from the index while keeping the local copy:
git rm --cached -- .claude/settings.local.json
git add -- .gitignore
git diff --cached --name-status
git ls-files -- .claude/settings.local.json
git check-ignore -v -- .claude/settings.local.json
git rm --cached leaves the working-tree file alone. If it refuses because staged changes conflict, stop and inspect those changes privately rather than adding a force flag. Review the staged filenames so unrelated work does not enter the cleanup commit.
The final tracking check should produce no path, while the ignore check should identify the intended exclusion. Commit the scoped change through your normal review process. The deletion in that commit affects future snapshots; earlier commits still need a separate decision.
Decide whether history cleanup is necessary
If your security team requires removal from history, coordinate it with everyone working on the repository. Rewriting shared history changes commit identities and can disrupt open work. Old clones can also reintroduce the removed material. Follow GitHub's documented process rather than treating a force push as a quick cleanup command.
For prevention, keep real credential values out of commands and permission rules wherever possible. Use the credential handling supported by the service or tool, narrow permissions to the work required, and inspect configuration changes before committing them. Git's ignore mechanism is useful, but it was never a secret-management system.
The strongest outcome is a development workflow where routine approval creates a reusable permission and nothing worth stealing. Once that boundary is clear, checking a local file becomes a small maintenance task rather than an emergency response.
I'm Paras. I work at the intersection of AI, engineering and distribution.
I help technical teams explain developer workflows and security decisions clearly, without turning them into marketing copy.