Claude Code stores approved shell commands in a local settings file inside your project directory. If that project is an npm package, there is a good chance that file is shipping to the public registry with your credentials inside it.
We built a scanner to measure how common this is and to examine what ends up in those files. This post covers how the exposure occurs, what we found, and how to prevent it.
This research was inspired by a LinkedIn post from Kirill Efimov, who first spotted -bc-.claude/settings.local.json-bc- files appearing inside published npm packages. We wanted to expand on this to understand the true scale of the issue and raise awareness of it.
How Claude Code's Permission Model Works
Claude Code operates with a permission system for shell commands. When Claude wants to run a command it has not been permitted to run before, it presents you with options, one of which is "allow always". Choosing this writes the exact command string, to .claude/settings.local.json as a permanent allowlist entry. Claude will not ask about that command again.
The file lives in -bc-.claude/-bc- at the root of your project directory. It looks something like this:
Every command you permanently approve gets recorded there, including any credentials that were inline at the time. A -bc-curl-bc- call with an -bc-Authorization-bc-header. An environment variable like -bc-API_KEY=abc123-bc- prepended to a command. All of it ends up in the file, and the file ends up in your project directory.
The npm Publishing Gap
npm packages are built from the contents of your project directory. Files are excluded via -bc-.npmignore-bc- or the -bc-files-bc- field in package.json, but neither has a default entry for -bc-.claude/-bc-. There is no warning during -bc-npm publish-bc- if the directory is present. The settings file is a hidden dotfile that does not stand out in any part of the normal publish workflow.
-bc-.claude/settings.local.json-bc- follows the same convention as -bc-.env-bc-. The -bc-.local-bc- suffix signals that the file is personal and environment-specific. Unlike -bc-.env-bc-, it does not benefit from widespread awareness or tooling that flags it before it ships.
What We Built
We wrote a TypeScript service that monitors the npm registry's CouchDB changes feed. For every new or updated package, it fetches the tarball and inspects its contents. When a -bc-.claude/settings.local.json-bc- is present, the file is extracted and saved for analysis.
The Findings
Across approximately 46,500 packages monitored over our scan window, 428 contained a -bc-.claude/settings.local.json-bc-. Of those, 33 files across 30 packages contained credentials. Roughly one in thirteen settings files that shipped contained something sensitive.
What Was Inside
-db1-
- npm authentication tokens used to publish packages to the npm registry
- npm login credentials in plaintext: username, password, and email address concatenated into a single allowlist entry
- GitHub personal access tokens, including both fine-grained PATs and classic PATs
- Telegram Bot API tokens, which grant full control of the associated bot: reading messages, sending messages, and all other bot API operations
- Production bearer tokens for third-party services
- Hugging Face API tokens
- Plaintext test credentials: email and password pairs embedded in curl commands used to provision local development accounts-db1-
Why This Is Easy to Miss
The file is not obviously sensitive: it reads as a list of shell commands, and nothing in the publish workflow surfaces it. Most developers never open it.
Credentials end up in allowlist entries naturally. During active development with Claude Code, you approve a lot of commands. Most are harmless. But some involve authenticated API calls, deployment scripts, or service logins. Hit "allow always" instead of "allow once" on any of those, and they go into the file permanently.
Prevention
Add -bc-.claude/-bc- to your -bc-.npmignore-bc-:
If you use the -bc-files-bc- field in -bc-package.json-bc- to control what gets published, -bc-.claude/-bc- will not be included by default, but double-check before you publish.
Add it to -bc-.gitignore-bc- as well. The file has no place in version control:
Check what your next publish will include:
Check versions you have already published:
If The File Has Already Shipped
npm tarballs are permanent. Deprecating a version removes it from default install resolution but does not delete it and does not invalidate cached copies. Any credential that appeared in a published tarball should be considered compromised from the moment of publication, regardless of when it is discovered.
Rotate npm tokens at -bc-npmjs.com/settings/~/tokens-bc- and GitHub tokens at -bc-github.com/settings/tokens-bc-. For any other service whose credentials appeared in the file, rotate those too.
Conclusion
-bc-.claude/settings.local.json-bc- is not inherently dangerous, but it accumulates credentials as a side effect of normal use, and the current defaults do nothing to keep those credentials out of published packages. The fix is a single line in .npmignore. Add it before your next release.





