Processes tool call requests from AI agent hook systems (Claude Code, Cline). Reads JSON from stdin, evaluates against policy, returns allow/deny on stdout.
Usage
Typically called by agent frameworks, not directly by users.
How it works
- Agent invokes hook - Sends tool call as JSON on stdin
- Hook parses input - Extracts tool, command, parameters
- Policy evaluation - Checks against loaded policies
- Response - Returns decision as JSON on stdout
- Agent proceeds - Executes if allowed, blocks if denied
Flags
--audit-dir
string
default:"~/.rampart/audit"
Directory for audit logs (JSONL files)
Mode: enforce, monitor, or audit
--format
string
default:"claude-code"
Input format: claude-code or cline
--serve-url
string
default:"http://localhost:9090"
Rampart serve API URL (auto-discovered)
Bearer token for serve API (auto-discovered from ~/.rampart/token)
--config-dir
string
default:"~/.rampart/policies/"
Additional policy directory (merged with --config)
claude-code
Native Claude Code hook protocol.
Input (PreToolUse):
{
"session_id": "abc123",
"hook_event_name": "PreToolUse",
"tool_name": "Bash",
"tool_input": {
"command": "npm test"
},
"tool_use_id": "toolu_01ABC",
"cwd": "/home/user/project"
}
Output (allow):
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "allow"
}
}
Output (deny):
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "Rampart: Destructive command blocked"
}
}
Output (ask):
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "ask",
"permissionDecisionReason": "Production deployment requires approval"
}
}
cline
Cline (VS Code extension) hook protocol.
Input:
{
"clineVersion": "3.0.0",
"hookName": "preToolUse",
"timestamp": "2026-03-03T14:23:01Z",
"taskId": "task_123",
"preToolUse": {
"toolName": "execute_command",
"parameters": {
"command": "npm test"
}
}
}
Output (allow):
Output (deny):
{
"cancel": true,
"errorMessage": "Rampart: Destructive command blocked"
}
Setup
Hook is typically configured by rampart setup.
Claude Code
Manual setup (~/.claude/settings.json):
{
"hooks": {
"PreToolUse": [
{
"matcher": ".*",
"hooks": [
{
"type": "command",
"command": "rampart hook"
}
]
}
],
"PostToolUseFailure": [
{
"matcher": ".*",
"hooks": [
{
"type": "command",
"command": "rampart hook"
}
]
}
]
}
}
Or use setup:
rampart setup claude-code
Cline
Use setup:
Policy evaluation
Hook evaluates against:
- Global policy -
~/.rampart/policies/*.yaml
- Project policy -
.rampart/policy.yaml (if in git repo)
- Embedded standard - Fallback if no files found
Priority:
- Project denies override global
- Global
default_action always wins
Session detection
Hook auto-detects session from git:
# In git repo: myapp, branch: main
# Session: myapp/main
Override:
export RAMPART_SESSION=my-custom-session
Audit output
All tool calls are logged to ~/.rampart/audit/audit-hook-YYYY-MM-DD.jsonl:
{
"id": "01HGW1...",
"timestamp": "2026-03-03T14:23:01Z",
"agent": "claude-code",
"session": "myapp/main",
"tool": "exec",
"request": {"command": "npm test"},
"decision": {
"action": "allow",
"matched_policies": ["allow-dev"],
"message": "Development tool allowed"
},
"hash": "a7f3c2e8...",
"prev_hash": "b6e2d1c7..."
}
Examples
Test hook manually
# Create test input
echo '{
"tool_name": "Bash",
"tool_input": {"command": "rm -rf /"}
}' | rampart hook
# Output:
# {"hookSpecificOutput":{"hookEventName":"","permissionDecision":"deny","permissionDecisionReason":"Rampart: Destructive command blocked"}}
Debug hook
# Enable verbose logging
echo '{...}' | rampart hook --verbose
# Check stderr for debug output
Monitor mode
# Log only, don't block (modify settings.json)
{
"hooks": {
"PreToolUse": [{
"matcher": ".*",
"hooks": [{"type": "command", "command": "rampart hook --mode monitor"}]
}]
}
}
Environment variables
Hook reads:
Override auto-detected session (git repo/branch)
RAMPART_SERVE_URL
string
default:"http://localhost:9090"
Override serve URL
Override token (auto-read from ~/.rampart/token)
RAMPART_NO_PROJECT_POLICY
Set to 1 to skip project policy loading
Typical latency:
- Policy load: ~2ms (cached after first call)
- Evaluation: 4μs
- Audit write: less than 1ms
- Total: ~5ms per tool call
Invisible to user.
Troubleshooting
Hook not firing
Check settings.json:
cat ~/.claude/settings.json | jq '.hooks'
Verify rampart in PATH:
Check hook command:
echo '{"tool_name":"Bash","tool_input":{"command":"ls"}}' | rampart hook
Commands still allowed when they shouldn’t be
Check policy:
rampart policy lint
rampart test "rm -rf /"
Check audit:
rampart audit tail --decision deny
Session not detected
Check git repo:
git rev-parse --show-toplevel
git rev-parse --abbrev-ref HEAD
Override:
export RAMPART_SESSION=my-project
Exit codes
0 - Success (decision made)
1 - Error (policy load failed, etc.)
Note: Exit code does NOT indicate allow/deny. Check JSON output.
See also