DEV Community

Cover image for Claude Code's 'Don't Ask Again' Saved Secrets in 1,122 Public Files. 215 Beat Both Scanners
Gabriel Anhaia
Gabriel Anhaia

Posted on Edited on AI-assisted

Claude Code's 'Don't Ask Again' Saved Secrets in 1,122 Public Files. 215 Beat Both Scanners


You ask Claude Code to check a row in the staging database. It proposes a psql command with the password right there after PGPASSWORD=. You pick "Yes, and don't ask again" so it stops asking, and you move on.

That approval doesn't disappear. Claude Code saves it as an allow rule in .claude/settings.local.json, and an August 2025 bug report says commands with credentials are "stored as is with plain text credentials" in that file. Security firm Apiiro went looking for those files on public GitHub. As The Hacker News reported on November 7, it checked 104,185 copies in 103,617 public repositories and found 1,122 copies holding at least one secret, 1,379 distinct secrets in all. Two common secret scanners didn't catch all of them. Across the 1,122 files, gitleaks flagged 564 and TruffleHog flagged 643, and the report says neither flagged 215.

What "don't ask again" writes

Claude Code's permissions docs say a Bash approval saved with "Yes, and don't ask again" lasts "permanently per repository and command". The rule goes into .claude/settings.local.json at the root of the git repository, and it applies to future sessions anywhere in that repo, worktrees included.

Sometimes the prompt offers a pattern, like the docs' example npm test *. Sometimes the rule is the exact command, and The Hacker News notes that exact commands are where the secrets end up: a password typed inside the command becomes part of the rule text.

According to the same report, Apiiro's researchers reproduced this with the latest models, Opus 5.5 and Fable 5.1. Of 16 coding agents whose docs they compared, Claude Code is the only one confirmed to save the full approved command in a project file by default.

A large rubber stamp shaped like an approval checkmark pressing a brass key flat into a sheet of paper inside an open project folder
One standing approval, saved as text in a file inside the project.

The ignore rule lives on your laptop, not in the repo

Claude Code does try to keep this file out of git. The settings docs say that the first time it writes the file in a repository that doesn't already ignore it, "it adds **/.claude/settings.local.json to your global git excludes file". That file is core.excludesFile, or ~/.config/git/ignore by default.

That protects one machine. A global excludes file isn't committed, so it doesn't travel with the project to a teammate's clone, a CI runner or a fresh laptop. The docs also say that if you created the file by hand, you have to add it to .gitignore yourself. And no ignore rule untracks a file that is already committed.

Apiiro's data suggests the agent itself is often the one committing. In 539 of the 1,105 repositories it traced, per The Hacker News, a commit listing Claude as co-author changed the file.

The shared file is in the scan too. .claude/settings.json is the one teams commit on purpose, and 298 of its 76,011 public copies held a secret, per the report. The settings docs add that in the VS Code extension, the approval card lets you choose which file a rule goes to, including that shared one; in the CLI, approvals go only to the local file.

What was in the files

More than a third of the secrets open a database directly, including 379 database passwords, The Hacker News reports. Apiiro also counted 43 SSH logins for public servers, 42 GitHub, GitLab and npm tokens, and 23 AWS keys. GBHackers adds 122 Supabase service-role keys.

According to the report, the affected files belong to 63 organizations, "mostly software companies of all sizes". Deleting the current file isn't the end of it. Older versions in git history held 734 more secrets across 509 repositories, and 211 forks of 74 repositories carry the same secrets. Counting shared settings, history and saved agent chat logs, the total is 2,539 secrets across 1,994 repositories, the figure GBHackers leads with.

Apiiro's count has limits. It treated a value as a secret when it matched a known key format, or when a password or token sat next to a public server address and an AI reviewer agreed. The Hacker News says Apiiro "did not test whether any still work". One company it notified confirmed its key had been live.

