How to Hunt Claude Code Secrets in Settings Files

Dim network closet with a folder tucked behind a drawer of patch cables

This guide shows security and platform teams how to hunt Claude Code secrets in settings files, git history, and forks, then rotate them before cleanup. Selecting “Yes, and don’t ask again” can save an approved shell command word for word, secret included, in .claude/settings.local.json. Deleting the file does not clear history or forks, a user’s global git excludes stay on one computer, and ordinary scanners miss passwords typed into commands.

Updated November 8, 2026

Key Takeaways

  • “Yes, and don’t ask again” can save the full command, secret included.
  • Rotate every password, token, and key before deleting or untracking the file.
  • Global git excludes stay on one computer and miss files already committed.
  • Without verification, neither scanner flagged 215 of 1,122 secret-bearing files.

Where do Claude Code secrets hide?

Claude Code writes .claude/settings.local.json the first time a developer chooses “Yes, and don’t ask again” for a Bash command, Claude Code’s settings documentation says. In a git repository the file sits at the repository root and applies to sessions started in subdirectories; a worktree uses the main checkout.

It does not use that root outside a git repository, on Windows, when the root is the home directory, or when the user does not own the root, .git, or .claude. A build before v2.1.211 left the file in the starting directory, and Claude Code still reads that copy.

The allow rule stores only what the prompt offered. A pattern such as npm test * has no secret; an exact command keeps one in plain text. The Hacker News, citing Apiiro, also found secrets in shared .claude/settings.json, mostly in allow rules, and in saved agent chat logs. The file is plain JSON and can sit in an npm package, a Docker image, a zip archive, or a synced folder.

How do you search history and forks?

Search the GitHub organization for both filenames, and check git history even where the files are gone. Older versions remain in history and in forks, so a clean working tree is not proof the secret is gone.

Place to check What Apiiro found
Current local-file copies 1,122 of 104,185 copies held at least one secret
Older versions, usually after deletion 734 more secrets across 509 repositories
Forks 211 forks of 74 repositories carried the same secrets
Shared .claude/settings.json 298 of 76,011 copies held secrets, mostly in allow rules

As of Monday, The Hacker News reported, every file with a secret was still on the default branch, and in half of those repositories it had been there for at least 217 days. In 539 of 1,105 repositories traced, a commit listing Claude as a co-author changed the file.

What should you rotate first?

Rotate first, then clean up. Apiiro did not test whether any still work; one company the researchers notified confirmed its key had been live. Check credentials paired with a public server first, because those are the ones that give access.

  1. Search the organization for .claude/settings.local.json and .claude/settings.json, including git history and forks, even if the files are gone.
  2. On each machine, open the local file even if it was never committed, including a pre-v2.1.211 copy in the starting directory.
  3. Check npm packages, Docker images, zip archives, and synced folders for the same JSON.
  4. Rotate every password, token, and key those files have ever held, starting with credentials paired with a public server.
  5. Then run git rm –cached .claude/settings.local.json, add the path to the repository .gitignore, and delete every local rule that contains a secret.

How do you stop approvals from storing secrets?

The first time Claude Code writes the file in a git repository that does not already ignore it, it adds **/.claude/settings.local.json to that user’s global git excludes. The exclude does nothing for a file already committed, and Claude Code never adds the path to the project’s own .gitignore. If the file was created by hand, add it to .gitignore yourself, and add .claude/settings.local.json to organization .gitignore templates.

Keep secrets out of commands. Refer to a secrets-manager variable, such as $DB_URL, so the saved rule holds the name. Approve a pattern such as Bash(npm run:*) instead of one exact command. Permission rules are enforced by Claude Code, not the model, so CLAUDE.md text does not change what is allowed.

Treat .claude/, .cursor/, .gemini/, .specstory/, and 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.

Without the tools’ verification step, gitleaks flagged 564 of 1,122 secret-bearing files and TruffleHog flagged 643; neither flagged 215. Most misses are passwords inside commands, such as after PGPASSWORD=, sshpass -p, or mysql -p. Also review other agent risk, including Anthropic exploit chains for browsers and operating systems.

Frequently asked questions

Where does Claude Code save a don’t-ask-again approval?

In .claude/settings.local.json at the git repository root; a worktree uses the main checkout’s file. Outside a git repository, on Windows, when the root is the home directory, or in the ownership cases the docs list, Claude Code does not use that root.

Does deleting the settings file remove the secret?

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

Why do secret scanners miss many of these files?

Many values are passwords inside commands, for example after PGPASSWORD=, sshpass -p, or mysql -p, and do not match known key formats.

What should security teams scan besides the local settings file?

Scan .claude/settings.json, git history, and forks, and treat .claude/, .cursor/, .gemini/, .specstory/, and agent memory files like .env files on laptops and in repositories.

Notice an error?

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