# Example 09: Security Hooks **Capability:** Claude Code executes hook scripts before and after every tool call. PreToolUse hooks can block dangerous operations. PostToolUse hooks create audit trails. **OpenClaw equivalent:** Docker sandbox, exec approvals, tool deny lists, allowlists. --- ## How the Hooks Work The `hooks/` directory in this repo contains two scripts: - `pre-tool-use.sh` - runs before every Bash tool call. Blocks destructive patterns. - `post-tool-use.sh` - runs after every tool call. Appends to `hooks/audit.log`. Both are registered in `.claude/settings.json` under the `hooks` key. --- ## The Prompt ``` Try running this shell command: rm -rf /tmp/test-deletion-target Before running it, explain what you expect the PreToolUse hook to do. After the attempt, check hooks/audit.log and show me the last 5 entries. Then explain what was blocked and why it was flagged by the hook. ``` --- ## What Happens 1. Claude Code calls the Bash tool with `rm -rf /tmp/test-deletion-target` 2. Before execution, `pre-tool-use.sh` receives the command as input 3. The hook matches the `rm -rf` pattern and exits with a non-zero code 4. Claude Code receives the block signal and does not execute the command 5. `post-tool-use.sh` logs the blocked attempt with timestamp and tool name 6. Claude Code reports what happened and shows the audit log --- ## Reading the Audit Log ```bash tail -20 hooks/audit.log ``` Each entry has the format: `[timestamp] TOOL: bash | STATUS: blocked | CMD: rm -rf ...` --- ## Expected Output Claude will first explain what it expects the hook to do, then attempt the command. You should see something like: ``` I expect the PreToolUse hook (hooks/pre-tool-use.sh) to intercept this command because it matches the "rm -rf" pattern in the blocked list... [Claude attempts: rm -rf /tmp/test-deletion-target] [Hook blocks the command] The command was blocked by the PreToolUse hook. The hook matched "rm -rf" in the command string and returned exit code 2 with a block decision. ``` The audit log (`hooks/audit.log`) will contain an entry like: ``` [2026-03-26T10:15:23] TOOL: bash | STATUS: blocked | CMD: rm -rf /tmp/test-deletion-target ``` **How you know it worked:** - The `rm -rf` command was NOT executed (nothing was deleted) - Claude reported the hook blocked it - `hooks/audit.log` exists and has at least one entry - The entry shows STATUS: blocked --- ## Architecture Difference from OpenClaw OpenClaw sandboxes via Docker: the agent runs inside a container that limits what it can affect on the host. Claude Code sandboxes via permission layers and hooks: PreToolUse intercepts at the call level, before any syscall happens. For personal use, hooks are more flexible. You write exactly the rules you need. For untrusted third-party agents, Docker isolation is stronger. See `security/nemoclaw-comparison.md` for a full breakdown.