Configuration¶
Rampart has two kinds of configuration:
- Runtime/client config — where Rampart should find its local service
- Policy config — what agents are allowed to do once Rampart evaluates a tool call
Most users only need one runtime setting:
Runtime Config (~/.rampart/config.yaml)¶
If you do not want to keep exporting environment variables, Rampart can load persistent local defaults from ~/.rampart/config.yaml.
url: http://127.0.0.1:9090
# serve_url: http://127.0.0.1:9090 # compatibility alias for url
# api: http://127.0.0.1:9091 # optional advanced override for split control-service setups
| Setting | Use it for | Notes |
|---|---|---|
url | Primary Rampart base URL | Canonical setting for hook, watch, plugin, and service-backed flows |
serve_url | Backwards-compatible alias for url | Kept for compatibility; prefer url in new configs |
api | Optional API base URL override for approval/control commands | Advanced only; usually unnecessary unless you split the API away from the main serve endpoint |
Resolution order¶
Rampart resolves service addresses in this order:
flag → environment → config file → auto-discovered state → default
That means:
--apior--serve-urlwins when you pass it explicitly- environment variables such as
RAMPART_URL,RAMPART_SERVE_URL, andRAMPART_APIoverride file values ~/.rampart/config.yamlis the persistent local default- if nothing is configured, Rampart falls back to discovered local state and then localhost defaults
For rampart protect, the resolved service URL is used consistently for startup checks, host configuration, and behavioral verification. An explicit non-default endpoint must already be reachable; Rampart will not silently start the default service instead. OpenClaw's native plugin further requires a loopback HTTP(S) URL and rejects credentials, paths, queries, and fragments.
Which setting should I use?¶
Use url unless you have a specific reason not to.
urlis the normal setting for local Rampart service discoveryserve_urlexists for compatibility with older setupsapiis not the normalrampart servesetting — it is an advanced client-side override for approval/control flows
Two different meanings of --api
Client-side --api flags expect an API base URL such as http://127.0.0.1:9091.
Daemon/server --api flags refer to an API listen address such as 127.0.0.1:9091.
Policy File Location¶
Rampart policies are YAML files that define what your AI agent can and can't do. Policies are evaluated in microseconds and hot-reload when you edit them.
By default, Rampart looks for policies in ~/.rampart/policies/. You can specify a custom location:
Basic Structure¶
version: "1"
default_action: allow # allow | deny | ask | watch
policies:
- name: my-policy
match:
tool: ["exec"] # Which tool types this applies to
rules:
- action: deny # deny | allow | ask | watch | webhook
when:
command_matches: ["rm -rf *"]
message: "Destructive command blocked"
Actions¶
| Action | Effect |
|---|---|
deny | Block the tool call. Agent receives an error. |
allow | Permit the tool call. |
watch | Permit but log with elevated visibility. (Previously called log — log still works as an alias.) |
ask | Block until a human approves or denies. Also valid as default_action: ask to surface unmatched calls for review. |
webhook | Delegate the decision to an external HTTP endpoint. |
Deny always wins. If any matching policy says deny, the call is denied regardless of other policies.
Tool Types¶
Common normalized tool types include:
| Tool | What It Matches |
|---|---|
exec | Shell commands (Bash, terminal) |
read | File read operations |
write | File write/edit operations |
fetch | HTTP requests, network operations |
For MCP tools, the tool name from the MCP tools/call is used directly (e.g., mcp__filesystem__read_file).
Matching Rules¶
Command Matching¶
rules:
- action: deny
when:
command_matches:
- "rm -rf *" # Glob pattern
- "mkfs.*" # Filesystem format
- "dd if=*" # Raw disk write
- ":(){ :|:& };:" # Fork bomb
Path Matching¶
rules:
- action: deny
when:
path_matches:
- "**/.ssh/id_*" # SSH private keys
- "**/.aws/credentials" # AWS credentials
- "**/.env" # Environment files
path_not_matches:
- "**/*.pub" # Exclude public keys
URL Matching¶
Match the full request URL for fetch tool calls. Useful when you need more precision than domain matching — for example, to allow a domain but restrict specific paths:
rules:
- action: deny
when:
url_matches:
- "https://api.example.com/admin/*" # Block admin endpoints
- "http://*/*" # Block non-HTTPS requests
- "https://*/v1/secrets*" # Block any host's secrets path
Use domain_matches when you only care about the hostname; use url_matches when path, scheme, or query matter.
Session Matching¶
Filter rules by session identity — the repo path, branch, or project label Rampart associates with the current run. Useful for per-project policies without separate YAML files:
rules:
- action: deny
when:
session_matches:
- "*/production" # Any repo on the production branch
- "infra-*" # Sessions labelled infra-*
- action: allow
when:
session_not_matches:
- "*/main" # Exclude main branch from this rule
Sessions are set by the agent integration (Claude Code sets them from the project path; MCP proxy uses the client-provided session ID).
Tool Parameter Matching¶
Match arbitrary MCP tool input parameters by name and glob pattern. Each key is a parameter name; any matching parameter triggers the rule (OR logic across params):
rules:
- action: deny
when:
tool_param_matches:
path: "**/.env*" # deny if the "path" param targets .env files
url: "*webhook.site*" # deny if the "url" param points to webhook.site
This is particularly useful for MCP tools where the tool name alone doesn't give enough context — for example, a generic file_read MCP tool where you want to restrict specific path arguments.
Domain Matching¶
rules:
- action: deny
when:
domain_matches:
- "*.ngrok-free.app"
- "*.requestbin.com"
- "webhook.site"
Response Matching¶
Scan tool output for sensitive patterns:
rules:
- action: deny
when:
response_matches:
- "AKIA[0-9A-Z]{16}" # AWS access key
- "-----BEGIN (RSA )?PRIVATE KEY-----" # Private keys
- "ghp_[a-zA-Z0-9]{36}" # GitHub PAT
Rate Limiting¶
Use call_count to trigger a rule when a tool is invoked more than N times in a sliding time window. Useful for capping runaway agents or limiting expensive operations:
rules:
- action: ask
when:
call_count:
gte: 50 # Threshold: 50 or more calls...
window: 10m # ...within the last 10 minutes
message: "High fetch volume — pausing for review"
- action: deny
when:
call_count:
tool: fetch # Optional: count only fetch calls (omit for all tools)
gte: 200
window: 1h
message: "Fetch rate limit exceeded"
window accepts standard duration strings: 1h, 30m, 10m, 5m, 1m. The counter increments on every PreToolUse event and resets as calls age out of the window.
Priority¶
Lower priority number = evaluated first. Use priority to ensure critical rules run before general ones:
policies:
- name: critical-blocks
priority: 1 # Evaluated first
match:
tool: ["exec"]
rules:
- action: deny
when:
command_matches: ["rm -rf /"]
- name: general-logging
priority: 10 # Evaluated later
match:
tool: ["exec"]
rules:
- action: watch
when:
command_matches: ["curl *"]
Approval Flow¶
For commands that aren't dangerous enough to block outright, but risky enough for a human to decide:
policies:
- name: approve-deployments
match:
tool: ["exec"]
rules:
- action: ask
when:
command_matches:
- "kubectl apply *"
- "terraform apply *"
- "docker push *"
- "helm upgrade *"
message: "Deployment — approve or deny?"
- name: approve-installs
match:
tool: ["exec"]
rules:
- action: ask
when:
command_matches:
- "pip install *"
- "npm install *"
- "brew install *"
message: "Package install — approve or deny?"
How you'll see the approval prompt depends on your setup:
- Claude Code — native permission dialog (the same one Claude uses for
ask) - Standalone MCP clients —
askfails closed immediately because the stdio proxy has no safely reachable approval resolver; use an explicit allow/deny rule for now - OpenClaw — sends a chat message you can approve inline
- Webhooks — sends a notification with a signed approve/deny link
Manage pending approvals:
rampart pending # What's waiting
rampart approve abc123 # Let it through
rampart deny abc123 --reason "not now" # Block it
Webhook Notifications¶
Get alerts when commands are blocked or need approval:
version: "1"
default_action: allow
notify:
url: "https://discord.com/api/webhooks/your/webhook"
on: ["deny", "ask"] # Options: deny, log, ask
policies:
# ... your policies
Example: Standard Policy¶
A sensible default that blocks destructive commands and credential access:
version: "1"
default_action: allow
policies:
- name: block-destructive
match:
tool: ["exec"]
rules:
- action: deny
when:
command_matches:
- "rm -rf /"
- "rm -rf ~"
- "mkfs*"
- "dd if=*"
- "chmod -R 777 /"
message: "Destructive command blocked"
- name: block-credential-access
match:
tool: ["read"]
rules:
- action: deny
when:
path_matches:
- "**/.ssh/id_*"
- "**/.aws/credentials"
- "**/.env"
path_not_matches:
- "**/*.pub"
message: "Credential file access blocked"
- name: block-exfil
match:
tool: ["fetch"]
rules:
- action: deny
when:
domain_matches:
- "*.ngrok-free.app"
- "*.requestbin.com"
- "webhook.site"
message: "Exfiltration domain blocked"
Example: Anti-Exfiltration Policy¶
Detect encoding, obfuscation, and data staging:
version: "1"
default_action: allow
policies:
- name: encoding-sensitive-files
priority: 1
match:
tool: "exec"
rules:
- action: deny
when:
command_matches:
- "base64 ~/.ssh/*"
- "base64 ~/.aws/*"
- "*cat*.ssh*|*base64*"
- "*cat*.aws*|*base64*"
- "*xxd*.ssh*"
message: "Encoding of sensitive files blocked"
- name: encoded-data-exfil
priority: 1
match:
tool: "exec"
rules:
- action: deny
when:
command_matches:
- "*base64*|*curl*"
- "*base64*|*wget*"
- "*base64*|*nc *"
message: "Encoded data sent to network blocked"
- name: reverse-shell
priority: 1
match:
tool: "exec"
rules:
- action: deny
when:
command_matches:
- "*bash -i >& /dev/tcp*"
- "*python*socket*connect*"
- "*nc -e /bin/*"
message: "Reverse shell pattern blocked"
Hot Reload¶
Rampart watches policy files for changes via fsnotify. Edit a YAML file and the policy engine picks it up immediately — no restart needed.
Validation¶
Check your policy file for errors:
Trace how a specific command would be evaluated:
Next Steps¶
- Policy Engine → — Full evaluation logic
- Policy Schema → — Complete YAML reference
- Integration Guides → — Hook up your agent