How to keep API keys and passwords away from Claude Code

By: Irina Shvaya | October 14, 2026
This article is part of our Claude Code Guide: what Claude Code is, how to use it safely on a business website, and how to budget for and choose help. Want it set up for your team? See Claude Code consulting.

The short answer: never type a secret into a prompt or a CLAUDE.md file, deny Claude Code read access to the files that hold secrets, turn on the sandbox and tell it which credential files and environment variables to hide, and scan every push for keys that slipped into code. No single setting does the whole job. Permission rules stop Claude's file tools, the sandbox stops shell commands, and git-side scanning catches what both miss.

A secret here means anything that grants access: API keys, database passwords, SSH keys, hosting and CMS admin logins, payment and email service tokens, and analytics secrets. On a website project they tend to sit in a few files: .env files, framework config, and on WordPress the wp-config.php file, which WordPress describes as holding "database connection information." This guide shows how to keep all of them out of Claude Code's reach as of October 2026, and what to do if one leaks anyway.

Key Takeaways

  • Anything Claude reads is sent to Anthropic and written to a plaintext transcript under ~/.claude/projects/, kept 30 days by default. A pasted key ends up in both places.
  • Deny rules such as Read(./.env) block Claude's file tools, but not "a command that reads files without naming them, such as grep -r pattern .". The sandbox covers that gap.
  • The sandbox's credentials setting can block files like ~/.ssh and unset variables like GITHUB_TOKEN for shell commands. "There is no built-in credential deny list," so list your own.
  • Auto mode allows "Reading .env and sending credentials to their matching API" by default, and blocks "Printing a live credential or token into the transcript or a file."
  • GitHub push protection for a repository "Is disabled by default" and needs GitHub Secret Protection; the user-level version is on by default for public repositories.
  • If a key leaks, GitHub's advice applies: "rotate the affected credential immediately."

Why secrets and AI sessions don't mix

Three facts from Anthropic's documentation explain the risk. First, Claude Code sends "all user prompts and model outputs" to the model over TLS, so anything in the conversation leaves your machine. Second, transcripts are stored "locally in plaintext under ~/.claude/projects/ for 30 days by default." Third, shell commands Claude runs inherit your environment variables, "including any secrets in its environment."

There is also the risk of a hostile instruction hidden in content Claude reads, which tries to get it to send a key somewhere. That is covered in our guide to prompt injection risks on websites. The point here is simple: if a secret is never readable, it can't be leaked by mistake or on purpose.

Layer 1: what you type and what you commit

Start with habits, because no setting can undo a key you pasted yourself.

  • Never paste secrets into prompts. If Claude needs to call an API, it should read the key from an environment variable at run time, not see the value.
  • Never put secrets in CLAUDE.md or any file in .claude/. Project CLAUDE.md files are shared with your team through git. Our guide to writing a CLAUDE.md for a website covers what belongs there instead, such as "keys live in .env; never print them."
  • Don't send sessions that touched secrets with /feedback. Feedback reports include conversation history and code and are retained for 5 years.
  • Keep secret files out of git with .gitignore, and commit a template such as .env.example with empty values instead.

Layer 2: permission deny rules for Claude's file tools

Permission rules in .claude/settings.json are enforced by Claude Code itself, not by the model. A starting set for a website repository, using rule formats from Anthropic's permissions documentation:

{
"permissions": {
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)",
"Read(./config/credentials.json)"
]
}
}

What to know about these rules:

  • A Read deny rule also blocks editing that path, and Read and Edit rules also cover file commands Claude Code recognizes in Bash, such as cat and head.
  • Deny rules win across scopes: a deny in any settings file beats an allow in another, and "Deny rules block in every mode, including bypassPermissions."
  • A .claudeignore file "has no effect"; move its entries into Read deny rules.
  • The limit: they don't apply "to a command that reads files without naming them, such as grep -r pattern . run from the directory that holds the file, or to arbitrary subprocesses that read or write files indirectly." Anthropic's advice is to enable the sandbox "For OS-level enforcement."

Add your platform's own secret files to the list, such as Read(./wp-config.php) on WordPress, after checking that nothing in your workflow needs Claude to edit them. The full rule system is explained in every permission mode explained.

Layer 3: the sandbox and its credentials setting

The Bash sandbox is an operating-system boundary around the shell commands Claude runs. It is off by default; turn it on with /sandbox or sandbox.enabled. It runs on macOS, Linux and WSL2, not native Windows. By default, sandboxed commands can still read "Most of the machine, including credential files such as ~/.ssh and ~/.aws/credentials," so you have to say what to hide.

The sandboxing documentation offers a dedicated sandbox.credentials block. Anthropic's example denies two credential files and removes two tokens from the environment of sandboxed commands:

{
"sandbox": {
"enabled": true,
"credentials": {
"files": [
{ "path": "~/.aws/credentials", "mode": "deny" },
{ "path": "~/.ssh", "mode": "deny" }
],
"envVars": [
{ "name": "GITHUB_TOKEN", "mode": "deny" },
{ "name": "NPM_TOKEN", "mode": "deny" }
]
}
}
}

Anthropic says a deny entry "only ever narrows access," so any settings scope can add one and none can remove one another scope added. There is also a mask mode, where commands see a placeholder and the sandbox proxy substitutes the real value only on requests to hosts you allow. It depends on an experimental TLS setting and is honored only from user settings, managed settings or the --settings flag, never from a repository's settings files, so treat it as an advanced option for teams with an admin who can test it.

