https://github.com/peg/rampart
Open-source firewall for AI agents. Policy engine that audits and controls what OpenClaw, Claude Code, Cursor, Codex, and any AI tool can do on your machine.
https://github.com/peg/rampart
agent-security ai-agents ai-security audit-trail claude-code cli codex devtools golang ld-preload llm mcp openclaw policy-engine prompt-injection secure-ai-agents secure-openclaw security security-openclaw
Last synced: about 1 month ago
JSON representation
Open-source firewall for AI agents. Policy engine that audits and controls what OpenClaw, Claude Code, Cursor, Codex, and any AI tool can do on your machine.
- Host: GitHub
- URL: https://github.com/peg/rampart
- Owner: peg
- License: apache-2.0
- Created: 2026-02-10T22:51:51.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2026-03-25T01:19:06.000Z (3 months ago)
- Last Synced: 2026-03-25T18:59:06.970Z (3 months ago)
- Topics: agent-security, ai-agents, ai-security, audit-trail, claude-code, cli, codex, devtools, golang, ld-preload, llm, mcp, openclaw, policy-engine, prompt-injection, secure-ai-agents, secure-openclaw, security, security-openclaw
- Language: Go
- Homepage: https://rampart.sh
- Size: 4.48 MB
- Stars: 55
- Watchers: 1
- Forks: 8
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Codeowners: .github/CODEOWNERS
- Security: SECURITY.md
- Roadmap: docs/ROADMAP.md
- Notice: NOTICE
Awesome Lists containing this project
- awesome-openclaw - peg/rampart - Open-source firewall for AI agents. Policy engine that audits and controls what OpenClaw, Claude Code, Cursor, Codex, and any AI tool can do on your machine. (๐ก๏ธ Security & Safety)
README
# Rampart
**A firewall for AI coding agents.**
[](https://go.dev)
[](LICENSE)
[](https://github.com/peg/rampart/actions/workflows/ci.yml)
[](https://github.com/peg/rampart/releases)
[](https://docs.rampart.sh)
---
Claude Code's `--dangerously-skip-permissions` mode, and similar autonomous modes in Cline and Codex, give agents unrestricted shell access. Your agent can read your SSH keys, exfiltrate your `.env`, or `rm -rf /` with no guardrails.
Rampart sits between the agent and your system. Every command, file access, and network request is evaluated against your policy before it executes. Dangerous commands never run.
---
## Install
```bash
# Homebrew (macOS and Linux, recommended)
brew install peg/tap/rampart
# One-line install (no sudo required)
curl -fsSL https://rampart.sh/install | bash
# Go install (requires Go 1.24+)
go install github.com/peg/rampart/cmd/rampart@latest
```
**Windows (PowerShell):**
```powershell
irm https://rampart.sh/install.ps1 | iex
```
After installing, run `rampart quickstart` or follow the setup steps below.
---
## Quick start
Pick your agent and run one command:
```bash
# Claude Code
rampart setup claude-code
# OpenClaw
rampart setup openclaw
# Cline
rampart setup cline
# Codex CLI
rampart setup codex
# Any other agent (wraps $SHELL)
rampart wrap -- your-agent
```
That's it. Verify everything is working:
```bash
rampart doctor
```
Then watch your agent in real time:
```bash
rampart watch
```
### Optional persistent local config
If you do not want to keep exporting environment variables, Rampart also supports
`~/.rampart/config.yaml` for local defaults:
```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 daemon/split-topology API setups
```
| Setting | Use it for | Notes |
| --- | --- | --- |
| `url` | Primary Rampart base URL | Canonical setting for hook/watch/plugin/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 |
Notes:
- `url` is the main knob; use this unless you have a specific reason not to.
- `api` is **not** the normal setting for `rampart serve`; it is for advanced daemon/split-topology setups.
- Client-side `--api` flags expect an **API base URL** (`http://127.0.0.1:9091`), while daemon/server `--api` flags refer to an **API listen address** (`127.0.0.1:9091`).
Resolution order is: flag โ environment โ config file โ auto-discovered state โ default.
Once running, every tool call goes through Rampart's policy engine first:
```
ALLOW 14:23:01 exec "npm test" [allow-dev]
ALLOW 14:23:03 read ~/project/src/main.go [default]
DENY 14:23:05 exec "rm -rf /tmp/*" [block-destructive]
LOG 14:23:08 exec "curl https://api.example.com" [log-network]
ASK 14:23:10 exec "kubectl apply -f prod.yaml" [ask]
DENY 14:23:12 resp read .env [block-credential-leak]
-> blocked: response contained AWS_SECRET_ACCESS_KEY
```
---
## How it works

Pattern matching handles 95%+ of decisions in microseconds. The optional [rampart-verify](https://github.com/peg/rampart-verify) sidecar adds LLM-based classification for ambiguous commands. All decisions go to a hash-chained audit trail.
| Agent | Setup command | Integration |
|-------|--------------|-------------|
| **Claude Code** | `rampart setup claude-code` | Native `PreToolUse` hooks via `~/.claude/settings.json` |
| **OpenClaw** | `rampart setup openclaw` | Native plugin + selective native approvals |
| **Cline** | `rampart setup cline` | Native hooks via settings |
| **Codex CLI** | `rampart setup codex` | Wrapper that runs Codex through `rampart preload` |
| **Any agent** | `rampart wrap -- ` | Shell wrapping via `$SHELL` |
| **MCP servers** | `rampart mcp -- ` | MCP protocol proxy |
| **System-wide** | `rampart preload -- ` | LD_PRELOAD syscall interception |
Table of Contents
**Getting Started:** [Install](#install) ยท [Quick start](#quick-start) ยท [Claude Code](#claude-code) ยท [OpenClaw](#openclaw) ยท [Wrap any agent](#wrap-any-agent)
**Core Features:** [Policies](#writing-policies) ยท [Approval flow](#approval-flow) ยท [Audit trail](#audit-trail) ยท [Live dashboard](#live-dashboard) ยท [Webhook notifications](#webhook-notifications)
**Advanced:** [LD_PRELOAD](#protect-any-process-ld_preload) ยท [MCP proxy](#protect-mcp-servers) ยท [SIEM integration](#siem-integration) ยท [Webhook actions](#webhook-actions) ยท [Preflight API](#preflight-api)
**Reference:** [Performance](#performance) ยท [Security](#security-recommendations) ยท [OWASP coverage](#owasp-coverage) ยท [CLI reference](#cli-reference) ยท [Compatibility](#compatibility) ยท [Building from source](#building-from-source)
---
## Claude Code
Native integration through Claude Code's hook system. Every Bash command, file read, and write goes through Rampart before execution:
```bash
# Install background service
rampart serve install
# Wire up hooks
rampart setup claude-code
```
Then use Claude Code normally. Rampart runs invisibly in the background.
To remove:
```bash
rampart setup claude-code --remove
```
---
## OpenClaw
Native plugin integration is now the preferred setup on current OpenClaw builds:
```bash
rampart setup openclaw
```
This keeps OpenClaw's native approval UI while letting Rampart decide which commands actually need approval.
`rampart serve` is part of this path. The plugin calls the local Rampart service for policy evaluation, approvals, and audit flow.
### How exec approvals work
Rampart leaves global `tools.exec.ask` set to `"off"`, so routine shell commands do not spam you with approval prompts. When a Rampart policy returns `ask` for a specific exec call, the plugin reissues only that command with `ask: "always"`, which sends it through OpenClaw's native approval card.
In practice, that means:
- safe commands run normally, with no prompt
- denied commands are blocked immediately
- only commands that match a Rampart `ask` rule show an OpenClaw approval card
### What the plugin protects
**1. Native plugin**: evaluates tool calls in `before_tool_call`, blocks deny decisions immediately, and routes selective exec approvals through OpenClaw's native approval UI.
**2. Selective native approvals**: Rampart decides when an exec should require approval, and OpenClaw shows the approval card only for those matched commands.
**3. Bundled policy profile**: installs the OpenClaw-focused policy profile used by the plugin setup.
### Legacy compatibility path
`rampart setup openclaw --patch-tools` still exists as a compatibility option for older setups, but it is no longer the recommended path. It modifies OpenClaw dist files and must be re-applied after upgrades.
Run `rampart doctor` at any time to verify the current OpenClaw integration state.
---
## Wrap any agent
For agents without a hook system, `wrap` sets `$SHELL` to a policy-checking shim. Works with any agent that reads `$SHELL` (Aider, OpenCode, Continue, and more):
```bash
rampart wrap -- aider
rampart wrap -- opencode
rampart wrap -- python my_agent.py
```
---
## Protect any process (LD_PRELOAD)
For agents with no hook system and no `$SHELL` support, `preload` intercepts exec-family syscalls at the OS level:
```bash
rampart preload -- codex
rampart preload -- python my_agent.py
rampart preload -- node agent.js
# Monitor mode: log only, no blocking
rampart preload --mode monitor -- risky-tool
```
Intercepts `execve`, `execvp`, `system()`, `popen()`, and `posix_spawn()`. Denied calls return `EPERM`.
**Platform notes:** Works with all dynamically-linked binaries on Linux. Works on macOS with Homebrew/nvm/pyenv binaries; blocked by SIP for `/usr/bin/*` (AI agents don't live there).
---
## Protect MCP servers
Drop-in proxy between your agent and any MCP server:
```bash
rampart mcp -- npx @modelcontextprotocol/server-filesystem /path
```
In your MCP config (Claude Desktop, etc.):
```json
{
"mcpServers": {
"filesystem": {
"command": "rampart",
"args": ["mcp", "--", "npx", "@modelcontextprotocol/server-filesystem", "."]
}
}
}
```
Auto-generate policies from an MCP server's tool list:
```bash
rampart mcp scan -- npx @modelcontextprotocol/server-filesystem .
```
---
## Writing policies
Policies are YAML. Glob matching, hot-reload on file change.
> `rampart setup` creates `~/.rampart/policies/custom.yaml` as a starter template. It's never overwritten by upgrades.
```yaml
version: "1"
default_action: allow
policies:
- name: block-destructive
match:
tool: ["exec"]
rules:
- action: deny
when:
command_matches: ["rm -rf *", "mkfs.*", "dd if=*", ":(){ :|:& };:"]
message: "Destructive command blocked"
- name: block-credential-reads
priority: 1
match:
tool: ["read"]
rules:
- action: deny
when:
path_matches: ["**/.ssh/id_*", "**/.aws/credentials", "**/.env"]
message: "Credential 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"
```
Use `command_contains` for substring matching (case-insensitive):
```yaml
- name: block-dangerous-substrings
match:
tool: ["exec"]
rules:
- action: deny
when:
command_contains: ["DROP TABLE", "rm -rf"]
message: "Dangerous substring detected"
```
Use `action: ask` to trigger an approval prompt:
```yaml
- name: ask-before-sudo
match:
agent: ["claude-code"]
tool: ["exec"]
rules:
- action: ask
when:
command_contains: ["sudo "]
message: "This command needs your approval"
```
**No YAML editing required for common cases.** When a command is blocked, Rampart suggests what to run:
```bash
# When "npm install lodash" gets denied:
# ๐ก To allow this: rampart allow "npm install *"
rampart allow "npm install *"
# Rule added; policy reloaded (12 rules active)
```
**Evaluation:** Deny always wins. Lower priority number = evaluated first. Four actions: `deny`, `ask`, `watch`, `allow`.
### Project-local policies
Drop `.rampart/policy.yaml` in any git repo for project-specific rules. Commit it so every team member gets the same rules automatically:
```bash
rampart init --project
```
**Security note:** Set `RAMPART_NO_PROJECT_POLICY=1` to skip project policy loading when working in untrusted repos.
### Built-in profiles
```bash
rampart init --profile standard # allow-by-default, blocks dangerous commands
rampart init --profile paranoid # deny-by-default, explicit allowlist
rampart init --profile ci # strict; all approvals become hard denies
rampart init --profile yolo # log-only, no blocking
```
---
## Approval flow
For commands that need a human to decide:
```yaml
policies:
- name: production-deploys
match:
tool: ["exec"]
rules:
- action: ask
when:
command_matches: ["kubectl apply *", "terraform apply *"]
message: "Production deployment requires approval"
```
How approval reaches you depends on your environment:
| Environment | How you approve |
|-------------|----------------|
| Claude Code | Native approval prompt in the terminal |
| OpenClaw | Native approval card in your connected chat surface |
| Any | `rampart approve ` via CLI, dashboard, or signed URL |
```bash
rampart pending # What's waiting
rampart approve abc123 # Let it through
rampart deny abc123 # Block it
```
Pending approvals expire after 2 minutes by default (`--approval-timeout` to change).
---
## Audit trail
Every tool call is logged to hash-chained JSONL. Tamper with any record and the chain breaks:
```bash
rampart audit tail --follow # Stream events
rampart audit verify # Check chain integrity
rampart audit stats # Decision breakdown
rampart audit search # Query by tool, agent, decision, time range
```
---
## Live dashboard
```bash
rampart watch # TUI: live colored event stream
```
Web dashboard at **http://localhost:9090/dashboard/** when `rampart serve` is running. Three tabs: live stream, history, and a policy REPL to test commands before they run.
---
## Webhook notifications
```yaml
notify:
url: "https://discord.com/api/webhooks/your/webhook"
on: ["deny"]
policies:
# ...
```
Works with Discord webhooks, Slack incoming webhooks, or any HTTP endpoint.
---
## SIEM integration
```bash
# RFC 5424 syslog (Wazuh, QRadar, ArcSight, Sentinel)
rampart serve --syslog localhost:514
# Common Event Format (Splunk, QRadar)
rampart serve --syslog localhost:514 --cef
```
---
## Webhook actions
Delegate allow/deny decisions to an external service:
```yaml
rules:
- action: webhook
when:
command_matches: ['*production*']
webhook:
url: 'http://localhost:8090/verify'
timeout: 5s
fail_open: true
```
See [rampart-verify](https://github.com/peg/rampart-verify), an optional LLM sidecar for ambiguous commands (~$0.0001/call).
---
## Preflight API
Check if a call would be allowed without executing it:
```bash
curl -s localhost:9090/v1/preflight/exec \
-H "Authorization: Bearer $TOKEN" \
-d '{"agent":"a","session":"s","params":{"command":"rm -rf /"}}'
# โ {"allowed":false,"decision":"deny","matched_policies":["block-destructive"]}
```
---
## Performance
Policy evaluation 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 |
---
## Security recommendations
**Self-modification protection.** Agents cannot bypass their own policy by running `rampart allow` or `rampart block`. Those commands are blocked when executed by an agent. Policy modifications must be made by a human.
**Don't run your AI agent as root.** Root access defeats user separation. Run agent frameworks as an unprivileged user.
**Run `rampart serve` as a separate user** in production to prevent agents from reading audit logs or modifying policies.
For a full discussion of the threat model, see [`docs/THREAT-MODEL.md`](docs/THREAT-MODEL.md).
---
## OWASP coverage
Rampart maps to the [OWASP Top 10 for Agentic Applications](https://genai.owasp.org/resource/owasp-top-10-for-agentic-applications-for-2026/):
| Risk | Coverage |
|------|----------|
| **ASI02: Tool Misuse** | Yes: every tool call is evaluated before execution |
| **ASI05: Unexpected Code Execution** | Yes: pattern matching plus optional LLM verification |
| **ASI08: Data Exfiltration** | Yes: domain blocking and credential response scanning |
| **ASI09: Human-Agent Trust** | Yes: `ask` actions enforce human-in-the-loop |
| **ASI10: Rogue Agents** | Yes: hash-chained audit trail and response scanning |
| **ASI01: Goal Hijack** | Partial: policy limits blast radius even if goals are altered |
| **ASI06: Context Poisoning** | Partial: response scanning blocks credentials from context window |
| **ASI07: Inter-Agent Communication** | โ Not addressed |
[Full OWASP mapping โ](https://docs.rampart.sh/reference/owasp-mapping/)
---
## CLI reference
```bash
# Setup
rampart quickstart # Auto-detect, install, configure, health check
rampart setup claude-code # Claude Code native hooks
rampart setup cline # Cline native hooks
rampart setup openclaw # OpenClaw native plugin integration
rampart setup codex # Codex CLI shell wrapper (Linux, macOS)
rampart setup --remove # Clean uninstall
# Run
rampart wrap -- # Wrap any agent via $SHELL
rampart preload -- # LD_PRELOAD syscall interception
rampart mcp -- # Proxy MCP with policy enforcement
rampart mcp scan -- # Auto-generate policies from MCP tools
# Serve
rampart serve [--port 9090] # Start approval + dashboard server
rampart serve install # Install as a boot service (systemd/launchd)
rampart serve --background # Start in background
rampart serve stop # Stop background server
# Diagnose
rampart doctor # Health check (colored output)
rampart doctor --fix # Auto-apply missing patches
rampart doctor --json # Machine-readable (exit 1 on issues)
rampart status # Quick dashboard: what's protected
rampart watch # Live TUI event stream
# Policy
rampart init [--profile standard|paranoid|ci|yolo] # Initialize global policy
rampart init --project # Create .rampart/policy.yaml
rampart policy lint [file] # Lint policy file
rampart policy explain "git status" # Trace evaluation
rampart policy list # Browse community registry
rampart policy fetch # Install community policy
# Rules (no YAML editing required)
rampart allow "npm install *" # Allow a command pattern
rampart block "curl * | bash" # Block a pattern
rampart rules # List custom rules
rampart rules remove 3 # Remove by number
rampart allow "docker *" --for 1h # Temporary allow
# Test
rampart test "rm -rf /" # Dry-run against policies
rampart test --json # Structured output for CI
# Approvals
rampart pending # What's waiting
rampart approve # Allow
rampart deny # Deny
# Audit
rampart audit tail [--follow]
rampart audit verify
rampart audit stats
rampart log --deny # Recent denies
# Upgrade
rampart upgrade # New binary + refresh policies
rampart upgrade --no-binary # Refresh policies only
```
---
## Compatibility
| Agent | Method | Platforms |
|-------|--------|-----------|
| Claude Code | `rampart setup claude-code` | Linux, macOS, Windows |
| OpenClaw | `rampart setup openclaw` | Linux, macOS |
| Cline | `rampart setup cline` | Linux, macOS, Windows |
| Codex CLI | `rampart setup codex` | Linux, macOS (requires `librampart.so`/`.dylib`) |
| Claude Desktop | `rampart mcp` | All |
| Aider, OpenCode, Continue | `rampart wrap` | Linux, macOS |
| Python agents | `rampart preload` or HTTP API | Linux, macOS |
| Node.js agents | `rampart preload` or HTTP API | Linux, macOS |
| Any MCP server | `rampart mcp` | All |
| Any process | `rampart preload` | Linux, macOS |
| Custom agents | HTTP API at `localhost:9090` | All |
---
## Building from source
```bash
git clone https://github.com/peg/rampart.git
cd rampart
go build -o rampart ./cmd/rampart
go test ./...
```
Requires Go 1.24+.
---
## Upgrading from v0.9.8?
v0.9.9 contains three breaking changes:
**`action: require_approval` is now a hard error.**
Update your policies from:
```yaml
- action: require_approval
```
to:
```yaml
- action: ask
ask:
audit: true
```
Run `rampart policy lint` to find all occurrences.
**`--serve-token` flag removed.**
Use the `RAMPART_TOKEN` environment variable instead:
```bash
# Before (v0.9.8 and earlier)
rampart serve --serve-token mysecrettoken
# After (v0.9.9+)
RAMPART_TOKEN=mysecrettoken rampart serve
```
**`GET /v1/policy` endpoint removed.**
Use `GET /v1/status` for server health or `GET /v1/policies` to list active policies.
---
## Companion Tool: Snare
Rampart blocks. [Snare](https://snare.sh) catches.
Snare plants canary tokens in your AI agent's environment - API keys, cloud credentials, file paths. If your agent, or something that compromised it, uses those tokens, you get an instant alert.
**Rampart + Snare = preventive + detective controls.** Use both.
---
## Contributing
Contributions welcome. Open an issue first for anything beyond small fixes. All work goes through the `staging` branch. PRs to `main` require one approving review.
---
## License
[Apache 2.0](LICENSE)