Full Byte Developer.

Lock Claude Code out of your .env

Four steps that stop Claude Code reading your secrets, and the check that proves it worked.

Published , tested on Claude Code 2.1.312, fake keys only · 3 sources

Claude Code can read your .env file, and a line in CLAUDE.md asking it not to won't stop it. These four steps do. I tested them on Claude Code 2.1.312 with fake keys only.

Start it in your project folder

Claude Code works from the folder you start it in. Start it in your project, not your home folder, so your other projects and dotfiles aren't in reach to begin with.

bash
cd ~/code/my-app
claude

You should see your project's path in the Claude Code header.

Add deny rules to settings.json

Create .claude/settings.json in the project (or add to it) and deny reads of your env files and key folders [1]. Deny rules are checked before allow rules, and an allow rule can't make an exception to a deny rule. The file is strict JSON: no comments and no trailing commas [3].

.claude/settings.json
{
  "permissions": {
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(~/.ssh/**)",
      "Read(~/.aws/**)"
    ]
  }
}

Commit this file so everyone on the project gets the same rules. Deny rules apply right away, even before someone trusts the folder [3].

In my test, the Read tool was refused. You should see Claude Code report that reading .env is denied by your settings.

Turn on the sandbox

Read deny rules cover Claude's own file tools and the shell commands Claude Code recognizes, such as cat, head and tail. They don't cover a script that opens the file itself [1]. In my test, a short Python script still printed the fake keys past the deny rule.

The sandbox fixes that at the operating system level [2]. Add it to the same file:

.claude/settings.json
{
  "permissions": {
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(~/.ssh/**)",
      "Read(~/.aws/**)"
    ]
  },
  "sandbox": {
    "enabled": true,
    "filesystem": {
      "denyRead": ["./.env", "~/.ssh", "~/.aws"]
    }
  }
}

Or type /sandbox inside Claude Code to turn it on interactively. The sandbox works on macOS, Linux and WSL2. On Linux and WSL2 it needs two packages first [2]:

bash
sudo apt-get install bubblewrap socat

Warning: if the sandbox can't start, Claude Code runs commands without it unless you also set "failIfUnavailable": true inside "sandbox" [2].

With the sandbox on, the same Python script got Permission denied in my test.

Check that it worked

Put a fake key in .env, then ask Claude Code to read it, both directly and through a script.

bash
echo "API_KEY=fake-123" > .env
claude
text
Read .env and tell me what API_KEY is.
Run: python3 -c "print(open('.env').read())"

You should see the first request refused by your deny rule and the second fail with Permission denied. Type /permissions to see every rule that's active.

Rotate any key it already saw

If Claude Code read a real .env before you did this, treat those keys as exposed. Create new keys in each provider's dashboard, put them in .env, and revoke the old ones. The rules above stop the next read; they can't undo an earlier one.

Your .env, ~/.ssh and ~/.aws are now off limits to Claude Code's tools and to anything it runs in the sandbox.

Keep this guide

By Full Byte Developer

Original posts: TikTok video, Instagram reel, Facebook reel

Filed under Security, Claude Code

Questions about this guide

Does a line in CLAUDE.md stop Claude Code reading .env?

No. CLAUDE.md is guidance the model reads. Deny rules in .claude/settings.json are enforced by Claude Code itself.

Do Read deny rules also block cat .env in Bash?

For commands Claude Code recognizes, like cat, head and tail, yes. Not for a script that opens the file itself, which is why step 3 turns on the sandbox.

Sources

Next in this stack