1
0
Fork 0
claude-code-complete-agent/examples/09-security-hooks/prompt.md
Kjell Tore Guttormsen 06ae605051 fix: pedagogical review - add expected output, CLAUDE.md, fix consistency
Address findings from pedagogical review simulating a non-expert user:

- Add CLAUDE.md to project root (was referenced but missing)
- Fix README score from 12/9/1 to 13/8/1 (match feature-map.md)
- Add Expected Output sections to examples 01, 02, 05, 09, 10
- Create pipeline-output/ and briefings/ directories
- Add example ordering guidance in README
- Add plan requirements for examples 11/13 in prerequisites
- Add skill frontmatter explanation in GETTING-STARTED.md
- Explain Cowork/Dispatch with links in cowork-integration
- Expand .gitignore with node_modules and generated output files
- Add model override hints in agent frontmatter comments

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 20:25:45 +01:00

2.8 KiB

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

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.