3.1 KiB
3.1 KiB
Pre-Exec Hooks
Pre-exec hooks let workspace-level scripts intercept and approve/deny shell commands before they run. This provides a safety net for AI agent operations — preventing pushes to protected branches, writes to production databases, or dangerous file operations.
How It Works
Agent runs: git push origin develop
↓
Clawdbot exec tool → runs pre-exec hooks
↓
~/.clawdbot/hooks/safe-git.sh → receives command as JSON
↓
Hook outputs: {"decision": "deny", "reason": "🚫 Protected branch"}
↓
Exec tool throws error instead of running command
Hook Discovery
Hooks are discovered from these directories (in order):
<workspace>/.clawdbot/hooks/(preferred)<workspace>/hooks/(fallback)
Any executable shell script in these directories is treated as a hook.
Hook Protocol
Input (JSON on stdin)
{
"tool_name": "exec",
"tool_input": {
"command": "git push origin main",
"workdir": "/path/to/workspace",
"env": {}
}
}
Output (JSON on stdout)
{
"decision": "approve",
"reason": "optional message"
}
Or to deny:
{
"decision": "deny",
"reason": "🚫 Pushing to protected branches is blocked."
}
Writing a Hook
Create an executable script in .clawdbot/hooks/:
#!/bin/bash
# .clawdbot/hooks/block-sudo.sh
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')
if echo "$COMMAND" | grep -qE '(^|\s)sudo\s'; then
echo '{"decision": "deny", "reason": "🚫 sudo is not allowed."}'
exit 0
fi
echo '{"decision": "approve"}'
Make it executable:
chmod +x .clawdbot/hooks/block-sudo.sh
Example Hooks
Clawdbot includes example hooks in examples/pre-exec-hooks/:
safe-git.sh
Blocks:
- Force pushes (
--force,-f) - Pushes to protected branches (main, develop, staging, production)
- Remote modifications (
git remote add/remove/set-url)
safe-db.sh
Blocks:
- Non-SELECT operations on remote databases
- Migrations/seeds targeting staging/production environments
safe-rm.sh
Blocks:
rm -rf /rmon home/system directoriesrm -rf *(wildcard deletion)
Behavior
- Sequential execution: Hooks run in alphabetical order
- Short-circuit: First "deny" stops execution
- Fail-open: Timeouts and errors default to "approve"
- Timeout: 10 seconds per hook (configurable)
Environment Variables
Hooks receive these environment variables:
| Variable | Description |
|---|---|
CLAWDBOT_HOOK_NAME |
Name of the current hook |
CLAWDBOT_TOOL_NAME |
Tool being invoked (exec or Bash) |
Tips
- Use jq for parsing JSON input
- Keep hooks fast — they run on every command
- Log to stderr — only stdout is parsed
- Test locally before deploying
# Test a hook manually
echo '{"tool_name":"exec","tool_input":{"command":"git push origin main"}}' | .clawdbot/hooks/safe-git.sh
Related
- Exec Tool — Shell command execution
- Exec Approvals — Allowlist-based command approval