Skip to content

Navigation Menu

Sign in
Appearance settings
Sign up
Appearance settings
Open more actions menu

Latest commit

 

History

2 Commits
2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 

Repository files navigation

Securing Claude Code against secrets exposure

Claude Code reads .env files by default and no single built-in control fully prevents it. This guide layers multiple defences so that sensitive files are protected even if one mechanism is bypassed.


Threat model

Vector Risk
Built-in Read tool Claude directly reads .env via its file tool
Bash (cat, grep, etc.) Shell commands bypass permissions.deny rules
System reminders File-change notifications leak contents into Claude's context
Environment variable inheritance Secrets loaded at startup are visible in the process environment
Prompt injection (CVE-2025-55284) Malicious content tricks Claude into exfiltrating secrets via DNS

Note: .claudeignore is not a real feature - Claude reads files listed in it anyway.
.gitignore protects your Git history, not your secrets from AI tools.


Layer 1: permissions.deny Rules (block the Read Tool)

Create or edit .claude/settings.json in your project root:

{
  "permissions": {
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./.env.local)",
      "Read(./.env.production)",
      "Read(./secrets/**)",
      "Read(./**/*.pem)",
      "Read(./**/*.key)",
      "Read(./**/*id_rsa*)"
    ]
  }
}

⚠️ Syntax gotcha: Absolute paths require // not /.
Always use relative paths starting with ./ to avoid silent failures.

What this blocks: Claude's built-in Read, Grep, Glob, and LS tools.
What it does not 100% block: Bash commands like cat .env.


Layer 2: PreToolUse Hook (block Shell Commands)

Hooks intercept tool calls before they execute. Exit code 2 blocks the action; exit 0 allows it.

Step 1: Create the hook script

mkdir -p ~/.claude/hooks
touch ~/.claude/hooks/block-sensitive-reads.sh
chmod +x ~/.claude/hooks/block-sensitive-reads.sh

Step 2: Write the script

#!/bin/bash
# ~/.claude/hooks/block-sensitive-reads.sh
# Blocks shell-level access to sensitive files.
# Claude passes the tool input as JSON on stdin.

INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.command // ""')

BLOCKED_PATTERNS=(
  '\.env'
  '\.env\.'
  'secrets/'
  '\.pem'
  '\.key'
  'id_rsa'
  'credentials'
  '\.netrc'
  'aws/credentials'
  'kubeconfig'
)

for pattern in "${BLOCKED_PATTERNS[@]}"; do
  if echo "$COMMAND" | grep -qiE "$pattern"; then
    echo "Blocked: access to sensitive files via shell is not permitted." >&2
    exit 2
  fi
done

exit 0

Step 3: Register the hook in settings.json

{
  "permissions": {
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)"
    ]
  },
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "~/.claude/hooks/block-sensitive-reads.sh"
          }
        ]
      }
    ]
  }
}

⚠️ Limitation: Hooks are best-effort. A creative shell one-liner
(python3 -c "print(open('.env').read())") can still slip through.
This is why Layer 3 is essential.


Layer 3: Enable /sandbox (OS-Level enforcement)

/sandbox uses macOS Seatbelt or Linux bubblewrap to enforce deny rules at the OS level, closing the Bash bypass vector entirely.

Inside a Claude Code session, run:

/sandbox

With sandboxing active, deny rules block all access - including shell commands - not just Claude's built-in tools. This is the single most impactful step you can take.

/sandbox is per-session. If you close and reopen Claude Code, re-enable it.


Checklist

Copy this to your project and work through it top to bottom.

[ ] 1. Added permissions.deny rules to .claude/settings.json
[ ] 2. Created and registered the PreToolUse hook script
[ ] 3. Enabled /sandbox at the start of each Claude Code session
[ ] 4. Confirmed .env is in .gitignore (protects Git history)
[ ] 5. Rotated any secrets that were already in a project Claude Code accessed

Summary

Layer Mechanism Blocks Read tool Blocks Bash OS-enforced
1 permissions.deny ❓ (sometimes)
2 PreToolUse hook ✅ (best effort)
3 /sandbox

Recommended stack: All three layers together.


Further reading

About

No description, website, or topics provided.

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Morty Proxy This is a proxified and sanitized view of the page, visit original site.