|
1 | 1 | --- |
2 | 2 | title: Securing OpenClaw |
3 | | -description: "Native Rampart integration for OpenClaw — policy enforcement, exec approval routing, and file tool protection in one command." |
| 3 | +description: "Native Rampart integration for OpenClaw — policy enforcement via before_tool_call hook. One command, full coverage." |
4 | 4 | --- |
5 | 5 |
|
6 | 6 | # OpenClaw |
7 | 7 |
|
8 | | -Rampart integrates natively with OpenClaw 2026.3.x. One command sets up full protection and connects Rampart's policy engine to OpenClaw's exec approval system. |
| 8 | +Rampart integrates natively with OpenClaw via the `before_tool_call` plugin API. Every tool call — exec, read, write, web_fetch, browser, message, and more — is evaluated against your policy before it runs. |
9 | 9 |
|
10 | | -!!! info "Version requirement" |
11 | | - Requires OpenClaw 2026.3.x or later for native exec approval integration. Earlier versions work with shell shim only. |
| 10 | +!!! info "Version requirements" |
| 11 | + - **OpenClaw >= 2026.3.28**: Native plugin (recommended) — full tool coverage via `before_tool_call` hook |
| 12 | + - **OpenClaw < 2026.3.28**: Legacy shim + bridge — exec-only coverage, requires re-patching after upgrades |
12 | 13 |
|
13 | | -!!! tip "Fastest path" |
14 | | - If you want your OpenClaw agent to install and configure Rampart for you, just say: |
15 | | - > "Install Rampart and protect this machine." |
16 | | - |
17 | | - The agent will run `rampart quickstart --yes` which handles everything automatically. |
18 | | - See the [agent install guide](../guides/agent-install.md) for full details. |
| 14 | + `rampart setup openclaw` auto-detects your version and uses the right method. |
19 | 15 |
|
20 | 16 | ## Setup |
21 | 17 |
|
22 | 18 | ```bash |
23 | | -rampart quickstart |
| 19 | +rampart setup openclaw |
24 | 20 | ``` |
25 | 21 |
|
26 | 22 | That's it. Rampart: |
27 | 23 |
|
28 | | -1. Installs `rampart serve` as a boot service |
29 | | -2. Configures the OpenClaw shell shim (exec protection) |
30 | | -3. Patches OpenClaw file tools (read/write/edit/grep protection) |
31 | | -4. Patches `web_fetch` (network exfiltration protection) |
32 | | -5. Auto-selects the `openclaw.yaml` policy profile |
33 | | -6. Connects to the OpenClaw gateway for native exec approval routing |
| 24 | +1. Detects your OpenClaw version |
| 25 | +2. **If >= 2026.3.28**: Extracts the bundled plugin and installs it via `openclaw plugins install` |
| 26 | +3. Configures OpenClaw to route decisions through Rampart (`tools.exec.ask: off`) |
| 27 | +4. Copies the `openclaw.yaml` policy profile to `~/.rampart/policies/openclaw.yaml` |
| 28 | +5. Starts `rampart serve` as a boot service (if not already running) |
34 | 29 |
|
35 | | -## How it works after setup |
| 30 | +No external downloads, no npm install — the plugin is bundled inside the `rampart` binary. |
36 | 31 |
|
37 | | -When `rampart serve` starts, it automatically connects to the OpenClaw gateway WebSocket and subscribes to exec approval events. This is the native integration — Rampart becomes the policy engine inside OpenClaw's approval flow. |
| 32 | +### Force the native plugin |
38 | 33 |
|
39 | | -``` |
40 | | -Agent wants to run a command |
41 | | - └─ OpenClaw fires exec.approval.requested |
42 | | - └─ Rampart evaluates policy |
43 | | - ├─ Hard deny (rm -rf /, cat ~/.ssh/id_rsa, etc.) |
44 | | - │ → resolved immediately, command never runs |
45 | | - │ → user sees nothing (no prompt needed) |
46 | | - │ |
47 | | - ├─ Safe command (npm test, git status, etc.) |
48 | | - │ → resolved allow-once immediately |
49 | | - │ → command runs, no prompt |
50 | | - │ |
51 | | - └─ Needs human review (kubectl apply, sudo, etc.) |
52 | | - → Rampart creates approval, notifies via your |
53 | | - configured channel (Discord, Telegram, etc.) |
54 | | - → command waits until you approve or deny |
| 34 | +```bash |
| 35 | +rampart setup openclaw --plugin |
55 | 36 | ``` |
56 | 37 |
|
57 | | -You can verify the bridge is connected: |
| 38 | +### Migrate from the old shim/bridge integration |
58 | 39 |
|
59 | 40 | ```bash |
60 | | -rampart status |
61 | | -# Shows: OpenClaw bridge: connected (ws://127.0.0.1:18789) |
| 41 | +rampart setup openclaw --migrate |
62 | 42 | ``` |
63 | 43 |
|
64 | | -Or check the serve log: |
| 44 | +Removes old dist patches and bridge config, installs the native plugin. |
| 45 | + |
| 46 | +## How it works |
65 | 47 |
|
66 | | -```bash |
67 | | -rampart log |
68 | | -# bridge: connected to OpenClaw gateway, listening for approval requests |
69 | 48 | ``` |
| 49 | +Agent wants to run a tool (exec, read, write, web_fetch, ...) |
| 50 | + └─ OpenClaw fires before_tool_call hook |
| 51 | + └─ Rampart plugin POSTs to localhost:9090/v1/tool/<name> |
| 52 | + └─ Rampart evaluates openclaw.yaml policy |
| 53 | + ├─ allow → tool runs |
| 54 | + ├─ deny → tool blocked, agent gets error message |
| 55 | + └─ ask → Rampart creates approval, notifies you |
| 56 | + tool waits until you approve or deny |
| 57 | +``` |
| 58 | + |
| 59 | +## Coverage |
| 60 | + |
| 61 | +With the native plugin, **all tool calls are covered**: |
| 62 | + |
| 63 | +| Tool | Coverage | Notes | |
| 64 | +|------|----------|-------| |
| 65 | +| `exec` | ✅ Native plugin | All commands evaluated | |
| 66 | +| `read` | ✅ Native plugin | Path-based policy matching | |
| 67 | +| `write` / `edit` | ✅ Native plugin | Path-based policy matching | |
| 68 | +| `web_fetch` | ✅ Native plugin | Domain allowlist/blocklist | |
| 69 | +| `web_search` | ✅ Native plugin | Always allowed by default | |
| 70 | +| `browser` | ✅ Native plugin | Domain-based rules | |
| 71 | +| `message` | ✅ Native plugin | Read actions always allowed; sends to unknown channels require approval | |
| 72 | +| `canvas` | ✅ Native plugin | Always allowed (UI only) | |
| 73 | +| `sessions_spawn` | ✅ Native plugin | Subagents cannot spawn further agents | |
70 | 74 |
|
71 | | -## Protecting Sub-Agents |
| 75 | +!!! note "Sub-agents" |
| 76 | + The `before_tool_call` hook fires for tool calls from subagents too. The `openclaw.yaml` profile uses `session_matches: ["subagent:*"]` to apply stricter rules to subagent sessions. |
72 | 77 |
|
73 | | -OpenClaw can spawn sub-agents like Codex CLI and Claude Code. These agents execute commands through their own shell processes, not through OpenClaw's exec tool. The bridge doesn't cover sub-agents — they need their own interception. |
| 78 | +## The `openclaw.yaml` profile |
| 79 | + |
| 80 | +The default profile installed by `rampart setup openclaw`. Key behaviors: |
| 81 | + |
| 82 | +- **`default_action: ask`** — any tool call not matched by an explicit rule surfaces for human approval (no silent failures) |
| 83 | +- **Safe exec commands allowed** — `go build`, `npm install`, `git commit`, `docker build`, etc. |
| 84 | +- **Dangerous exec requires approval** — `sudo`, `docker run --privileged`, `kubectl delete`, force-push blocked |
| 85 | +- **Credential reads require approval** — `.env`, `.kube/config`, `.aws/credentials` ask before reading; SSH keys hard-denied |
| 86 | +- **External curl/wget blocked** — use `web_fetch` tool instead (which is policy-aware) |
| 87 | +- **Subagent depth guard** — subagents cannot spawn further agents |
| 88 | + |
| 89 | +Install manually: |
74 | 90 |
|
75 | 91 | ```bash |
76 | | -rampart setup codex # Wraps Codex CLI with LD_PRELOAD |
77 | | -rampart setup claude-code # Adds hooks to ~/.claude/settings.json |
| 92 | +rampart init --profile openclaw |
78 | 93 | ``` |
79 | 94 |
|
80 | | -`rampart quickstart` handles this automatically if Codex or Claude Code are detected. |
| 95 | +## Always Allow writeback |
81 | 96 |
|
82 | | -## Coverage Matrix |
| 97 | +When you click "Always Allow" in the OpenClaw approval UI, Rampart writes a permanent smart-glob rule to `~/.rampart/policies/user-overrides.yaml` via `POST /v1/rules/learn`. The rule takes effect immediately without restarting serve. |
83 | 98 |
|
84 | | -| What | Protected by | Notes | |
85 | | -|------|-------------|-------| |
86 | | -| OpenClaw exec commands | ✅ Native bridge | Policy engine inside approval flow | |
87 | | -| File reads/writes/edits | ✅ File tool patches | Re-run after OpenClaw upgrades | |
88 | | -| `web_fetch` requests | ✅ Dist patch | Exfiltration via URL blocked | |
89 | | -| Codex CLI commands | ✅ `rampart setup codex` | LD_PRELOAD — all child processes | |
90 | | -| Claude Code commands | ✅ `rampart setup claude-code` | Native hooks | |
91 | | -| Other sub-agent commands | ✅ `rampart preload --` | LD_PRELOAD — universal | |
92 | | -| Browser automation | ⚠️ Not intercepted | Separate browser process | |
93 | | -| `message` tool | ⚠️ Not intercepted | Issue [#221](https://github.com/peg/rampart/issues/221) | |
| 99 | +For example, approving `sudo apt-get install nmap` always writes: |
| 100 | +```yaml |
| 101 | +- name: user-allow-<hash> |
| 102 | + match: |
| 103 | + tool: exec |
| 104 | + rules: |
| 105 | + - when: |
| 106 | + command_matches: ["sudo apt-get install *"] |
| 107 | + action: allow |
| 108 | +``` |
94 | 109 |
|
95 | | -## Rampart deny overrides OpenClaw approval |
| 110 | +## Verify the integration |
96 | 111 |
|
97 | | -!!! important "Approving in OpenClaw does not override a Rampart deny" |
98 | | - With the native bridge, Rampart evaluates the command **before** OpenClaw shows it to you. Hard deny rules (`action: deny`) are resolved immediately and the command never runs — you won't see an approval prompt at all. |
| 112 | +```bash |
| 113 | +rampart doctor |
| 114 | +``` |
99 | 115 |
|
100 | | - For commands that should be human-approvable, use `action: ask` in your policy. That creates an approval gate where Rampart notifies you and waits for your decision before resolving OpenClaw's approval. |
| 116 | +Expected output when fully configured: |
101 | 117 |
|
102 | | -## The `openclaw.yaml` profile |
| 118 | +``` |
| 119 | +✓ rampart serve: running (pid 12345) |
| 120 | +✓ OpenClaw plugin: installed (before_tool_call hook active) |
| 121 | +✓ Policy: openclaw.yaml loaded (N rules, default: ask) |
| 122 | +✓ Approval store: persistent (N pending) |
| 123 | +``` |
| 124 | + |
| 125 | +Or check plugin status directly: |
103 | 126 |
|
104 | | -`rampart quickstart` auto-selects the `openclaw.yaml` policy profile when OpenClaw is detected. This profile includes everything in `standard.yaml` plus: |
| 127 | +```bash |
| 128 | +openclaw plugins list |
| 129 | +# rampart v0.9.12 ✓ active |
| 130 | +``` |
105 | 131 |
|
106 | | -- **Session-aware rules**: main session (direct chat) has different permissions from subagents and cron jobs |
107 | | -- **Deployment gates**: `kubectl apply`, `terraform apply`, `docker push`, `helm install/upgrade` require approval |
108 | | -- **Tighter sub-agent restrictions**: subagents face more restrictions on sensitive file access and external actions |
| 132 | +## Troubleshooting |
109 | 133 |
|
110 | | -To install it manually: |
| 134 | +**Plugin not loading after setup:** |
111 | 135 |
|
112 | 136 | ```bash |
113 | | -rampart init --profile openclaw |
| 137 | +openclaw plugins list # check rampart is listed |
| 138 | +rampart doctor # shows plugin check status |
| 139 | +``` |
| 140 | + |
| 141 | +If missing, re-run setup: |
| 142 | + |
| 143 | +```bash |
| 144 | +rampart setup openclaw --plugin --force |
114 | 145 | ``` |
115 | 146 |
|
116 | | -## Disabling the bridge |
| 147 | +**OpenClaw version too old:** |
117 | 148 |
|
118 | | -To run Rampart without the native bridge (shim-only mode): |
| 149 | +```bash |
| 150 | +npm install -g openclaw@latest |
| 151 | +rampart setup openclaw # auto-detects new version |
| 152 | +``` |
| 153 | + |
| 154 | +**Checking what's being blocked:** |
119 | 155 |
|
120 | 156 | ```bash |
121 | | -rampart serve --no-openclaw-bridge |
| 157 | +rampart log --deny # recent denials |
| 158 | +rampart log --ask # recent approvals |
122 | 159 | ``` |
123 | 160 |
|
| 161 | +## Legacy: shim + bridge (OpenClaw < 2026.3.28) |
| 162 | + |
| 163 | +If you're on an older OpenClaw version, `rampart setup openclaw` falls back to: |
| 164 | + |
| 165 | +1. Shell shim (exec interception via `SHELL` env override) |
| 166 | +2. OpenClaw gateway bridge (WebSocket, exec-only coverage) |
| 167 | +3. Dist patches for file tools (fragile, re-run after OpenClaw upgrades) |
| 168 | + |
| 169 | +Upgrade OpenClaw to get the native plugin and avoid the upgrade fragility. |
| 170 | + |
124 | 171 | ## Uninstall |
125 | 172 |
|
126 | 173 | ```bash |
127 | 174 | rampart uninstall --yes |
128 | 175 | ``` |
129 | 176 |
|
130 | | -Removes the service, shell shim, OpenClaw gateway drop-in, and restores patched tool files. Policies and audit logs in `~/.rampart/` are preserved. |
131 | | - |
132 | | -!!! warning "File patches require re-running after OpenClaw upgrades" |
133 | | - `--patch-tools` modifies files in `node_modules`. After upgrading OpenClaw, run: |
134 | | - ```bash |
135 | | - rampart setup openclaw --patch-tools --force |
136 | | - ``` |
137 | | - Or restart the OpenClaw gateway — the `ExecStartPre` drop-in re-patches automatically on gateway restart. |
| 177 | +Removes the service, OpenClaw plugin, gateway drop-in, and restores any patched files. Policies and audit logs in `~/.rampart/` are preserved. |
0 commit comments