Block Writes That Embed a Live-Looking API Key
Catches the case the commit-time hook misses entirely: a secret written into a new file that never gets committed in this session — a scratch script, a local `.ipynb`, a debug dump — but sits on disk in the clear. Blocks the write itself rather than waiting for a git operation.
1. Save this as the hook script
#!/usr/bin/env python3
"""PreToolUse hook — blocks a Write/Edit whose new content contains a
live-looking secret. Wire this to the Write|Edit matcher."""
import json, re, sys
data = json.load(sys.stdin)
tool_input = data.get("tool_input") or {}
content = tool_input.get("content") or tool_input.get("new_string") or ""
PATTERNS = [
r"AKIA[0-9A-Z]{16}", r"sk-(ant|proj|live)-[A-Za-z0-9_-]{20,}",
r"ghp_[A-Za-z0-9]{36}",
]
for p in PATTERNS:
if re.search(p, content):
print(f"BLOCKED: new file content matches secret pattern `{p}`.", file=sys.stderr)
sys.exit(2)
sys.exit(0)
Save to a path inside your project, e.g. .claude/hooks/block-writes-with-live-api-key.sh, then chmod +x it.
2. Wire it into .claude/settings.json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{"type": "command", "command": "python3 .claude/hooks/block-writes-with-live-api-key.py"}
]
}
]
}
}
Before you use this
A hook runs with your local shell's permissions — review the script above before adding it, the same way you'd review any script you didn't write yourself. See our guide on hook security risks for the specific CVEs this category of feature has already produced.
Related hooks