Skip to content

Snippet: Env Guard Hook for Claude Code

A PreToolUse bash script for Claude Code to intercept and block secret access.

snippet
dev-tools
security
ai

When using Claude Code CLI, the agent runs in your terminal and has access to your local files. To prevent Claude from reading .env files and accidentally sending your secrets to Anthropic's APIs, you can set up a PreToolUse hook.

Save this bash script to ~/.claude/hooks/guard-env.sh and make it executable (chmod +x).

#!/usr/bin/env bash
# PreToolUse hook (Read/Bash/Grep): blocks tool calls touching secret/credential
# files or dumping the environment.
#
# .env-style names are checked per token, so an allowlisted name elsewhere in
# the payload can't be smuggled in to defeat the guard (e.g. `cat .env .env.example`).

PAYLOAD=$(cat)

block() {
  printf '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"SECURITY: Blocked %s. Read .env.example or a schema file (env.ts/env.mjs) instead."}}\n' "$1"
  exit 0
}

# Secret paths and env dumps — any match blocks. 
DENIED='\.dev\.vars|\.pem\b|\.p12\b|\.pfx\b|\.ppk\b|\.p8\b|\bid_rsa\b|\bid_dsa\b|\bid_ed25519\b|\bid_ecdsa\b|\.ssh/|\.gnupg/|\.aws/|\.kube/config|\.docker/config|\.config/gh/|\.htpasswd\b|\.tfstate\b|\.[a-z0-9]+_history\b|(~|'"$HOME"')/\.(netrc|npmrc|pypirc|yarnrc|git-credentials|pgpass|my\.cnf|cargo/credentials|config/git/credentials|codex/config\.toml)|/proc/[^[:space:]]*/environ|\bprintenv\b|(^|[[:space:];&|"])env[[:space:]]*($|\|)'
printf '%s' "$PAYLOAD" | grep -Eiq "$DENIED" && block "a secret file or env dump"

KEYFILE='["'"'"'][A-Za-z0-9._~/-]*(\.key|credentials\.(json|ya?ml|toml)|secrets\.(json|ya?ml|toml))["'"'"']|(/|\./|~/)[^[:space:]"'"'"'{}()$]*(\.key|credentials\.(json|ya?ml|toml)|secrets\.(json|ya?ml|toml))\b'
printf '%s' "$PAYLOAD" | grep -Eiq "$KEYFILE" && block "a key/credential file"

while IFS= read -r tok; do
  case "${tok##*/}" in
    .env.example|.env.template|.env.sample|.env.defaults|env.ts|env.mjs|env.d.ts) ;;
    .env|.env.*|.envrc) block "a .env file" ;;
  esac
done < <(printf '%s' "$PAYLOAD" | grep -Eio '[^[:space:]"'"'"';|&<>()]*\.env[A-Za-z0-9._-]*')

exit 0

Get new posts by email

New writing in your inbox. Unsubscribe anytime.