A PreToolUse hook that parses bash commands before execution. Understands wrappers (sudo, kubectl exec, ssh), SQL queries, and subcommands so you can allow kubectl get but ask for kubectl delete, or let SELECTs through while catching writes.
Beats manually approving every ls or blindly allowing everything.
git clone https://github.com/Osso/claude-bash-hook
cd claude-bash-hook
cargo build --releasecp target/release/claude-bash-hook ~/.local/bin/
# or wherever you keep your binariesmkdir -p ~/.config/claude-bash-hook
cp config.default.toml ~/.config/claude-bash-hook/config.tomlEdit config.toml to match your workflow. The example config has sensible defaults.
Add to ~/.claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "claude-bash-hook"
}
]
}
]
}
}# Default for unknown commands
default = "ask"
# Allow read-only commands
[[rules]]
commands = ["ls", "cat", "grep", "find", "ps", "df"]
permission = "allow"
reason = "read-only"
# Allow git read operations
[[rules]]
commands = ["git status", "git log", "git diff", "git branch"]
permission = "allow"
reason = "git read-only"
# Ask for git write operations
[[rules]]
commands = ["git push", "git push --force"]
permission = "ask"
reason = "git push"
# Recursive delete asks (not auto-denied)
[[rules]]
commands = ["rm -rf", "rm -r"]
permission = "ask"
reason = "recursive delete"Commands like sudo, env, kubectl exec, ssh, and timeout are unwrapped to analyze the inner command:
sudo rm -rf /tmp # checks "rm -rf" rule, not "sudo" rule
kubectl exec pod -- ls # checks "ls" ruleFor mysql/mariadb commands, the -e query is parsed:
mysql -e "SELECT * FROM users" # allowed (read-only)
mysql -e "DELETE FROM users" # asks (write operation)Rules can match command + subcommand:
kubectl get pods # matches "kubectl get" -> allow
kubectl delete pod # matches "kubectl delete" -> askSuggest better alternatives:
[[suggestions]]
command = "git checkout"
message = "Consider using 'git switch' or 'git restore' instead"- Claude Code calls the hook before executing a bash command
- Hook parses the command using tree-sitter-bash
- Checks against rules in order (first match wins)
- Returns
allow,ask, ordenyto Claude Code