DevLazar
Note
079
Series
The Wire · Tooling
Date
Nov 14, 2026
Read
7 min · 1,320 words
Rev
1
Drawn by
L. Stanković · Niš
Lab notes / The Wire

'Don't Ask Again' Remembers Your Password: Claude Code Approvals Are Leaking Secrets to GitHub

Apiiro found 1,379 secrets in public copies of Claude Code's local settings file, written there by the 'don't ask again' button. How it happens, who counted, what Anthropic has said, and how to clean up.

Lazar StankovićEngineer, DevLazar · Niš, Serbia

Claude Code's most convenient button has a long memory. On November 6, Apiiro published research showing that "Yes, and don't ask again" can save a full shell command, password included, to .claude/settings.local.json, and that the file keeps reaching public GitHub: 1,379 distinct secrets in 1,122 current copies, and 2,539 across 1,994 repositories counting history, the shared settings file and chat logs, per The Hacker News. No exploit, just a permission record doing its job in a file few scanners read.

The button that writes things down

Claude Code's settings documentation says that button saves the approval as an allow rule in .claude/settings.local.json. A rule can be a pattern or one exact command, and an exact command is stored verbatim, so a password typed after PGPASSWORD=, sshpass -p or mysql -p lands there in plain text; Apiiro reproduced it with Opus 5.5 and Fable 5.1 (The Hacker News). The problem, with an invented credential, and Apiiro's fix, where the command names a variable instead:

Listing 1Diff
1// .claude/settings.local.json (credential is fictional)
2 {
3   "permissions": {
4     "allow": [
5-      "Bash(PGPASSWORD=example-only psql -h db.example.com -U app -c \"select 1\")"
6+      "Bash(psql \"$DATABASE_URL\" -c \"select 1\")"
7     ]
8   }
9 }

The file is meant to stay local: on first write in a repository that does not already ignore it, Claude Code adds **/.claude/settings.local.json to your global git excludes; create it by hand and .gitignore is your job (Claude Code docs). That guard lives on one laptop. It does not travel to a teammate's clone, a CI runner, a Docker COPY or an npm tarball (CSA; CSO Online).

The shared .claude/settings.json is a second route. It is meant to be committed, the docs suggest it for "the environment variables the project needs", and the VS Code approval card can save a rule straight into it (Claude Code docs). Apiiro found secrets in 298 of 76,011 public copies of it, mostly in allow rules (The Hacker News).

How big, and who counted

Apiiro found 104,185 public copies of the local file in 103,617 repositories, counting a secret when a value matched a known key format or was a password beside a public server address, and an AI reviewer agreed (The Hacker News). About 1.1% of copies held one. Another 734 secrets survive only in history across 509 repositories, and 211 forks carry the same ones. Owners include 63 organizations; in half the affected repositories the file had sat on the default branch for at least 217 days (CSA).

The current copies held 379 database passwords, 43 SSH logins, 42 GitHub, GitLab and npm tokens, and 23 AWS keys. Apiiro says more than a third of secrets open a database; 379 is about 27% of 1,379 by our arithmetic, a gap CSA also flags.

The scanner result matters most. Run without verification, gitleaks flagged 564 of the 1,122 leaking files, TruffleHog 643, and 215 slipped past both, mostly inline passwords with no recognisable prefix (The Hacker News).

Column chart: of 1,122 leaking files, gitleaks flagged 564, TruffleHog 643, and 215 were missed by both
Chart: Leaking Claude Code local settings files, by scanner result. Source: The Hacker News; CSA.

One more figure: in 539 of 1,105 repositories traced, a commit listing Claude as co-author changed the file (The Hacker News). CSA notes this does not prove the agent introduced the credentials.

What Anthropic has said

Very little on the record. Anthropic did not respond to Apiiro, and four related issue reports were closed by a bot without reply, the latest on November 6 (The Hacker News). Issue #5544, filed August 11, 2025, was bot-closed as "not planned" on January 3, 2026 (CSA). Nor had it answered CSO Online by November 11.

The only acknowledgement is second-hand: GitGuardian reported that Claude Code lead Boris Cherny said Anthropic was exploring safeguards, including built-in secret scanning (CSO Online). We found no release note or documentation change that redacts stored rules. GitGuardian's telemetry adds a twist: monthly leaks in this file peaked in April and fell to 959 by October, and researcher Guillaume Valadon told CSO "we do not yet know what changed."

Of 16 coding agents whose documentation Apiiro compared, only Claude Code is confirmed to save the full approved command in a project file by default (The Hacker News). That is a docs comparison, not a scan; CSA still says to treat .cursor/, .gemini/ and .specstory/ as secret-bearing (CSA).

Cleanup, in the right order

Rotate first. A credential that sat on a public branch for months is presumed copied, and as this site's November 12 post on the wfx campaign showed, harvested secrets are spent fast. Rotation ends the exposure; the rest is hygiene (CSA).

Then make the ignore rule travel: untrack the file, add it to the project's .gitignore, and confirm.

Listing 2Bash
1git rm --cached .claude/settings.local.json
2printf '%s\n' '**/.claude/settings.local.json' >> .gitignore
3git check-ignore -v .claude/settings.local.json
4git add .gitignore
5git commit -m "Stop tracking Claude Code local settings"

Untracking does not touch history. List every commit on any branch that touched either file, then scan all history with gitleaks, whose --log-opts passes options to git log -p (gitleaks README):

