Claude Code's permissions.allow rules are fundamentally broken in many configurations. Wildcard matching fails, compound commands bypass rules, and bypassPermissions ignores allowlists entirely.
A PreToolUse hook enforces allowlists at the process level. The model cannot bypass hooks.
allowlist.sh — only approved commands can execute:
#!/bin/bash
# TRIGGER: PreToolUse | MATCHER: "Bash"
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')
[[ -z "$COMMAND" ]] && exit 0
ALLOWED=(
"^\\s*git (add|commit|diff|log|status|show|stash|branch)"
"^\\s*npm (test|run|install|ci|ls)"
"^\\s*python3? -m (pytest|py_compile)"
"^\\s*(cat|head|tail|wc|sort|grep|find|ls|pwd)"
)
for pattern in "${ALLOWED[@]}"; do
echo "$COMMAND" | grep -qE "$pattern" && exit 0
done
echo "BLOCKED: Not in allowlist" >&2
exit 2
| Feature | permissions.allow | Hook allowlist |
|---|---|---|
| Compound commands | Broken | Works |
| Wildcard matching | Inconsistent | Full regex |
| bypassPermissions | Ignored | Still enforced |
| Background agents | Often broken | Always works |
Related issues: #6850 (settings not respected), #30519 (permissions fundamentally broken), #40343 (bypassPermissions ignores allowlist).
npx cc-safe-setup --install-example allowlist
591 hooks. 8,872 tests.
cc-safe-setup · GitHub