Loading repository data…
Loading repository data…
h3rrkent / repository
Production-ready hook system and guardrails for Claude Code — synthesized by a 5-agent swarm (Security, Bash, PowerShell, SQL, DevOps)
A transparent discovery signal based on current public GitHub metadata.
This score does not audit code, security, maintainers, documentation quality, or suitability. Verify the repository and its current documentation before adoption.
A comprehensive, production-ready hook system for Claude Code, synthesized from five expert domains: bash/shell engineering, security, PowerShell/Windows, database safety, and DevOps/infrastructure. This document is the primary reference for understanding, configuring, deploying, and maintaining the system.
Claude Code hooks are shell scripts that intercept tool calls before and after they execute. This system implements a defense-in-depth strategy with four layers:
settings.json — fast, Claude-native enforcementThe system is built around the CLAUDE_ENV control plane: setting CLAUDE_ENV=production activates all production guardrails. Each hook sources a shared lib/common.sh library for consistent logging, error handling, and OS notifications.
Key guarantees:
rm -rf /, terraform destroy, kubectl delete) are always blocked regardless of environment~/.claude/logs/audit.jsonl)Based on the security expert's analysis, Claude Code faces eight threat categories:
An attacker embeds malicious instructions in content that Claude reads (web pages, files, API responses). The instructions attempt to override Claude's behavior.
Mitigations: user-prompt-guard.sh (7 injection categories), web-guard.sh (SSRF prevention)
A crafted prompt causes Claude to execute a malicious shell command (fork bomb, pipe-to-shell, disk wipe).
Mitigations: pre-bash.sh (HIGH severity patterns, always block), settings.json deny list
Attempts to read or print secrets, API keys, private keys, or cloud credentials.
Mitigations: file-guard.sh (read/write protection), post-audit.sh (output scanning), pre-bash.sh (sensitive file patterns)
Transferring project files, secrets, or data to external servers.
Mitigations: user-prompt-guard.sh (exfiltration patterns), settings.json deny list (scp, rsync to remote)
Installing malicious packages via npm install -g, pip install from untrusted URLs, or cargo install --git.
Mitigations: blocklist.conf (MEDIUM patterns), settings.json deny list
Using sudo, su, Start-Process -Verb RunAs, or writing to sudoers/authorized_keys.
Mitigations: pre-bash.sh (HIGH patterns), pre-bash.ps1 (Windows patterns), settings.json deny list
Writing to crontab, rc files, ~/.ssh/authorized_keys, systemd units, Windows autorun registry keys, or scheduled tasks.
Mitigations: pre-bash.sh, pre-bash.ps1, settings.json deny list
Database drops, infrastructure deletion, filesystem wiping, firewall disabling.
Mitigations: sql-guard.sh, migration-guard.sh, infra-guard.sh, git-guard.sh, pre-bash.sh
claude-hooks-production/
├── README.md # This document
├── settings.json # Production-ready Claude Code settings
├── install.sh # Installation script
└── hooks/
├── lib/
│ └── common.sh # Shared library (logging, helpers, OS notify)
├── blocklist.conf # Medium-risk ERE patterns (configurable)
├── pre-bash.sh # Bash command safety (HIGH/MEDIUM severity)
├── sql-guard.sh # SQL command risk classification
├── migration-guard.sh # ORM migration safety (alembic, prisma, etc.)
├── git-guard.sh # Git operation safety (force push, etc.)
├── infra-guard.sh # Terraform, K8s, AWS, GCP, Azure safety
├── file-guard.sh # File read/write protection
├── web-guard.sh # WebFetch SSRF prevention
├── post-audit.sh # PostToolUse credential detection
├── user-prompt-guard.sh # Prompt injection detection (7 categories)
├── notify.sh # OS + Slack + Teams notifications
├── session-end.sh # Session summary, cleanup, log rotation
├── cicd-integration.sh # Test/Terraform sentinels, Slack CI/CD notifications
├── pre-bash.ps1 # PowerShell/Windows equivalent of pre-bash.sh
└── tests/
└── run_tests.sh # Test framework for all hooks
All hooks are installed to ~/.claude/hooks/. Logs are written to ~/.claude/logs/.
The system enforces safety at three layers that work together:
The fastest enforcement layer. Claude Code evaluates these patterns before even calling hooks. They use glob-style matching against the tool invocation.
settings.json
└── permissions.deny
├── Destructive filesystem (rm -rf /, dd to block devices)
├── Remote code execution (curl|bash, wget|bash)
├── Privilege escalation (sudo -i, su -)
├── Git destructive ops (push --force, reset --hard)
├── Infrastructure deletion (terraform destroy, kubectl delete)
├── AWS/GCP/Azure destructive ops
└── Database destructive ops (DROP, TRUNCATE, FLUSHALL)
When to rely on deny patterns: For clearly-named destructive operations where the command string is deterministic. Fast and reliable but cannot inspect context (environment tier, file contents, etc.).
Deep contextual inspection before any tool executes. Hooks can access the full command/path/URL and environment variables.
PreToolUse hooks
├── Bash tool → git-guard → infra-guard → sql-guard → migration-guard → pre-bash
├── Write|Edit|MultiEdit → infra-guard → file-guard
├── WebFetch → web-guard
└── Read → file-guard
Hook return protocol:
0 = allow (tool proceeds normally)2 + JSON {"decision":"block","reason":"..."} on stdout = block (Claude sees the reason message)Runs after the tool completes. Cannot block but can detect problems and alert.
PostToolUse hooks (Bash|Write|Edit|MultiEdit)
├── cicd-integration → detect test pass/fail, terraform plan, git commit
└── post-audit → credential scan in output, large output alert, network with suppressed stderr
"model": "claude-sonnet-4-6"
Pins the model to ensure consistent behavior. Update when upgrading.
The allow list uses Claude Code's glob syntax to permit read-only and safe operations without hook overhead. Patterns follow the format Tool(glob).
Key allow categories:
| Category | Examples |
|---|---|
| Git safe ops | git status, git log*, git diff*, git add*, git commit* |
| Package managers | npm install, yarn run *, pnpm test |
| Language toolchains | go test*, cargo build*, python3 * |
| Terraform read-only | terraform plan*, terraform show*, terraform output* |
| Kubernetes read-only | kubectl get*, kubectl describe*, kubectl logs* |
| AWS read-only | aws ec2 describe*, aws s3 ls*, aws sts get-caller-identity |
| System inspection | ls*, find*, cat*, grep*, jq* |
The deny list is the union of patterns from all five experts. It covers:
The deny list is intentionally broad. False positives (legitimate commands blocked) are resolved by adding them to the allow list or adjusting hook logic.
| Variable | Default | Purpose |
|---|---|---|
CLAUDE_ENV | dev | Control plane: dev, staging, production |
LOG_DIR | ~/.claude/logs | Directory for audit and session logs |
PROTECTED_BRANCHES | main:master:release:hotfix:production | Colon-separated list of git branches that cannot be pushed to directly |
REQUIRE_TESTS_BEFORE_COMMIT | false | If true, requires a passing test sentinel before git commit |
TERRAFORM_PLAN_REQUIRED | true | Requires a plan sentinel before terraform apply |
PRODUCTION_NAMESPACES | prod:production:prd | Kubernetes namespaces treated as production |
ASSUME_PROD_WHEN_UNKNOWN | true | When environment cannot be detected, treat as production |
BLOCK_ON_MEDIUM | 1 | If 1, block medium-risk blocklist.conf matches; if 0, warn only |
NOTIFY_SLACK_MIN_LEVEL | warn | Minimum severity to post to Slack: info, warn, or error |
SESSION_SUMMARY_MIN_CHANGES | 3 | Minimum file changes before posting a session summary to Slack |
NOTIFICATION_APP_NAME | Claude Code | App name shown in OS notifications |
MAX_OUTPUT_BYTES | 51200 | Alert threshold for large tool output (50KB) |
LOG_MAX_BYTES | 10485760 | Audit log rotation threshold (10MB) |
PRODUCTION_AWS_ACCOUNTS | `` | Colon-separated AWS account IDs treated as production |
Optional variables (not set by default):
| Variable | Purpose |
|---|---|
SLACK_WEBHOOK_URL | Slack incoming webhook URL for notifications |
TEAMS_WEBHOOK_URL | Microsoft Teams incoming webhook URL |
Important: Never put secrets (API keys, webhook URLs containing tokens) directly in settings.json env block if the file is committed to version control. Use ~/.claude/settings.local.json for machine-specific secrets, or export them in your shell profile before starting Claude Code.
When Claude tries to run a Bash command, hooks execute in this order:
1. git-guard.sh (timeout: 10s)
- Force push detection
- Protected branch push detection
- git reset --hard
- git clean -f
- --no-verify bypass
- Optional test sentinel check
2. infra-guard.sh (timeout: 15s)
- terraform destroy/force-unlock
- terraform apply (plan sentinel check)
- kubectl delete/drain/cordon
- kubectl exec on prod namespaces
- AWS destructive/IAM/assume-role
- GCP/Azure destructive/IAM
- .tfstate direct edit
3. sql-guard.sh (timeout: 10s)
- DB client detection (psql, mysql, sqlite3, mongosh, redis-cli, etc.)
- Environment detection (5-tier)
- Risk classification (CRITICAL/HIGH/ELEVATED/MEDIUM/SAFE)
- CRITICAL always block, HIGH/ELEVATED env-gated
4. migration-guard.sh (timeout: 10s)
- ORM detection (alembic, prisma, flyway, liquibase, knex, django, rails, sequelize)
- Destructive migrations blocked on staging/prod
- Some patterns always blocked (flyway clean, liquibase dropAll)
5. pre-bash.sh (timeout: 10s)
- HI