How to Lock Down Claude Code Secrets in Git

Night desk with a turned-away laptop, keyboard, notebook, and unreadable whiteboard diagrams under a warm lamp.

This incident-response checklist shows developers how to lock down Claude Code secrets saved when someone picks “Yes, and don’t ask again.” That choice can store the approved shell command, word for word, in .claude/settings.local.json, including any password or token typed into it. The Hacker News, citing Apiiro, reports those files are already on public GitHub, and removing the current copy does not undo older versions in git history or forks.

Updated November 7, 2026

Key Takeaways

  • Rotate every password, token, and key before deleting the file.
  • Search git history for both Claude settings files, even if deleted.
  • Untrack settings.local.json and add it to the repo .gitignore.
  • Approve command patterns, not exact commands that contain secrets.

What should you check first?

The researchers’ advice is to rotate first. They did not test whether the secrets still work, but one company they notified confirmed its key had been live. iTWire notes that GitHub recommends revoking or rotating before cleanup, because deleting the current file does not remove earlier commits, forks, or other clones.

  1. Search your GitHub organization for .claude/settings.local.json and .claude/settings.json, and check git history even where the files are gone.
  2. Rotate every password, token, and key those files have ever held, then clean up.
  3. Open the local file on your own computer, even if nobody committed it, and delete every rule that contains a secret.
  4. Hunt copies that never reach GitHub: the file is plain JSON and can sit in an npm package, a Docker image, a zip archive, or a synced folder.
  5. Check credentials paired with a public server first, because those are the ones that give access.

Where do Claude Code secrets get saved?

By default, Claude Code asks before most shell commands. Choosing “Yes, and don’t ask again” writes an allow rule to .claude/settings.local.json, Claude Code’s settings documentation says. A pattern such as npm test * does not embed a secret; an exact command does, in plain text. Apiiro reproduced that with Opus 5.5 and Fable 5.1.

The first write in a git repository adds **/.claude/settings.local.json to that user’s global git excludes, so git on that computer ignores the file in every repository. The Hacker News, from the docs, says that protection stays in one user’s git settings and is never added to the project .gitignore, so it does not travel with the project. It does nothing for a file that was already committed, the researchers say. If you created the file by hand and Claude Code has not written to it yet, add it to .gitignore yourself.

File Who it affects How it meets git
~/.claude/settings.json Every project on your machine Stays on that machine
.claude/settings.json Teammates and cloud only if committed Shared project settings
.claude/settings.local.json Your copy of that project Global excludes, unless tracked

In a git repository, Claude Code reads and writes the local file at the repo root, and a worktree uses the main checkout’s root. The file stays with .claude/settings.json instead when you are outside a git repository, when the root is your home directory, on Windows, or when you do not own the root, .git, or .claude. Also check a pre-v2.1.211 copy left in the starting directory.

How do you stop tracking the local file?

Ignore rules do not affect files already under version control. Stop tracking with git rm –cached .claude/settings.local.json, then add the path to the repository’s own .gitignore. While the file stays untracked, its allow rules apply without the workspace trust step. If git tracks it, that trust step applies too.

In 539 of 1,105 repositories Apiiro traced, a commit listing Claude as a co-author changed the file. Review those commits, but a co-author line is not proof Claude introduced every secret. A deleted file is not an all-clear: history and forks can still hold the secret. Shared .claude/settings.json is committed on purpose, and secrets in public copies mostly sit inside allow rules, so review that file too.

What should security leads change next?

Keep secrets out of commands. Use a variable from a secrets manager, such as $DB_URL, so the saved rule stores the name. An inline assignment that still contains the password remains command text. Approve a pattern such as Bash(npm run:*) instead of one exact command.

Treat .claude/, .cursor/, .gemini/, and .specstory/, plus agent memory files, like .env files, on laptops and in repositories. Add them to pre-commit and CI scanning, including git history, and make sure the scanner catches passwords inside commands, not only known key formats. Add .claude/settings.local.json to the organization’s .gitignore templates.

Apiiro ran gitleaks and TruffleHog without the tools’ verification step. Of 1,122 files with a secret, gitleaks flagged 564 and TruffleHog 643, and neither flagged 215. Most misses are passwords after PGPASSWORD=, sshpass -p, or mysql -p.

Do not wait on a product fix: a report filed August 11, 2025 was closed as “not planned” on January 3, 2026, after 60 days without activity. The researchers say none of the four related reports they cite got a reply from Anthropic, The Hacker News reports. The same rotate-first order is why an unrevoked LiteLLM supply-chain key matters, and agent folders belong in the same review as reports of a Claude Code backdoor that may have reached Cursor users.

Frequently asked questions

Does deleting settings.local.json remove a leaked secret?

No. Older versions stay in git history and in forks, so rotate every password, token, and key the file has ever held before you clean up.

Why doesn’t Claude Code’s git exclude stop the leak?

The first write adds the file to one user’s global git excludes, not the project .gitignore. That does not travel with the repo, and the researchers say it does nothing if the file was already committed.

Do secret scanners catch passwords inside approved commands?

Often not. Of 1,122 files with a secret, gitleaks flagged 564 and TruffleHog 643, and neither flagged 215, mostly passwords typed inside commands.

What should you approve instead of an exact command?

Approve a pattern such as Bash(npm run:*) and refer to secrets as variables, such as $DB_URL, so the saved rule holds the name and not the secret.

Notice an error?

Help us improve our content by reporting any issues you find.