NEWS 7 min read

Claude Code Left Secrets in 1,122 GitHub Files—Check This Setting

Apiiro traced exposed credentials to Claude Code permission files. The awkward part: approving a command can preserve the password inside your project.

By EgoistAI ·
Claude Code Left Secrets in 1,122 GitHub Files—Check This Setting

The approval outlived the command

Apiiro reports that 1,122 public GitHub copies of Claude Code’s .claude/settings.local.json contained credentials. Its November 5 research, updated November 8, describes an uncomfortable route from terminal convenience to public exposure: approve a command containing a secret with “Yes, and don’t ask again,” and the saved permission can retain that secret. Commit the file, and the permission becomes public. Apiiro’s report is the source of the finding.

That number needs a boundary. It counts files containing credentials under Apiiro’s classification, not confirmed account compromises. The researchers say they did not test credentials or contact the associated hosts. A credential-shaped string in a public repository is evidence of exposure; it does not establish that an attacker used it or that it still works.

For builders, the immediate question is concrete: what did your coding agent save after you approved that database check? A successful command can leave behind an unsuccessful security decision. The terminal finishes. The project file stays.

A permission file is also stored data

Anthropic’s permission documentation distinguishes between temporary and persistent approvals. For Bash commands, the “don’t ask again” choice persists per repository and command. For file modifications, the equivalent approval lasts until the session ends. Those are different lifetimes behind a similar interaction.

The useful mental model is a saved instruction with an argument attached. If the argument contains a password, preserving the instruction can preserve the password. Reviewing whether a command should execute therefore answers only part of the question. You also need to know which representation of that command will be written to disk.

Consider a hypothetical staging check whose shell command includes a database password directly. The developer may intend to authorize one connection or stop repeated prompts during debugging. Neither intention implies consent to publish the credential. Yet a later commit review can miss the stored value because it appears under permissions rather than in an obvious credentials file.

Our assessment: this is a storage problem as much as an approval problem. A stronger model does not automatically change what the surrounding application records. Teams evaluating coding agents should inspect their artifacts alongside their execution controls. A permission dialog deserves scrutiny, but so does the JSON it leaves behind.

“Local” describes scope, not a guarantee

Anthropic’s settings documentation gives the two project files different jobs. .claude/settings.json carries shared project settings that teams can commit. .claude/settings.local.json contains personal overrides for one project. The documentation says Claude Code keeps the local file out of Git when it creates it; a manually created file needs an ignore entry supplied by the user.

That distinction matters during review. A blanket instruction to commit every agent configuration file can sweep personal settings into a shared repository. A blanket instruction to delete the whole .claude directory can discard deliberate team configuration. Inspect the particular file and its contents before deciding what belongs in version control.

Git also has a sharp edge here. Its gitignore manual says ignore rules apply to intentionally untracked files. Files already tracked are unaffected. Adding an ignore entry after a file has entered the index does not make subsequent changes disappear from commits.

The operational implication is simple: verify repository state instead of trusting the filename. “Local” is a product convention, not an access-control boundary. A reviewer should be able to answer whether Git tracks the file, whether history contains it, and whether its permission entries carry sensitive values. None of those questions is answered by the word local.

Anthropic is discussing prevention, not declaring victory

In the Hacker News discussion, Boris Cherny, identifying himself as being from the Claude Code team, said the product historically had not scrubbed secrets. He said the team was looking at prevention, with possible approaches including basic secret scanning and changes involving auto mode. He also recommended secret scanning and keeping the local settings file out of source control.

There is a disagreement worth preserving. Cherny attributed the exposed files to manual creation and check-in, pointing to automatic Git ignoring. Apiiro describes additional failure paths and argues that the protection does not reliably travel with a project. Neither account justifies assuming that a particular checkout is safe without inspecting it.

As of this November 9 article, those comments should be read as a response and discussion of possible mitigations. They are not evidence that a shipped change has removed the exposure route. A team should not close an incident because a vendor has acknowledged it or suggested a different approval mode.

Separate two decisions in your own review: how the agent receives permission to act, and how credentials enter its commands and saved files. Changing the first may improve workflow. It does not demonstrate that previously recorded secrets have been revoked, removed, or prevented from returning.

Check the repository before changing the workflow

A useful first pass is to inspect the local settings file privately and determine whether Git tracks it. git ls-files -- .claude/settings.local.json checks the current index; git log --all -- .claude/settings.local.json helps locate commits affecting that path in the history available locally. Neither command proves that every remote branch, fork, or older copy has been covered.

Review the permission entries without copying their contents into a public issue or shared chat. The review question is whether a rule contains a credential value, connection string, or authenticated request that should never have become project data. Keep any findings in an appropriately restricted incident record. A cleanup ticket should not become the next place the password lives.

For a local override file that should remain private, add the exact path to the repository’s .gitignore. If it is already tracked, removing it from the index with git rm --cached .claude/settings.local.json preserves the working copy while preparing its removal from future commits. Review that staged change before committing. This addresses future tracking, not historical exposure.

Then inspect the shared settings separately. A file can be appropriate to commit while containing an inappropriate value. The goal is to preserve useful team configuration while excluding credentials, rather than making the entire agent directory somebody else’s problem.

For future sensitive operations, prefer a workflow that obtains credentials at execution time without placing their literal values in the approved command. Check what the agent actually sees and records: a variable name is only helpful if the surrounding workflow does not expand and save its value elsewhere. Trial changes with a harmless placeholder, then inspect the resulting settings diff.

Rotation comes before repository cosmetics

GitHub’s sensitive-data removal guidance puts revocation or rotation first when a password, token, or other credential has leaked. Removing visible text does not disable the credential. History cleanup is a separate decision, with coordination costs and effects on collaborators.

For this incident pattern, a practical response is to identify the credential’s owner, revoke or replace it through its issuing service, and update legitimate consumers. Confirm that the old credential no longer grants access through your normal administrative process. Record the exposure window and examine available access logs according to the credential’s privileges and the systems it could reach.

Treat history rewriting as planned repository maintenance. GitHub warns that it changes commit hashes and that old clones can reintroduce removed material. Deleting the current file is easier than coordinating every copy, which is precisely why making the exposed credential useless takes priority.

The builder lesson is to give saved permissions an owner. Include changes to agent settings in commit review, ask what data those settings retain, and verify that your scanning covers the artifacts your team actually produces. Approval fatigue is understandable; turning its residue into a public credential archive is avoidable. The next review should inspect what the assistant remembered, as well as what it executed.

Frequently asked questions

Were 1,122 accounts confirmed compromised?

No. Apiiro reported credential-containing public files and said it did not test the credentials. Exposure does not establish account compromise.

Will adding the file to .gitignore fix an existing leak?

No. Ignore rules do not affect tracked files or erase history. Revoke or rotate exposed credentials, then address tracking and cleanup.

Has Anthropic announced a completed fix?

The cited response discusses possible prevention measures. It does not establish that a completed fix has shipped.

Share this article

> Want more like this?

Get the best AI insights delivered weekly.

By subscribing, you agree to our Privacy Policy. You can unsubscribe at any time.

> Related Articles