Vancouver
Meridan ReportVancouver: AI research, film tech, Pacific Rim capital

Advertisement · Why this ad?

Technology

Claude Code's "Don't Ask Again" exposes passwords in 1,122 public GitHub files

Marcus Chen
Managing Editor · Saturday, November 7, 2026 at 8:45 PM · 6 min read
Claude Code's "Don't Ask Again" exposes passwords in 1,122 public GitHub files — Vancouver Technology news

Apiiro research found 2,539 real secrets in 1,994 public GitHub repositories: database passwords, cloud keys, API tokens, SSH root logins. Among them: a database vendor's own admin-level cloud key, a production Azure Postgres password, a Square production token, and the owner password of a medical-records database. 63 organizations, mostly software companies of all sizes, are affected. One confirmed its key had been live. Ask Claude Code to check a database or call an API, and the command it proposes carries the secret from your config file. It asks before running it. Pick "Yes, and don't ask again" and it saves that exact command, secret included, to .claude/settings.local.json inside the project folder. Nothing in the repo marks that file as private, so it gets committed with the rest of the code. Out of 104,185 public copies of this file on GitHub, 1,122 hold a real secret. We found 1,160 more in git history, in the shared settings.json teams commit on purpose, and in agent chat transcripts saved in repos. GitHub is just where we could count. The same file sits in plain text on every laptop where someone clicked "don't ask again." Malware already collects credentials from developer machines in bulk. The Shai-Hulud npm worm ran TruffleHog over victims' files; that same scanner flags 643 of the 1,122 files we found. And one in five of those files is flagged by neither gitleaks nor TruffleHog, usually because the secret is a password typed inside a command, not a key in a recognizable format. Check if you’re affected Is it public? Search your GitHub organization for .claude/settings.local.json and .claude/settings.json. Each hit is a file anyone can read right now. Was it ever committed? Check each repo’s git history for the file, even if it’s gone today. If history has it, so does every fork and clone. What's in it? Find every copy of the file on your machine and read its allow list. Each entry is a command you approved, with whatever you typed into it: look for passwords, tokens, keys and connection strings. Found something: rotate first, clean up second. How a secret ends up in a settings file Developer machines hold secrets: a database connection string in a config file, cloud keys in local installations, an API token in .env. Ask Claude Code to check why login fails on staging or to run a migration, and the command it proposes carries that secret, because it can’t work without it. Claude Code asks before it runs a shell command, multiple times a session. Pick "Yes, and don't ask again" and it runs the command and adds a permission rule to .claude/settings.local.json in the project folder, so it won't ask again. The rule is the command string itself: This is Claude Code's own behavior, not the model's: it happens with Anthropic's latest models too, and we reproduced it with Opus 5.5 and Fable 5.1. The file is meant to stay on the developer’s machine, and Claude Code tries to keep it there. When it creates the file inside a git repo, it adds it to the developer's global git ignore list. That covers the common case. It doesn’t cover a folder that becomes a repo later, a clone on another machine, or a file someone already committed. The rule never goes into the repo's own .gitignore, so nothing travels with the project to protect it. Often Claude commits the file itself. In 539 of the 1,105 repos with a real secret that we traced, a commit co-authored by Claude changed the file. Those commits name every recent model, from Sonnet 4.5 to Opus 5.5. Who is exposed 63 organizations hold a real secret in a public allowlist. The strongest cases, all in .claude/settings.local.json and each checked at a pinned commit: Organization What’s exposed Database vendor Its own cloud API key with manage access and no expiry claim, plus the cluster host B2B startup Production Azure Postgres password Software agency Square production access token Open-source project (over 1,000 stars) OpenAI-format API key Open-source project npm token IT services firm (medical-records app) Owner password for the app’s cloud Postgres database Payments startup Postgres password for the postgres role Organization Database vendor What’s exposed Its own cloud API key with manage access and no expiry claim, plus the cluster host Organization B2B startup What’s exposed Production Azure Postgres password Organization Software agency What’s exposed Square production access token Organization Open-source project (over 1,000 stars) What’s exposed OpenAI-format API key Organization Open-source project What’s exposed npm token Organization IT services firm (medical-records app) What’s exposed Owner password for the app’s cloud Postgres database Organization Payments startup What’s exposed Postgres password for the postgres role Most are companies: startups, software agencies, IT services firms. A few are established vendors, exposed through their own demo and workshop repos. Nobody meant to publish a key. The key was in a command, the command was approved, and the file was committed with everything else. The allowlists also hold server logins: 43 SSH credentials for public servers, some of them a root password in an sshpass command. One university repo, for example, permanently approved a root SSH command to a public server. How many Public GitHub holds 104,185 copies of .claude/settings.local.json, in 103,617 repositories. 1,122 files (1.1%) hold a real secret: a key in a known provider format, or a password or token next to a public host. Together they hold 1,379 distinct secrets: 636 provider keys and 743 passwords or tokens for public hosts. More than a third open a database directly: 379 database passwords and 122 Supabase service-role keys. Another 103 are Supabase account tokens, which control every project in the account. The rest are mostly API tokens for third-party services and AI model keys, plus 43 SSH logins, 42 GitHub, GitLab and npm tokens, 23 AWS keys and 6 private keys. Large allowlists drive the rate. One in ten files over 8 KB holds a real secret, against fewer than one in 500 under 500 bytes. The longer a developer has been clicking “don’t ask again”, the more the file holds. The files are still there: every one sat on its repo’s default branch on November 2, 2026, and most have sat there a long time. In the median repo with a real secret, the file was first committed 217 days before that. In 118 repos, more than a year before. Forks copy them: 211 forks of 74 repos carry the same secrets. Deleting the file doesn’t solve it. Earlier versions of the file hold 734 real secrets, in 509 repos, that appear in no current copy, usually because the file was deleted. Counting the file's history, the shared settings file and agent transcripts (next sections), the total comes to 2,539 distinct real secrets in 1,994 repos. What secret scanners miss Generic secret scanners miss many of these. We ran gitleaks and TruffleHog over all 104,185 files. Of the 1,122 files with a real secret, gitleaks flagged 564 and TruffleHog 643; 215 were flagged by neither. The gap is passwords inside commands. Scanners look for key formats: a provider prefix, a long random string. A password typed after PGPASSWORD= , sshpass -p or mysql -p , or a bearer header in a curl call, is an ordinary word in an ordinary command line, and both tools mostly let it through. This matters beyond this file. The same password-in-a-command pattern appears wherever an agent records what it ran: transcripts, memory files, handoff notes, and a scanner tuned to key formats misses it in all of them. Not just one file The allowlist is the clearest case, but agents write secrets into other files developers commit. File Checked With a real secret Shared .claude/settings.json All 76,011 298 files Agent chat transcripts (.specstory, aider, Cursor exports) 2,523 120 files in 87 repos Agent memory files (MEMORY.md and similar)

Up nextI Use Development-Driven Specs, Not Spec-Driven DevelopmentTechnology · 4 min read
You're offline — showing the last loaded page