Policy evaluation flow
Pattern matching handles 95%+ of decisions in microseconds. The optional rampart-verify sidecar adds LLM-based classification for ambiguous commands. All decisions go to a hash-chained audit trail.Evaluation order
When a tool call arrives, Rampart evaluates it in this order:- Match collection — Collect all policies whose
matchclause fits the tool call (tool type, agent name, session) - Rule evaluation — Within each policy, rules evaluate top-to-bottom until first match
- Cross-policy resolution — Across all matched policies:
- Any
deny→ denied immediately - No deny + any
log→ logged - Only
allow→ allowed
- Any
- Default action — Nothing matches → configurable default action (allow or deny)
Deny always wins. If any policy says deny, the call is denied. No ambiguity, no override.
Performance
Policy evaluation happens in single-digit microseconds:| Command | Decision | Time |
|---|---|---|
rm -rf / | deny | 8µs |
sudo reboot | watch | 6µs |
.ssh/id_rsa read | deny | 3µs |
git status | allow | 4µs |
curl ngrok.io | deny | 3µs |
Interception methods
Rampart supports multiple integration methods depending on your agent framework:Native hooks
Supported agents: Claude Code, ClineWorks in
--dangerously-skip-permissions mode for Claude Code.- Exec: ✅ (via PreToolUse hook)
- File operations: ✅ (via hooks)
- Response scanning: ✅ (PostToolUse for Claude Code)
- Subprocess cascade: ❌
Shell wrapping
Supported agents: Any agent that reads$SHELL
rampart wrap sets $SHELL to a policy-checking shim. Works with any agent that spawns commands via the shell environment variable.
How it works:
- Starts an embedded proxy
- Generates a shell shim script
- Sets
$SHELLto point to the shim - Execs the child process
- Every shell command spawned by the child goes through the shim
- Shim checks preflight API before executing
- Exec: ✅ (via shell shim)
- File operations: ❌
- Response scanning: ❌
- Subprocess cascade: ✅ (LD_PRELOAD)
LD_PRELOAD interception
Supported platforms: Linux (all), macOS (most binaries)execve, execvp, system(), popen(), posix_spawn()
Linux: Works with all dynamically-linked binaries (~95% coverage)
macOS: Works with Homebrew, nvm, pyenv, cargo binaries. Blocked by SIP for
macOS: Works with Homebrew, nvm, pyenv, cargo binaries. Blocked by SIP for
/usr/bin/* (but AI agents don’t live there)- Exec: ✅ (syscall interception)
- File operations: ❌
- Response scanning: ❌
- Subprocess cascade: ✅ (recursive LD_PRELOAD)
HTTP proxy
Supported: Any framework that can make HTTP requests- Exec: ✅ (if agent implements)
- File operations: ✅ (if agent implements)
- Response scanning: ✅
- Subprocess cascade: ❌
MCP proxy
Supported: Any MCP servertools/call against your policies.
In your MCP config:
- Exec: ✅
- File operations: ✅
- Response scanning: ✅
- Subprocess cascade: ❌
Command normalization
Before pattern matching, commands go through normalization to prevent evasion:Decoding
- Base64 commands decoded before pattern matching
- Leading shell comments stripped
- ANSI escape sequences removed
- Null bytes and control characters removed
Subcommand extraction
Inner commands are matched independently:$(cmd)— command substitution- Backticks — legacy command substitution
eval 'cmd'— eval expressions
Pattern matching
Two types of matching: Glob patterns (command_matches):
command_contains, case-insensitive):
Substring matching is more resilient against obfuscation but can produce false positives. Use both strategically.
Response-side scanning
For agents with native hooks (Claude Code), Rampart scans tool responses for credential patterns:- AWS access keys
- Private SSH keys
- API tokens
- Bearer tokens
- Generic secrets (BASE64-encoded credentials)
- Maximum pattern length: 500 characters
- Nested quantifiers rejected at load time
- Execution timeout: 100ms per regex match
- Response cap: 1MB maximum
Audit trail
Every tool call is logged to hash-chained JSONL. Each entry includes a SHA-256 hash of the previous entry — tamper with any record and the chain breaks.- ULID event IDs (time-ordered, sortable)
- External anchor every 100 events (prevents full-chain recomputation)
- fsync on every write
- Log rotation with chain continuity across files
The hash-chained audit trail detects partial tampering (editing, inserting, or deleting individual records). A complete rewrite from scratch with a new valid chain is not detectable from the log file alone.