← Back to Blog

guide

By ReclaimLLM Team

Claude Code settings.local.json: find and fix saved secrets

Saved Claude Code approvals can contain inline credentials. Check local settings, prevent accidental commits, and rotate secrets that were exposed.

Updated November 14, 2026.

A permission rule can become a credential store. If a shell command contains a password, saving that command as a standing approval can preserve the password alongside it. When the settings file then reaches a shared repository, the secret reaches everyone who can read that repository.

This is a specific Claude Code security issue worth checking across a team: inspect saved approvals, establish where copies went, and fix the repository rules that allowed them to travel.

How an approval becomes a saved secret

In November 2026, Apiiro reported finding secrets in public copies of .claude/settings.local.json. Its researchers described a path from approving an exact shell command with “Yes, and don't ask again” to saving that command, including an inline credential, as a permission rule. Their search found 1,122 public copies containing secrets. These are Apiiro's findings, rather than a ReclaimLLM scan. Apiiro did not test whether the credentials were still valid. Read the primary research, or the summaries by The Hacker News and GitLab.

For illustration, a command containing PGPASSWORD=EXAMPLE_ONLY can carry a password directly in its text. If that literal text is persisted, the settings file now holds the value too. EXAMPLE_ONLY is a dummy value here.

The exposure has two stages: writing a secret to a local file, then sharing that file. A local copy alone does not establish that a credential was published or used by someone else. Determine where it went before describing the incident.

What Claude Code already does

Anthropic documents .claude/settings.local.json as personal project settings, including standing permission approvals. When Claude Code first writes it in a Git repository that does not already ignore it, it adds an ignore pattern to the developer's global excludes file. That protection belongs to the machine. Shared project settings live separately in .claude/settings.json. Claude Code settings documentation.

For a team, put the intended exclusion in the repository as well. Git's documentation makes the crucial distinction: ignore rules affect untracked files; adding a rule does not stop tracking a file already in the index. Git ignore documentation.

Check the repository without spreading the values

Inspect local settings in a trusted local editor. Look at permissions.allow for database URLs, authorization headers, passwords and tokens inside commands. Review the shared .claude/settings.json too: being intentionally committed does not make its contents safe.

From the repository root, these checks show whether the local file is tracked and whether it appears in the history available in your clone:

git ls-files -- .claude/settings.local.json
git log --all --oneline -- .claude/settings.local.json

These commands list paths and commits rather than printing file contents. They do not inspect missing remote branches, deleted repositories or other developers' clones. Check nested project directories and older file locations where relevant.

Record the affected repository, credential owner and exposure window in the incident ticket. Keep the credential itself out of tickets, chat, screenshots and shared session exports.

Rotate exposed credentials, then clean up

If a secret was pushed or otherwise disclosed, revoke or rotate it at its issuing service first. Confirm dependent applications use the replacement, then review access logs under your normal incident process. GitHub's remediation guidance puts revocation or rotation before repository cleanup; it also explains that rewriting history may be unnecessary after invalidation and can disrupt collaborators. GitHub sensitive-data removal guidance.

For a value that stayed on an appropriately protected laptop, assess exposure using your organization's credential-handling policy. Finding plaintext is a reason to investigate, not proof of public compromise.

Remove secret-bearing rules. Add this pattern to the repository's .gitignore so nested project copies are covered:

**/.claude/settings.local.json

If the root file is already tracked, remove it from the index while preserving the developer's local copy:

git rm --cached -- .claude/settings.local.json

Review and commit the ignore rule and index change through your normal process. This prevents future ordinary additions; it does not erase earlier commits or copies already shared. Coordinate any required history cleanup separately.

Prevent the next saved credential

Review the proposed permission scope before saving it. Avoid approving literal credentials, and avoid replacing the problem with a broad permission that grants unrelated commands access.

Prefer an approved credential helper or secrets-manager workflow that keeps the value out of the agent's proposed command text. A variable reference such as $DATABASE_URL can help only if it remains a reference in the saved rule. Shell expansion, debug tracing and command output can still reveal its value. Inspect the resulting file using dummy credentials before adopting the workflow across the team.

Add local settings files to repository checks and secret-scanning coverage. Test the scanner with synthetic password-in-command examples, rather than assuming every credential resembles a recognizable API key. Review agent transcripts separately using the transcript secret-store guide.

The useful outcome is a repeatable check: local approvals stay local, shared settings receive review, and exposed credentials have an owner and a recorded rotation. The broader Claude Code security guide covers the surrounding managed settings, hooks and sandbox controls.

Review your team's Claude Code security controls.