Apiiro Finds Secrets in Claude Code Files

apiiro.comSunday, November 8, 2026
Apiiro Finds Secrets in Claude Code Files
  • •Apiiro researchers found 2,539 secrets across 1,994 public GitHub repositories, affecting 63 organizations.
  • •Of 104,185 public Claude Code settings files, 1,122 contained secrets; scanners missed 215.
  • •Claude Code stores approved command text in a project permission file when users select “Yes, and don’t ask again.”

Apiiro researchers Shmulik Cohen and Matan Giladi reported on November 5, 2026, that coding agents can save secrets in project files when developers approve commands. Their scan found 2,539 real secrets across 1,994 public GitHub repositories, affecting 63 organizations. Exposed information included database passwords, cloud keys, API tokens and SSH logins; one company confirmed its key had been live.

Claude Code asks before running a shell command. When a user selects “Yes, and don’t ask again,” it saves the approved command as a permission rule in `.claude/settings.local.json`. If the command contains a secret copied from a configuration file, the secret is stored in that rule. The file is meant to remain on the developer’s machine, and Claude Code adds it to the user’s global Git ignore list when creating it inside a repository. That does not cover every case: a folder may become a repository later, or the file may already have been committed. The repository’s own `.gitignore` does not receive the rule. Apiiro said the behavior is Claude Code’s, rather than the model’s, and reproduced it with Opus 5.5 and Fable 5.1.

Of 104,185 public copies of `.claude/settings.local.json` found on GitHub, 1,122 files contained a real secret. Together, the files held 1,379 distinct secrets: 636 provider keys and 743 passwords or tokens for public hosts. Apiiro also found 734 secrets in earlier file versions across 509 repositories; 211 forks of 74 repositories carried the same secrets. In 539 of 1,105 repositories with a traced secret, a commit co-authored by Claude changed the file.

Apiiro found 63 organizations with a real secret in a public allowlist, including a database vendor’s cloud API key, a production Azure Postgres password, a Square production token and the owner password for a medical-records database. The files also contained 43 SSH credentials for public servers. Across additional agent-related files, researchers found secrets in 298 of 76,011 shared `.claude/settings.json` files, 120 transcript files in 87 repositories, 9 repositories’ memory files and 33 handoff or deploy notes. They also found 9 affected repositories among 173 VS Code Copilot auto-approve settings.

Secret scanners missed many of the credentials. Gitleaks flagged 564 of the 1,122 files containing a real secret, while TruffleHog flagged 643; 215 were flagged by neither. Apiiro attributed the gap largely to passwords written inside ordinary command lines, such as `PGPASSWORD=`, `sshpass -p` or a bearer header, which do not match familiar provider-key formats. The researchers said the same pattern can appear in agent transcripts, memory files and handoff notes.

Apiiro said all the files it counted were on repositories’ default branches on November 2, 2026; in the median repository with a real secret, the file had first been committed 217 days earlier. Researchers reported organization cases to owners on November 2 and 3, 2026. They advised developers to rotate credentials found in these files, since deletion does not remove copies in Git history, forks or clones, and to remove secret-bearing rules from local files. Their recommendations also include using environment variables such as `$DB_URL` instead of typing secrets into commands, approving command patterns rather than literal commands, and scanning agent folders and repository history for passwords embedded in commands.

The research used read-only GitHub code and commit searches from November 1 to 3, 2026. Apiiro downloaded 104,185 local settings files and 76,011 shared settings files; file-history checks covered 43,120 repositories, so the researchers described the history count as a floor. They did not use or test credentials or contact hosts. “Real secret” meant a credential matching a provider format or paired with a public host, not a credential confirmed to work. An independent LLM reviewer assessed 2,774 remaining distinct values in masked context, and the researchers counted 2,539 as real secrets when the review and their rules agreed.