Listing 3Bash
1git log --all --oneline --name-only -- '*.claude/settings.local.json' '*.claude/settings.json'
2gitleaks detect --source . --log-opts="--all" -v

Since stock rules miss inline passwords, extend them. This .gitleaks.toml keeps the defaults and adds one rule with the README's documented fields; tune the regex:

Listing 4TOML
1[extend]
2useDefault = true
3
4[[rules]]
5id = "inline-cli-password"
6description = "Password passed inline to psql, sshpass or mysql"
7regex = '''(?:PGPASSWORD=|sshpass -p ?|mysql [^"\n]*?-p)([^\s"']{4,})'''
8secretGroup = 1
9keywords = ["pgpassword", "sshpass", "mysql"]

Then add the README's hook to .pre-commit-config.yaml:

Listing 5YAML
1repos:
2  - repo: https://github.com/zricethezav/gitleaks
3    rev: v8.16.0 # the README's example tag; pin the current release
4    hooks:
5      - id: gitleaks

On GitHub, enable push protection under Settings, Advanced Security, Secret Protection (GitHub Docs). Generic-pattern detection is documented separately, so do not expect push protection alone to catch a bare PGPASSWORD. Finally, keep secrets out of command lines, avoid broad allow patterns on curl, ssh or database clients, and add agent directories to .dockerignore and .npmignore (CSA).

What we could not verify

  • Apiiro's own page. We could not open it; its figures come from The Hacker News and CSA, which agree; a different original changes the counts.
  • Whether the secrets work. Apiiro did not test them; one notified company confirmed a live key; dead keys would shrink the real risk.
  • Anthropic's position. The Cherny remarks reach us through GitGuardian via CSO, undated. A fix shipped after November 11 would not be reflected here.
  • GitGuardian's trend and the 16-agent comparison. We saw neither method nor per-agent results; if rivals store full commands too, the problem is industry-wide.
  • gitleaks syntax. The README revision we checked shows v8.16.0 and detect; newer releases may differ, so check gitleaks help.

The 30,000-foot read

Every safety control eventually becomes a record, and every record eventually becomes a target. The permission prompt keeps a human in the loop; "don't ask again" turns that human's judgment into a line of JSON, and the line remembers more than the judgment did. It is the oldest leak in the trade, a password in a config file, arriving through a door few scanners watch.

You control rotation, project-level ignore rules, scanners that read command syntax, and never typing a secret where an agent can save it. You do not control how vendors store approvals, so ask them. Watch for three things: whether Anthropic ships redaction or a project-level ignore, whether GitGuardian learns why its curve fell, and whether .cursor/ and .gemini/ get the same audit .claude/ just received.

Sources: Apiiro research write-up (original research, published November 6; we could not open it directly); The Hacker News (Apiiro method and counts, scanner comparison, mechanism, model reproduction, 16-agent comparison, Anthropic non-response, bot-closed reports, Claude co-authored commits); Cloud Security Alliance research note (independent restatement of Apiiro figures and dates, secret types, 217-day persistence, issues #5544 and December 2025 duplicate, global-excludes limitation, database-share discrepancy, cleanup steps and agent directories); CSO Online (no Anthropic comment, Cherny acknowledgement via GitGuardian, GitGuardian monthly trend and Valadon quote, Docker COPY risk); Claude Code docs: Settings files and precedence (file scopes, global git excludes behaviour, shared env use, VS Code destination picker, rule syntax); gitleaks README (detect, --log-opts, .gitleaks.toml fields, pre-commit hook); GitHub Docs: Enabling push protection (settings path). CAVEAT: all study figures are Apiiro's, a commercial security vendor, single-sourced and not independently replicated; CSA restates rather than replicates them. The 27% share is our arithmetic. The Ars Technica report assigned as the lead could not be opened and is not cited; the account here rests on Apiiro as reported by The Hacker News and CSA. Anthropic's only reported acknowledgement is second-hand and undated. The gitleaks syntax follows the README revision linked; the git commands are standard porcelain; none were run against a live repository. The diff example uses a fictional credential; no victim repository or real secret is named.

Lazar Stanković
Engineer and writer, running a one-man shop in Niš, Serbia. I build systems that survive their launch and write down what the work teaches.
Related notes
Note 074 · The Wire · 7 min
The Commit That Wasn't There: Inside the wfx Raid on GitHub Actions Secrets
Since November 10, hijacked GitHub accounts have pushed a CI secret stealer to default branches and reverted it within seconds. How it hid, where the counts disagree, and what to check today.
Note 055 · The Wire · 9 min
How Deslopping works: one AI-written pull request, from risk score to merge
A step-by-step walk through Deslopping: how a pull request is scored, how its questions are written and tested, what happens after a wrong answer, and what a team learns about its AI without ever seeing a person.
Note 040 · The Wire · 9 min
Octoverse 2026: Agents Start Over 40% of Pull Requests, and Review Becomes the Bottleneck
GitHub's Octoverse 2026 says agents started over 40% of September's pull requests; Universe answered with 4M new cores and metered Copilot. Output now tracks agents, not headcount, and review is the scarce part.
← Note 078 · Jensen Huang Resigns, and Nvidia's CFO Inherits the Company Five Days Before EarningsNote 080 · October Runs Hot, and Markets Price a December Fed Hike →
The Wire · Weekly · Free
Notes like this one, every week.

AI infrastructure, shipping on a deadline, and the craft of building things that last. No noise.