Hook-Based Safety Guard Rails for Autonomous Code Agents
Runs small shell scripts on PreToolUse and PostToolUse hooks to block destructive commands, lint edits, and warn on context use outside the agent's reasoning
Add to Pack
Saved locally in this browser for now.
Cite This Pattern
yurukusa (@yurukusa) (2026). Hook-Based Safety Guard Rails for Autonomous Code Agents. In *Awesome Agentic Patterns*. Retrieved October 14, 2026, from https://agentic-patterns.com/patterns/hook-based-safety-guard-rails
@misc{agentic_patterns_hook-based-safety-guard-rails,
title = {Hook-Based Safety Guard Rails for Autonomous Code Agents},
author = {yurukusa (@yurukusa)},
year = {2026},
howpublished = {\url{https://agentic-patterns.com/patterns/hook-based-safety-guard-rails}},
note = {Awesome Agentic Patterns}
} Use when
- Code agents run unattended with shell and file write access
- Destructive commands or silent syntax errors are a risk
- The agent framework supports pre- and post-tool-use hooks
Avoid when
- The framework has no hook events
- You need complete protection, since pattern matching misses creative commands
- Every action already goes through human review
Problem
Autonomous code agents running unattended can execute destructive commands (rm -rf, git reset --hard), exhaust their context window without saving state, leak secrets via git push, or silently produce syntax errors that cascade into later failures.
These failures share a pattern: the agent took an action that a simple automated check would have caught. The agent itself can't reliably self-police because it operates within the same context that produces the mistakes.
Solution
Use the agent framework's hook system (PreToolUse / PostToolUse events) to inject safety checks that run outside the agent's reasoning loop. Each hook is a small shell script that inspects tool inputs or outputs and either warns, blocks, or logs.
Four guard rails that cover the most common failure modes:
-
Dangerous command blocker (PreToolUse: Bash) — Pattern-matches commands for
rm -rf,git reset --hard,DROP TABLE, etc. Blocks or warns before execution. -
Syntax checker (PostToolUse: Edit/Write) — After every file edit, runs the appropriate linter (
python -m py_compile,bash -n,jq empty). Catches errors immediately instead of 50 tool calls later. -
Context window monitor (PostToolUse: all) — Counts tool calls as a proxy for context consumption. Issues graduated warnings (soft → hard → critical) and auto-generates a checkpoint file when context is dangerously low.
-
Autonomous decision enforcer (PreToolUse: AskUserQuestion) — Blocks the agent from asking "should I continue?" during unattended sessions. Forces the agent to decide and log uncertainty instead.
# Example: dangerous command blocker (simplified)
#!/bin/bash
INPUT="$(cat)"
CMD="$(echo "$INPUT" | jq -r '.tool_input.command // empty')"
if echo "$CMD" | grep -qE 'rm\s+-rf|git\s+reset\s+--hard|git\s+clean\s+-fd'; then
echo "BLOCKED: Destructive command detected: $(echo "$CMD" | head -c 100)"
exit 2 # non-zero = block the tool call
fi
exit 0 # 0 = allow
Evidence
- Evidence Grade:
high - Academic Validation: External governance layers are necessary — OpenAgentSafety (2025) measures unsafe behavior on 51.2% of safety-vulnerable tasks with Claude-Sonnet-3.7, rising to 72.7% with o3-mini
- Runtime Governance: MI9 framework (2025) validates that rule-based, telemetry-driven safety logic operating outside the agent's context can effectively constrain behavior
- Pre-Execution Validation: CaMeL demonstrates that defeating prompt injections by design, with formally analyzed information flow around untrusted data, outperforms prompt-level defenses (Debenedetti et al., 2025)
How to use it
- Register hooks in the agent's settings file (e.g.,
settings.jsonfor Claude Code). - Each hook is a standalone shell script — no dependencies on the agent's internal state.
- PreToolUse hooks receive the tool name and input as JSON on stdin. Return exit code 2 to block.
- PostToolUse hooks receive the tool name, input, and output. Return exit code 0 (hooks can only warn, not block after execution).
- Shell scripts are the simplest handler, not the only one: Claude Code hooks also support HTTP endpoints, MCP tool calls, single-turn model prompts, and experimental subagent handlers, across 30+ events (PreCompact, SubagentStop, PermissionRequest, and others) beyond the tool-use pair shown here.
- Start with the dangerous command blocker (highest impact, lowest effort).
Trade-offs
-
Pros:
- Runs outside the agent's context — immune to prompt injection or reasoning failures
- Language-agnostic (shell scripts work with any agent framework that supports hooks)
- Each hook is independently deployable — add one at a time
- Zero performance overhead for the agent (hooks run in milliseconds)
-
Cons/Considerations:
- Pattern matching is inherently incomplete — creative destructive commands may slip through
- Context monitoring via tool-call counting is a proxy, not exact measurement
- Hooks can't prevent the agent from reasoning about dangerous actions, only from executing them
- Requires the agent framework to support PreToolUse/PostToolUse events
References
- Claude Code Hooks documentation — Official hook system for Claude Code: five handler types (command, HTTP, MCP tool, prompt, agent) and 30+ hook events
- claude-code-ops-starter — Open-source implementation of these 4 hooks with a risk-score diagnostic
- MI9: Runtime Governance Framework (2025) — Validating external governance layers for agentic AI
- OpenAgentSafety (2025) — Measures unsafe behavior on 51.2% (Claude-Sonnet-3.7) to 72.7% (o3-mini) of safety-vulnerable tasks
- CaMeL: Defeating Prompt Injections by Design (Debenedetti et al., 2025) — System-design defenses with formally analyzed information flow
- Design Patterns for Securing LLM Agents against Prompt Injections (Beurer-Kellner et al., 2025) — A catalogue of architectural security patterns for agents