A PreToolUse hook that intercepts destructive Bash commands before execution. Works in yolo/bypass mode — adds a safety net without slowing down safe operations.
You (or Claude) runs a command
↓
Hook intercepts
↓
┌─────────────────┐
│ Match rules table │
└────────┬────────┘
↓
┌────────────────┐
│ deny → blocked │ (production-only, no override)
│ ask → prompt │ (user confirms, then proceeds)
│ none → allow │ (passes silently)
└────────────────┘
Three decisions:
- deny: Hard block. Push to main, kubectl in production.
- ask: Shows confirmation prompt. User approves or rejects.
- allow: Everything else passes without friction.
mkdir -p ~/.claude/hooks
curl -o ~/.claude/hooks/dangerous-command-guard.sh \
https://gist.githubusercontent.com/walis85300/f81e55a2f4855ef71ad89258c1eb350e/raw/dangerous-command-guard.sh
chmod +x ~/.claude/hooks/dangerous-command-guard.shAdd this to ~/.claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "~/.claude/hooks/dangerous-command-guard.sh"
}
]
}
]
}
}# macOS
brew install jq
# Ubuntu/Debian
sudo apt-get install jqOpen ~/.claude/hooks/dangerous-command-guard.sh and add a line to the RULES table:
ask :: your\s+regex\s+pattern :: Description shown to user
- Separator is
::(space-colon-colon-space) - Regex is case-insensitive (grep -iE)
- Pipes
|work in regex for alternation - Use
denyinstead ofaskfor hard blocks
Example — block terraform destroy:
ask :: terraform\s+destroy :: Terraform destroy — removes infrastructure
| Decision | Pattern |
|---|---|
| deny | git push origin main/production |
| deny | kubectl destructive ops in production namespace |
| ask | git push --force, git reset --hard, git clean -f, git branch -D |
| ask | kubectl delete/patch/scale-to-0, rollout restart in shared namespaces |
| ask | SQL mutations via kubectl exec (DELETE, TRUNCATE, INSERT, UPDATE) |
| ask | rm -rf, docker system prune, docker-compose down -v |
| ask | DROP TABLE/DATABASE |
| ask | Doppler secrets changes in prod config |
| ask | curl -X DELETE |
| ask | Redis FLUSHALL/FLUSHDB via kubectl exec |
| ask | migrate --force, queue:flush, config:cache in running pods |
The hook outputs JSON to stdout using the official permissionDecision API:
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "ask",
"permissionDecisionReason": "Description of why this is dangerous"
}
}"ask"→ Claude Code shows a confirmation prompt to the user"deny"→ Claude Code blocks the command entirely- No output +
exit 0→ command proceeds normally
The hook is designed to grow over time. After each session where a potentially dangerous command was executed without a guard rule, add it to the table. The format is simple enough that even Claude can suggest additions.