YouMind
Войти

The .env Setup That Keeps Claude Code From Leaking Your Secrets (Full Config Included)

@zodchiii
АНГЛИЙСКИЙ30 апр. 2026 г.
1.7M
1.3K
149
30
5.9K

Суть

Learn how to secure Claude Code by configuring settings.json deny rules, using dummy test environments, and implementing pre-commit hooks to prevent sensitive credential leaks.

Claude Code reads your .env files the moment it opens your project.

Your API keys, database passwords, Stripe tokens, everything in .env file is loaded into memory and can end up in conversation logs sent to Anthropic's servers.

The only thing that actually blocks access is one line in settings.json, which most people don't have it and don't know about.

Here's the full security config 👇

Before we dive in, I share daily notes on AI & vibe coding in my Telegram channel: **https://t.me/zodchixquant**🧠

darkzodchi on X — cover

Why CLAUDE.md rules don't protect you

Most people add "never read .env files" to their CLAUDE.md and assume they're safe (they're not)

CLAUDE.md is a suggestion. Claude follows it most of the time, but under pressure (complex tasks, long context, ambiguous instructions) it can and does ignore advisory rules.

A GitHub issue from April 2026 confirmed: Claude reads and echoes .env contents into the conversation even when CLAUDE.md explicitly prohibits it.

The only reliable protection is a deny rule in settings.json. Deny rules are enforced at the system level before Claude even sees the file.

The difference between "please don't read this" and "you physically cannot read this."

darkzodchi - inline image

The 3 ways your secrets leak

It's not just about Claude reading .env directly. There are three paths:

1. Direct file read. Claude scans your project, opens .env, and the contents become part of the conversation context. This is the obvious one and the easiest to block with deny rules.

2. Runtime output capture. Claude runs your tests or starts your app. A failed HTTP request logs the full Authorization: Bearer sk-live-abc123... header. A database timeout dumps the connection string with the password. Claude captures all command output. Your secrets are now in the conversation, even though Claude never opened .env.

3. Grep and search tools. Claude uses grep to search your codebase for a function name. The search hits a config file containing credentials. The grep output includes the matched lines with your secrets visible.

Most people only protect against path 1. Paths 2 and 3 are where the real damage happens.

The deny rules that actually work

Add these to ~/.claude/settings.json for global protection across every project:

json

json
1{
2 "permissions": {
3 "deny": [
4 "Read(**/.env*)",
5 "Read(**/.dev.vars*)",
6 "Read(**/*.pem)",
7 "Read(**/*.key)",
8 "Read(**/secrets/**)",
9 "Read(**/credentials/**)",
10 "Read(**/.aws/**)",
11 "Read(**/.ssh/**)",
12 "Read(**/config/database.yml)",
13 "Read(**/config/credentials.json)",
14 "Read(**/.npmrc)",
15 "Read(**/.pypirc)",
16 "Write(**/.env*)",
17 "Write(**/secrets/**)",
18 "Write(**/.ssh/**)"
19 ]
20 }
21}

This blocks Claude from reading or writing any .env file, PEM keys, SSH keys, AWS configs, credential files, and npm/PyPI tokens. The \\ wildcard means it applies to every subdirectory in your project.

Blocking runtime leaks

Deny rules stop direct file reads but not runtime output. For that, use test-specific .env files with dummy values:

text
1# .env.test — safe to read, safe to leak
2STRIPE_SECRET_KEY=sk_test_not_a_real_key
3DATABASE_URL=postgres://test:test@localhost:5432/testdb
4OPENAI_API_KEY=sk-test-dummy-key-for-mocking
5AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
6AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

Point your test framework at .env.test instead of .env. Now when Claude runs your tests and captures output, the only keys visible are dummies.

The pre-commit hook that catches everything

Even with deny rules, mistakes happen. Add a git pre-commit hook that scans for secrets before any commit reaches your repo:

bash