Two cautions from the same page. "The sandbox covers shell commands only. Claude's file tools, MCP servers, and hooks run outside it." And allowing broad domains "such as github.com can create paths for data exfiltration," so keep the network allowlist short.

Layer 4: scrub credentials from everything Claude starts

Setting the environment variable CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=1 strips credentials from "the environments of the subprocesses Claude Code starts, such as Bash commands, hooks, and stdio MCP servers," whether or not the sandbox is on. Anthropic says this "reduces what a prompt injection attack can read." It recognizes credentials by name or value shape and "leaves GitHub tokens and proxy settings in place," and Anthropic recommends using it "as one layer alongside narrow permission rules rather than as the only control." Test your build and deploy scripts after turning it on, since a script that needs a key will no longer see it.

Layer 5: keys that can't do much damage

The OWASP Secrets Management Cheat Sheet says secrets should "Only be visible to those who need them (least privilege)," "Be revocable," and "Never be logged." For a website team that means:

SecretSafer setup for Claude Code work
Database passwordA staging database with its own user; read-only where the task allows
Payment or email service keyTest-mode or sandbox keys only on development machines
Hosting or deploy tokenNot on the machine where Claude Code runs; deploys go through a reviewed pipeline
CMS admin loginA staging site account, never the live admin
GitHub token for automationFine-grained and scoped to one repository
Keys in CI workflowsStored as repository secrets, never committed

For GitHub Actions, Anthropic's docs say: "Never commit API keys or OAuth tokens directly to your repository. Always store them as GitHub Secrets." For a key shared across repositories, they recommend a Console API key over an OAuth token, which "is tied to the subscription of the person who ran claude setup-token." Our guide to Claude Code in GitHub Actions has the workflow side.

Layer 6: catch secrets before they reach git

Claude Code can write a key into a config file as easily as a person can, so scan what gets committed.

  1. Turn on push protection. GitHub's push protection "blocks pushes that contain secrets before they reach your repository." Repository-level protection "Requires GitHub Secret Protection to be enabled" and "Is disabled by default." User-level protection "Is enabled by default" and covers pushes to public repositories. Note that by default "anyone with write access to the repository can bypass push protection by specifying a bypass reason."
  2. Use secret scanning. It "scans your entire Git history on all branches." It runs free on public repositories; private organization repositories need GitHub Secret Protection on GitHub Team or Enterprise Cloud.
  3. Add a pre-commit check. OWASP suggests catching secrets "before commit/PR either in the IDE ... or via pre-commit hook."
  4. Add a Claude Code hook. A PreToolUse hook can block edits to protected files such as .env; our guide to hooks for website projects shows the pattern.

Claude Code's own credentials

Claude Code stores its own login securely: "API keys and tokens are stored in the macOS Keychain when available. On Linux they're stored in a file with mode 0600." Keep it that way. Don't export an Anthropic API key in your shell profile on a machine where you mean to use a subscription; Anthropic's environment variable reference says that when ANTHROPIC_API_KEY is set, "this key is used instead of your Claude Pro, Max, Team, or Enterprise subscription even if you are logged in." Interactive sessions ask you to approve the key once; -p runs use it without asking. In a company, admins can force sign-in to the organization's account and block environment keys with managed settings, covered in managed settings and admin controls.

If a secret leaks

  1. Rotate it first. GitHub: "When you receive an alert, rotate the affected credential immediately." Removing it from history is slower and "often unnecessary if you've already revoked the credential."
  2. Check the provider's logs for use you don't recognize.
  3. Delete local transcripts of the session that contained it, from ~/.claude/projects/.
  4. Fix the cause: add the deny rule, sandbox entry or hook that would have stopped it.

Conclusion

Keeping secrets away from Claude Code is a stack, not a switch: no secrets in prompts or CLAUDE.md, deny rules on secret files, the sandbox with your own credential list, subprocess scrubbing, low-privilege staging keys, and push protection on the repository. Each layer covers a gap in the one before it. These settings belong in the repository and, for companies, in managed settings, so they don't depend on memory. For the wider checklist, see our website security checklist, and if you want these controls set up and tested for your team, that is part of our Claude Code consulting. More guides are in our Claude Code Guide.

Frequently asked questions

Can Claude Code read my .env file?

Yes, unless you stop it. Add Read deny rules for .env files so Claude's file tools can't open them, and turn on the sandbox with those paths denied so shell commands can't read them either.

Is a .claudeignore file enough?

No. Anthropic's permissions page says a .claudeignore file has no effect and that you should move its entries into Read deny rules.

Does auto mode protect my keys?

Partly. Its classifier blocks printing a live credential into the transcript or a file and sending sensitive data to external endpoints, but it allows reading .env and sending credentials to their matching API by default. Deny rules and the sandbox are the firmer controls.

Where should API keys live on a website project?

In environment files that are git-ignored and denied to Claude, in your host's or CI system's secret store, or in a password manager. Development machines should hold staging or test keys, not production ones.

I pasted a key into a prompt. What now?

Treat it as exposed. Rotate the key with the provider, delete the session's local transcript, and don't send that session with /feedback.

Put this into action with eSEOspace

We help businesses grow with seo, geo & aeo that actually performs. Explore the services behind this guide:

Book a free strategy call →

Get a FREE Audit

We'll perform a comprehensive SEO, AEO, GEO & CRO audit of your website — completely free — and show you exactly how to outrank your competitors.

Don't have a site yet? Get in touch →

Get a FREE GEO/AEO/SEO Audit

We'll analyze your site's SEO, GEO, AEO & CRO — completely free — and show you exactly how to get found across Google and AI answers.

Don't have a site yet? Get in touch →

You Might Also like to Read