Most of the 215 misses were passwords typed inside commands, after PGPASSWORD=, sshpass -p or mysql -p, which carry no provider prefix for a pattern to match, per the report. Both scanners also ran without their verification step.

A magnifying glass sweeping across a row of folders, catching brass keys in some while other keys slip through a gap under the lens
Keys with a known prefix get caught. A password inside a command often doesn't.

Check your repos

Start in any repo where you've used Claude Code. These are plain git commands:

# Is the file tracked right now?
git ls-files .claude/settings.local.json

# Was it ever committed, on any branch?
git log --all --oneline -- .claude/settings.local.json

# Which ignore rule covers it here, if any?
git check-ignore -v .claude/settings.local.json
Enter fullscreen mode Exit fullscreen mode

git check-ignore -v prints the ignore file and the matching pattern. If it prints nothing, no rule ignores the path in this clone, or the file is already tracked. Tracked files aren't subject to ignore rules.

Next, run a secret scanner over the full history. It catches the key-shaped secrets, like AWS keys and GitHub or npm tokens:

# gitleaks 8.19+ (older versions: gitleaks detect -v)
gitleaks git -v

# or TruffleHog
trufflehog git file://.
Enter fullscreen mode Exit fullscreen mode

Then grep the history for the password shapes scanners tend to miss:

git log --all -p -- .claude/ \
  | grep -nE 'PGPASSWORD=|sshpass -p|mysql .*-p'
Enter fullscreen mode Exit fullscreen mode

If anything turns up, the order matters. Apiiro's advice, via The Hacker News, is to rotate every password, token and key the files held before cleaning up. A secret that has been public is burned whether or not you rewrite history, and forks keep their own copy.

After rotating, stop tracking the file and ignore it in the repo itself, so the rule travels with the project:

git rm --cached .claude/settings.local.json
echo '.claude/settings.local.json' >> .gitignore
git commit -m "Stop tracking Claude Code local settings"
Enter fullscreen mode Exit fullscreen mode

Run /permissions inside Claude Code to see every rule and the file it comes from (permissions docs), and delete any rule with a secret in it, even in copies you never committed.

Stop writing secrets into approvals

The fix on your side is to keep literal secrets out of the command text. If the command reads PGPASSWORD="$DB_PASSWORD" psql ..., an approval saves the variable name, not the value. Apiiro's recommendation is the same: variables from a secrets manager over literal secrets in commands.

Approve patterns instead of one-off commands where you can. A rule shaped like the docs' example covers the whole family and holds no literal arguments:

{
  "permissions": {
    "allow": ["Bash(npm run test *)"],
    "deny": ["Read(./.env)", "Read(./.env.*)"]
  }
}
Enter fullscreen mode Exit fullscreen mode

The deny rules come from the same settings docs example. They stop Claude's file tools from reading .env files, so the agent is less likely to copy a value out of one into a command.

For teams, Apiiro suggests treating agent folders like .env files: add .claude/settings.local.json to your org's .gitignore templates, and scan .claude/, .cursor/, .gemini/ and .specstory/ in pre-commit and CI, history included.

Don't wait on a product change. The 2025 report was closed by a bot as "not planned" on January 3, 2026, with the message "This issue has been automatically closed due to 60 days of inactivity" (issue #5544). Neither The Hacker News nor GBHackers reports a response from Anthropic.

Did git ls-files turn the file up in any of your repos? Tell me in the comments how many, not what was in them.


If this was useful

I build Hermes IDE, a free, source-available IDE for running Claude Code, Codex and other coding agents on macOS, Windows and Linux. It's on GitHub if you want to look under the hood.

Where a credential lives, who can reach a database directly, and what a leak costs you are design decisions as much as tool settings. The System Design Pocket Guide: Interviews walks through 15 real systems step by step, with the trade-offs that come up in each. It's one of 8 short books in the Pocket Guides for Developers series, covering agents, RAG, prompts, observability, events, databases and system design.

System Design Pocket Guide: Interviews — 15 Real System Designs, Step by Step

Top comments (0)