bash
1#!/bin/bash
2# .git/hooks/pre-commit — blocks commits containing secrets
3
4PATTERNS=(
5 'sk-ant-' # Anthropic API keys
6 'sk-live-' # Stripe live keys
7 'sk_live_' # Stripe live keys (alt format)
8 'ghp_' # GitHub personal tokens
9 'gho_' # GitHub OAuth tokens
10 'AKIA' # AWS access keys
11 'xox[bpors]-' # Slack tokens
12 'SG\.' # SendGrid keys
13 'eyJ' # JWTs
14 'BEGIN.*PRIVATE KEY' # Private key material
15)
16
17BLOCKED_FILES=('.env' 'credentials.json' 'id_rsa' '*.pem' '*.key')
18
19for pattern in "${PATTERNS[@]}"; do
20 if git diff --cached --diff-filter=ACM | grep -qE "$pattern"; then
21 echo "BLOCKED: Found potential secret matching '$pattern'"
22 echo "Remove the secret and try again."
23 exit 1
24 fi
25done
26
27for file in "${BLOCKED_FILES[@]}"; do
28 if git diff --cached --name-only | grep -q "$file"; then
29 echo "BLOCKED: Attempted to commit sensitive file: $file"
30 exit 1
31 fi
32done
33
34echo "Pre-commit security check passed."
35exit 0

Make it executable: chmod +x .git/hooks/pre-commit

This catches Anthropic API keys, Stripe keys, GitHub tokens, AWS keys, Slack tokens, SendGrid keys, JWTs, and private key material. If any of these show up in a staged file, the commit is blocked.

Container isolation (the nuclear option)

For maximum security, run Claude Code inside a container where .env files literally don't exist:

bash

bash
1# Mount /dev/null over .env so Claude can't see it
2docker run -v /dev/null:/app/.env:ro your-dev-container

From Claude's perspective, .env is an empty file. Your secrets never enter the container filesystem. This is overkill for most projects but essential for client work with production credentials.

The full security config (copy-paste ready)

Complete ~/.claude/settings.json with all security protections:

json

json
1{
2 "permissions": {
3 "allow": [
4 "Read",
5 "Glob",
6 "Grep",
7 "LS",
8 "Edit",
9 "MultiEdit",
10 "Write(src/**)",
11 "Write(tests/**)",
12 "Bash(npm run *)",
13 "Bash(npm test *)",
14 "Bash(npx tsc *)",
15 "Bash(git status)",
16 "Bash(git diff *)",
17 "Bash(git log *)",
18 "Bash(git add *)",
19 "Bash(git commit *)"
20 ],
21 "deny": [
22 "Read(**/.env*)",
23 "Read(**/.dev.vars*)",
24 "Read(**/*.pem)",
25 "Read(**/*.key)",
26 "Read(**/secrets/**)",
27 "Read(**/credentials/**)",
28 "Read(**/.aws/**)",
29 "Read(**/.ssh/**)",
30 "Read(**/config/database.yml)",
31 "Read(**/config/credentials.json)",
32 "Read(**/.npmrc)",
33 "Read(**/.pypirc)",
34 "Write(**/.env*)",
35 "Write(**/secrets/**)",
36 "Write(**/.ssh/**)",
37 "Write(.github/workflows/*)",
38 "Bash(rm -rf *)",
39 "Bash(sudo *)",
40 "Bash(git push *)",
41 "Bash(npm publish *)",
42 "Bash(curl * | sh)",
43 "Bash(wget *)",
44 "Bash(chmod *)"
45 ],
46 "defaultMode": "acceptEdits"
47 }
48}

This is the settings.json from my previous article plus every security rule from this one. Allow rules for daily workflow, deny rules for secrets and dangerous operations. One file, full protection.

The checklist

Before your next Claude Code session:

  1. Do you have deny rules for .env files in settings.json?
  1. Do your tests use .env.test with dummy values?
  1. Is there a pre-commit hook scanning for secret patterns?
  1. Are production credentials stored in a vault, not plaintext files?
  1. Is .env in your .gitignore?
  1. Are .env files outside your project directory for extra safety?

If you checked all 6, your secrets are as protected as they can be. If you checked 0, you're one ambiguous Claude prompt away from your API keys appearing in a conversation log on Anthropic's servers.

I share daily notes on AI, finance, and vibe coding in my Telegram channel: **https://t.me/zodchixquant**

Thanks for reading🙏🏼

darkzodchi - inline image
Сохранение в один клик

Используйте YouMind для глубокого чтения вирусных статей с помощью ИИ

Сохраняйте источники, задавайте точные вопросы, обобщайте аргументы и превращайте вирусные статьи в полезные заметки в одном рабочем пространстве ИИ.

Исследовать YouMind
Для авторов

Превратите ваш Markdown в аккуратную статью для 𝕏

Когда вы публикуете длинные тексты, изображения, таблицы и блоки кода, форматирование в 𝕏 становится мучением. YouMind превращает полный черновик в Markdown в чистую статью, готовую к публикации в 𝕏.

Попробовать Markdown для 𝕏

Другие паттерны для анализа

Недавние виральные статьи

Смотреть другие виральные статьи