@clawdreyhepburn/carapace 0.2.1 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +337 -280
- package/docs/RECOMMENDED-POLICIES.md +189 -378
- package/docs/SECURITY.md +544 -0
- package/openclaw.plugin.json +31 -2
- package/package.json +1 -1
- package/src/index.ts +194 -28
- package/src/llm-proxy.ts +648 -0
- package/src/types.ts +9 -0
package/README.md
CHANGED
|
@@ -2,55 +2,142 @@
|
|
|
2
2
|
<h1 align="center">🦞 Carapace</h1>
|
|
3
3
|
<p align="center"><strong>Your agent's exoskeleton.</strong></p>
|
|
4
4
|
<p align="center">
|
|
5
|
-
|
|
6
|
-
Powered by <a href="https://www.cedarpolicy.com/">Cedar</a> +
|
|
7
|
-
<a href="https://github.com/JanssenProject/jans/tree/main/jans-cedarling">Cedarling WASM</a>.
|
|
5
|
+
Controls what your AI agent can do — which tools it can use, which commands it can run, and which websites it can talk to. If a policy says no, the agent can't do it.
|
|
8
6
|
</p>
|
|
9
7
|
<p align="center">
|
|
8
|
+
<a href="#how-it-works">How It Works</a> •
|
|
10
9
|
<a href="#installation">Installation</a> •
|
|
11
10
|
<a href="#quick-start">Quick Start</a> •
|
|
12
|
-
<a href="
|
|
11
|
+
<a href="docs/SECURITY.md">Security Guide</a> •
|
|
13
12
|
<a href="docs/RECOMMENDED-POLICIES.md">Recommended Policies</a> •
|
|
14
|
-
<a href="#gui">Control GUI</a> •
|
|
15
|
-
<a href="#security">Security</a> •
|
|
13
|
+
<a href="#the-control-gui">Control GUI</a> •
|
|
16
14
|
<a href="#attribution">Attribution</a>
|
|
17
15
|
</p>
|
|
18
16
|
</p>
|
|
19
17
|
|
|
20
18
|
---
|
|
21
19
|
|
|
22
|
-
|
|
20
|
+
## What is Carapace?
|
|
23
21
|
|
|
24
|
-
|
|
22
|
+
AI agents can do a lot. They can read and write files, run shell commands, call APIs, send emails, push code — anything you give them access to. That's powerful, but it's also dangerous. An agent that can delete files can delete *all* files. An agent that can call APIs can send your data anywhere.
|
|
25
23
|
|
|
26
|
-
**
|
|
24
|
+
**Carapace is a security layer that controls what your agent is allowed to do.** You write rules (called policies) that say things like "this agent can read files but not delete them" or "this agent can use git but not run sudo." Carapace enforces those rules on every single action the agent takes.
|
|
27
25
|
|
|
28
|
-
|
|
26
|
+
It works as a plugin for [OpenClaw](https://github.com/openclaw/openclaw) (an open-source AI agent platform), but the concepts apply to any agent system.
|
|
27
|
+
|
|
28
|
+
### What does it control?
|
|
29
|
+
|
|
30
|
+
Carapace gates three types of operations:
|
|
31
|
+
|
|
32
|
+
| What | How it works | Example |
|
|
33
|
+
|------|-------------|---------|
|
|
34
|
+
| **MCP tools** | Your agent connects to external tool servers (file system, GitHub, databases) via [MCP](https://modelcontextprotocol.io/). Carapace checks each tool call against your policies before it reaches the server. | Allow `read_file`, block `write_file` |
|
|
35
|
+
| **Shell commands** | Your agent runs commands on your computer. Carapace checks which program the agent is trying to run. | Allow `git` and `ls`, block `rm` and `sudo` |
|
|
36
|
+
| **API calls** | Your agent makes HTTP requests to websites and services. Carapace checks which domain the agent is trying to reach. | Allow `api.github.com`, block `pastebin.com` |
|
|
37
|
+
|
|
38
|
+
### What is Cedar?
|
|
39
|
+
|
|
40
|
+
[Cedar](https://www.cedarpolicy.com/) is a policy language created by AWS. Instead of configuring permissions in a settings file or a database, you write human-readable rules like this:
|
|
41
|
+
|
|
42
|
+
```cedar
|
|
43
|
+
// Let the agent use git
|
|
44
|
+
permit(
|
|
45
|
+
principal is Jans::Workload,
|
|
46
|
+
action == Jans::Action::"exec_command",
|
|
47
|
+
resource == Jans::Shell::"git"
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
// Never let the agent delete files
|
|
51
|
+
forbid(
|
|
52
|
+
principal,
|
|
53
|
+
action == Jans::Action::"exec_command",
|
|
54
|
+
resource == Jans::Shell::"rm"
|
|
55
|
+
);
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Cedar has one critical property: **forbid always wins.** If any rule says "no," the action is blocked — no matter how many other rules say "yes." This means you can't accidentally create a loophole by adding a new "allow" rule that overrides your safety restrictions.
|
|
59
|
+
|
|
60
|
+
Carapace uses [Cedarling](https://github.com/JanssenProject/jans/tree/main/jans-cedarling), a high-performance Cedar engine compiled to WebAssembly, so policy checks run in under 6 milliseconds.
|
|
61
|
+
|
|
62
|
+
### What is OpenClaw?
|
|
63
|
+
|
|
64
|
+
[OpenClaw](https://github.com/openclaw/openclaw) is an open-source platform for running AI agents. It connects AI models (like Claude or GPT) to messaging apps, tools, and services. Think of it as the runtime that makes your agent work. Carapace plugs into OpenClaw to add authorization — controlling what the agent is allowed to do within that runtime.
|
|
65
|
+
|
|
66
|
+
### What is MCP?
|
|
67
|
+
|
|
68
|
+
[MCP (Model Context Protocol)](https://modelcontextprotocol.io/) is an open standard for connecting AI agents to tools. An MCP server provides tools (like "read a file" or "search a database"), and the agent calls those tools to get work done. Carapace sits between the agent and the MCP servers, checking every tool call against your policies.
|
|
69
|
+
|
|
70
|
+
---
|
|
29
71
|
|
|
30
|
-
|
|
72
|
+
## How It Works
|
|
73
|
+
|
|
74
|
+
Carapace has two enforcement modes. You can use either or both.
|
|
75
|
+
|
|
76
|
+
### Mode 1: LLM Proxy (recommended — strongest protection)
|
|
77
|
+
|
|
78
|
+
This is the most secure setup. Here's what happens:
|
|
79
|
+
|
|
80
|
+
1. Your agent talks to an AI model (like Claude) to figure out what to do.
|
|
81
|
+
2. The AI model responds with instructions like "call the `exec` tool with command `rm -rf /tmp`."
|
|
82
|
+
3. **Normally**, your agent platform would immediately execute that instruction.
|
|
83
|
+
4. **With Carapace**, the AI model's response goes through Carapace first. Carapace reads every tool call in the response, checks it against your Cedar policies, and **removes any tool calls that aren't allowed.**
|
|
84
|
+
5. Your agent platform only sees the filtered response — it never even knows the AI tried to do something forbidden.
|
|
85
|
+
|
|
86
|
+
This works because Carapace intercepts the response before your agent platform processes it. The `setup` command automatically points your provider at Carapace's local proxy, so all LLM traffic flows through Cedar.
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
Your agent → Carapace proxy (localhost) → Anthropic/OpenAI API
|
|
90
|
+
↓
|
|
91
|
+
Cedar checks each
|
|
92
|
+
tool call in the
|
|
93
|
+
AI's response
|
|
94
|
+
↓
|
|
95
|
+
Denied calls are
|
|
96
|
+
removed before your
|
|
97
|
+
agent sees them
|
|
98
|
+
```
|
|
31
99
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
100
|
+
**Supports:** Anthropic (Claude) and OpenAI (GPT) APIs, both streaming and non-streaming.
|
|
101
|
+
|
|
102
|
+
### Mode 2: Tool-level gating (simpler, weaker)
|
|
103
|
+
|
|
104
|
+
Carapace registers its own versions of common tools (`carapace_exec` for shell commands, `carapace_fetch` for API calls, `mcp_call` for MCP tools). These check Cedar policies before doing anything. You then disable the built-in versions so the agent is forced to use Carapace's gated versions.
|
|
105
|
+
|
|
106
|
+
This is simpler to set up but weaker — it relies on the agent using the right tools. The LLM proxy is better because it's un-bypassable.
|
|
107
|
+
|
|
108
|
+
### The Control GUI
|
|
109
|
+
|
|
110
|
+
Carapace includes a web dashboard (runs locally on your machine) where you can:
|
|
111
|
+
|
|
112
|
+
- **See all tools** your agent has access to, organized by risk level
|
|
113
|
+
- **Toggle tools on/off** with a switch — each toggle creates a Cedar policy
|
|
114
|
+
- **Build policies visually** using dropdown menus instead of writing Cedar by hand
|
|
115
|
+
- **Edit the Cedar schema** that defines your policy structure
|
|
116
|
+
- **Verify** that all your policies are valid
|
|
117
|
+
|
|
118
|
+
Open it at [http://localhost:19820](http://localhost:19820) after starting Carapace.
|
|
119
|
+
|
|
120
|
+
---
|
|
37
121
|
|
|
38
122
|
## Architecture
|
|
39
123
|
|
|
40
124
|
```
|
|
41
|
-
|
|
42
|
-
|
|
|
43
|
-
|
|
|
44
|
-
|
|
|
45
|
-
|
|
|
46
|
-
|
|
|
47
|
-
| | | +----------------------+ |
|
|
48
|
-
|
|
|
49
|
-
|
|
|
50
|
-
| | |
|
|
51
|
-
|
|
|
52
|
-
|
|
|
53
|
-
| | |
|
|
125
|
+
+----------------------------+
|
|
126
|
+
| Carapace |
|
|
127
|
+
+-------------+ | | +------------------+
|
|
128
|
+
| | | +----------------------+ | | Anthropic / |
|
|
129
|
+
| OpenClaw |---->| | LLM Proxy | |---->| OpenAI API |
|
|
130
|
+
| Agent | | | (intercepts tool_use)| | +------------------+
|
|
131
|
+
| | | +----------------------+ |
|
|
132
|
+
| | | | | +-----------------+
|
|
133
|
+
| | | Cedar evaluates | | MCP Server A |
|
|
134
|
+
| | | every tool call |---->| (filesystem) |
|
|
135
|
+
| | | | | +-----------------+
|
|
136
|
+
| | | +----------------------+ | | MCP Server B |
|
|
137
|
+
| | | | Cedarling WASM | |---->| (GitHub) |
|
|
138
|
+
| | | | (Cedar 4.4.2) | | +-----------------+
|
|
139
|
+
| | | +----------------------+ |
|
|
140
|
+
| | | +----------------------+ |
|
|
54
141
|
| | | | Local Control GUI | |
|
|
55
142
|
+-------------+ | +----------------------+ |
|
|
56
143
|
+--------------+--------------+
|
|
@@ -61,303 +148,269 @@ The progression:
|
|
|
61
148
|
+-------------+
|
|
62
149
|
```
|
|
63
150
|
|
|
64
|
-
**
|
|
151
|
+
**Key components:**
|
|
152
|
+
|
|
153
|
+
- **LLM Proxy** — Sits between your agent and the AI model. Intercepts tool calls in the AI's response and filters out denied ones.
|
|
154
|
+
- **Cedarling WASM** — The Cedar policy engine, running as WebAssembly for near-native speed. This is where your policies are evaluated.
|
|
155
|
+
- **MCP Aggregator** — Connects to your upstream MCP servers, discovers their tools, and proxies calls through Cedar.
|
|
156
|
+
- **Control GUI** — A local web dashboard for managing tools and policies. Single HTML file, no build step, dark theme.
|
|
157
|
+
|
|
158
|
+
---
|
|
65
159
|
|
|
66
160
|
## Screenshots
|
|
67
161
|
|
|
68
162
|
### Tools Dashboard
|
|
69
|
-
|
|
163
|
+
See all tools across all connected servers. Toggle switches control access. Color-coded by risk level.
|
|
70
164
|
|
|
71
165
|

|
|
72
166
|
|
|
73
|
-
Tools are automatically categorized by risk level:
|
|
74
|
-
- ✏️ **Write** (orange) — creates or modifies data
|
|
75
|
-
- ⚡ **Execute** (red) — triggers operations, toggles state
|
|
76
|
-
- 🔍 **Browse** (blue) — lists, searches, inspects metadata
|
|
77
|
-
- 📖 **Read** (teal) — retrieves content, no side effects
|
|
78
|
-
|
|
79
|
-
Default sort puts the riskiest tools at the top. Filter by category, status, server, or search.
|
|
80
|
-
|
|
81
167
|
### Policy Management
|
|
82
|
-
View, edit, and delete Cedar policies. Each
|
|
168
|
+
View, edit, and delete Cedar policies. Each card shows permit/forbid and the full policy text.
|
|
83
169
|
|
|
84
170
|

|
|
85
171
|
|
|
86
172
|
### Visual Policy Builder
|
|
87
|
-
Build
|
|
173
|
+
Build policies with dropdown menus instead of writing Cedar. Live preview updates as you go.
|
|
88
174
|
|
|
89
175
|

|
|
90
176
|
|
|
91
177
|
### Schema Editor
|
|
92
|
-
View and edit the Cedar schema
|
|
178
|
+
View and edit the Cedar schema that defines your policy types and actions.
|
|
93
179
|
|
|
94
180
|

|
|
95
181
|
|
|
182
|
+
---
|
|
183
|
+
|
|
96
184
|
## Installation
|
|
97
185
|
|
|
98
|
-
###
|
|
186
|
+
### What you need
|
|
99
187
|
|
|
100
188
|
- [Node.js](https://nodejs.org/) 20 or later
|
|
101
|
-
- [OpenClaw](https://github.com/openclaw/openclaw)
|
|
189
|
+
- [OpenClaw](https://github.com/openclaw/openclaw) installed and running
|
|
102
190
|
|
|
103
|
-
###
|
|
191
|
+
### Step 1: Install the plugin
|
|
104
192
|
|
|
105
193
|
```bash
|
|
106
|
-
|
|
107
|
-
openclaw plugins install @openclaw/carapace
|
|
108
|
-
|
|
109
|
-
# Configure your MCP servers
|
|
110
|
-
openclaw configure
|
|
194
|
+
openclaw plugins install @clawdreyhepburn/carapace
|
|
111
195
|
```
|
|
112
196
|
|
|
113
|
-
###
|
|
197
|
+
### Step 2: Choose your enforcement mode
|
|
114
198
|
|
|
115
|
-
|
|
116
|
-
git clone https://github.com/clawdreyhepburn/carapace.git
|
|
117
|
-
cd carapace
|
|
118
|
-
npm install
|
|
119
|
-
npx tsx test/harness.ts
|
|
120
|
-
# Open http://localhost:19820
|
|
121
|
-
```
|
|
199
|
+
Carapace has two modes. Pick one (or use both for defense in depth).
|
|
122
200
|
|
|
123
|
-
|
|
201
|
+
#### Option A: LLM Proxy (recommended — strongest protection)
|
|
124
202
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
},
|
|
144
|
-
"github": {
|
|
145
|
-
transport: "stdio",
|
|
146
|
-
command: "npx",
|
|
147
|
-
args: ["-y", "@modelcontextprotocol/server-github"],
|
|
148
|
-
env: { "GITHUB_TOKEN": "${GITHUB_TOKEN}" }
|
|
149
|
-
}
|
|
150
|
-
}
|
|
203
|
+
The proxy sits between your agent and the AI model. It holds the real API key, intercepts every tool call in the AI's response, and removes anything your policies don't allow. **The agent can't bypass this because it never has the real API key.**
|
|
204
|
+
|
|
205
|
+
Add these sections to your `~/.openclaw/openclaw.json`:
|
|
206
|
+
|
|
207
|
+
**1. Add the Carapace plugin** (under `plugins.entries`):
|
|
208
|
+
|
|
209
|
+
```json
|
|
210
|
+
"carapace": {
|
|
211
|
+
"enabled": true,
|
|
212
|
+
"config": {
|
|
213
|
+
"guiPort": 19820,
|
|
214
|
+
"defaultPolicy": "allow-all",
|
|
215
|
+
"proxy": {
|
|
216
|
+
"enabled": true,
|
|
217
|
+
"port": 19821,
|
|
218
|
+
"upstream": {
|
|
219
|
+
"anthropic": {
|
|
220
|
+
"apiKey": "sk-ant-your-real-api-key-here"
|
|
151
221
|
}
|
|
152
222
|
}
|
|
223
|
+
},
|
|
224
|
+
"servers": {
|
|
225
|
+
"filesystem": {
|
|
226
|
+
"transport": "stdio",
|
|
227
|
+
"command": "npx",
|
|
228
|
+
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/docs"]
|
|
229
|
+
}
|
|
153
230
|
}
|
|
154
231
|
}
|
|
155
232
|
}
|
|
156
233
|
```
|
|
157
234
|
|
|
158
|
-
|
|
235
|
+
For **OpenAI** models, use `"openai"` instead of `"anthropic"` in the upstream block.
|
|
159
236
|
|
|
160
|
-
|
|
237
|
+
**2. Run setup:**
|
|
161
238
|
|
|
162
239
|
```bash
|
|
163
240
|
openclaw carapace setup
|
|
241
|
+
openclaw gateway restart
|
|
164
242
|
```
|
|
165
243
|
|
|
166
|
-
This
|
|
244
|
+
This automatically:
|
|
245
|
+
- Points your LLM provider at the Carapace proxy (sets `models.providers.<provider>.baseUrl`)
|
|
246
|
+
- Denies built-in tools that would bypass Cedar (`exec`, `web_fetch`, `web_search`)
|
|
167
247
|
|
|
168
|
-
You
|
|
248
|
+
Your existing API key environment variable (`ANTHROPIC_API_KEY` / `OPENAI_API_KEY`) still works — the proxy replaces the auth header when forwarding. You don't need to move any keys around.
|
|
249
|
+
|
|
250
|
+
**3. Verify:**
|
|
169
251
|
|
|
170
252
|
```bash
|
|
253
|
+
curl http://127.0.0.1:19821/health
|
|
254
|
+
# Should return: {"ok":true,"stats":{"requests":0,...}}
|
|
255
|
+
|
|
171
256
|
openclaw carapace check
|
|
257
|
+
# Should return: ✅ No bypass vulnerabilities found.
|
|
172
258
|
```
|
|
173
259
|
|
|
174
|
-
|
|
260
|
+
#### Option B: Tool-level gating (without proxy)
|
|
175
261
|
|
|
176
|
-
|
|
262
|
+
If you don't want to proxy LLM traffic, just omit the `proxy` section from the config above. Then run:
|
|
177
263
|
|
|
178
|
-
|
|
264
|
+
```bash
|
|
265
|
+
openclaw carapace setup
|
|
266
|
+
openclaw gateway restart
|
|
267
|
+
```
|
|
179
268
|
|
|
180
|
-
|
|
269
|
+
This denies built-in tools (`exec`, `web_fetch`, `web_search`) so the agent must use Carapace's Cedar-gated versions instead.
|
|
181
270
|
|
|
182
|
-
|
|
271
|
+
> ⚠️ **Without the proxy, this relies on the agent using the right tools.** The proxy (Option A) is stronger because it's un-bypassable.
|
|
183
272
|
|
|
184
|
-
|
|
185
|
-
- **Toggle OFF** → creates a `forbid` policy for that tool
|
|
273
|
+
### Step 3: Open the dashboard
|
|
186
274
|
|
|
187
|
-
|
|
275
|
+
Go to [http://localhost:19820](http://localhost:19820) to see your tools, manage policies, and control access.
|
|
188
276
|
|
|
189
|
-
|
|
277
|
+
### Uninstalling
|
|
190
278
|
|
|
191
|
-
|
|
192
|
-
// Allow the agent to read files but not write them
|
|
193
|
-
permit(
|
|
194
|
-
principal is Jans::Workload,
|
|
195
|
-
action == Jans::Action::"call_tool",
|
|
196
|
-
resource == Jans::Tool::"filesystem/read_file"
|
|
197
|
-
);
|
|
279
|
+
Carapace modifies your OpenClaw config during setup (denying built-in tools, adding proxy baseUrl overrides). The uninstall command reverses all of it:
|
|
198
280
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
action == Jans::Action::"call_tool",
|
|
203
|
-
resource == Jans::Tool::"filesystem/write_file"
|
|
204
|
-
);
|
|
205
|
-
|
|
206
|
-
// Allow git and npm commands, block everything else
|
|
207
|
-
permit(
|
|
208
|
-
principal is Jans::Workload,
|
|
209
|
-
action == Jans::Action::"exec_command",
|
|
210
|
-
resource == Jans::Shell::"git"
|
|
211
|
-
);
|
|
212
|
-
permit(
|
|
213
|
-
principal is Jans::Workload,
|
|
214
|
-
action == Jans::Action::"exec_command",
|
|
215
|
-
resource == Jans::Shell::"npm"
|
|
216
|
-
);
|
|
217
|
-
|
|
218
|
-
// Allow API calls to GitHub, block all other domains
|
|
219
|
-
permit(
|
|
220
|
-
principal is Jans::Workload,
|
|
221
|
-
action == Jans::Action::"call_api",
|
|
222
|
-
resource == Jans::API::"api.github.com"
|
|
223
|
-
);
|
|
224
|
-
|
|
225
|
-
// Block a specific domain
|
|
226
|
-
forbid(
|
|
227
|
-
principal,
|
|
228
|
-
action == Jans::Action::"call_api",
|
|
229
|
-
resource == Jans::API::"evil.example.com"
|
|
230
|
-
);
|
|
231
|
-
|
|
232
|
-
// Allow everything (use with caution)
|
|
233
|
-
permit(
|
|
234
|
-
principal is Jans::Workload,
|
|
235
|
-
action,
|
|
236
|
-
resource
|
|
237
|
-
);
|
|
281
|
+
```bash
|
|
282
|
+
openclaw carapace uninstall
|
|
283
|
+
openclaw gateway restart
|
|
238
284
|
```
|
|
239
285
|
|
|
240
|
-
|
|
286
|
+
This will:
|
|
287
|
+
- Restore the built-in `exec`, `web_fetch`, and `web_search` tools (removes them from `tools.deny`)
|
|
288
|
+
- Remove the proxy baseUrl override so your provider connects directly to its API again
|
|
289
|
+
- Disable the Carapace plugin in config
|
|
241
290
|
|
|
242
|
-
|
|
291
|
+
To fully remove the plugin files:
|
|
243
292
|
|
|
244
|
-
|
|
293
|
+
```bash
|
|
294
|
+
rm -rf ~/.openclaw/extensions/carapace
|
|
295
|
+
```
|
|
245
296
|
|
|
246
|
-
|
|
297
|
+
### For development
|
|
247
298
|
|
|
248
|
-
|
|
299
|
+
```bash
|
|
300
|
+
git clone https://github.com/clawdreyhepburn/carapace.git
|
|
301
|
+
cd carapace
|
|
302
|
+
npm install
|
|
303
|
+
npx tsx test/harness.ts # Starts test servers + GUI on port 19820
|
|
304
|
+
```
|
|
249
305
|
|
|
250
|
-
|
|
306
|
+
---
|
|
251
307
|
|
|
252
|
-
|
|
253
|
-
- **Three resource types** — `Tool` (MCP tools), `Shell` (commands by binary name), `API` (outbound HTTP by domain). All go through the same Cedar engine.
|
|
254
|
-
- **Forbid always wins** — if any policy says `forbid`, the request is denied regardless of any `permit` policies. This is core Cedar semantics and prevents privilege escalation.
|
|
255
|
-
- **Allow-all by default** — installing Carapace doesn't break anything. All operations work until you add `forbid` policies. Switch to `deny-all` when you're ready for least-privilege.
|
|
256
|
-
- **Sub-millisecond evaluation** — WASM runs at near-native speed. Typical authorization decisions take <6ms.
|
|
308
|
+
## Quick Start
|
|
257
309
|
|
|
258
|
-
|
|
310
|
+
Once you've installed and configured Carapace (see [Installation](#installation) above), here's how to start using it.
|
|
259
311
|
|
|
260
|
-
|
|
261
|
-
|------|-------------|--------|-------|---------|
|
|
262
|
-
| MCP Tool | `Jans::Tool` | `call_tool` | Upstream MCP server calls | `Tool::"filesystem/write_file"` |
|
|
263
|
-
| Shell | `Jans::Shell` | `exec_command` | Local command execution | `Shell::"rm"`, `Shell::"git"` |
|
|
264
|
-
| API | `Jans::API` | `call_api` | Outbound HTTP requests | `API::"api.github.com"` |
|
|
312
|
+
### Write your first policy
|
|
265
313
|
|
|
266
|
-
|
|
314
|
+
Here's a common starting point — let the agent use development tools but block dangerous commands:
|
|
267
315
|
|
|
268
|
-
|
|
316
|
+
```cedar
|
|
317
|
+
// Allow git, ls, cat, grep
|
|
318
|
+
permit(principal is Jans::Workload, action == Jans::Action::"exec_command", resource == Jans::Shell::"git");
|
|
319
|
+
permit(principal is Jans::Workload, action == Jans::Action::"exec_command", resource == Jans::Shell::"ls");
|
|
320
|
+
permit(principal is Jans::Workload, action == Jans::Action::"exec_command", resource == Jans::Shell::"cat");
|
|
321
|
+
permit(principal is Jans::Workload, action == Jans::Action::"exec_command", resource == Jans::Shell::"grep");
|
|
322
|
+
|
|
323
|
+
// Block dangerous commands
|
|
324
|
+
forbid(principal, action == Jans::Action::"exec_command", resource == Jans::Shell::"rm");
|
|
325
|
+
forbid(principal, action == Jans::Action::"exec_command", resource == Jans::Shell::"sudo");
|
|
326
|
+
|
|
327
|
+
// Allow GitHub API, block data exfiltration sites
|
|
328
|
+
permit(principal is Jans::Workload, action == Jans::Action::"call_api", resource == Jans::API::"api.github.com");
|
|
329
|
+
forbid(principal, action == Jans::Action::"call_api", resource == Jans::API::"pastebin.com");
|
|
330
|
+
```
|
|
269
331
|
|
|
270
|
-
|
|
332
|
+
> 🔒 **Want the full security walkthrough?** See the [Security Hardening Guide](docs/SECURITY.md) — step-by-step instructions with copy-paste commands for macOS, Linux, and Windows.
|
|
333
|
+
>
|
|
334
|
+
> 📖 **Want more policy examples?** See [Recommended Policies](docs/RECOMMENDED-POLICIES.md) — ready-made policies for common scenarios like blocking credential access, preventing data exfiltration, and complete starter configurations for different agent roles.
|
|
271
335
|
|
|
272
|
-
|
|
336
|
+
---
|
|
273
337
|
|
|
274
|
-
|
|
338
|
+
## Design Philosophy
|
|
275
339
|
|
|
276
|
-
|
|
277
|
-
|----------|-------|------|----------|
|
|
278
|
-
| ✏️ Write | Orange | High | `write_file`, `edit_file`, `create_directory` |
|
|
279
|
-
| ⚡ Execute | Red | High | `toggle-logging`, `trigger-long-running-operation` |
|
|
280
|
-
| 🔍 Browse | Blue | Medium | `list_directory`, `search_files`, `get-env` |
|
|
281
|
-
| 📖 Read | Teal | Low | `read_file`, `echo`, `get-sum` |
|
|
340
|
+
**Installing Carapace should never break your agent.** The default is `allow-all` — everything works exactly as before. You get visibility first (see what tools exist, what's being called) and control second (add restrictions when you're ready).
|
|
282
341
|
|
|
283
|
-
The
|
|
342
|
+
The recommended progression:
|
|
284
343
|
|
|
285
|
-
|
|
344
|
+
1. **Install** → everything works, open the GUI and look around
|
|
345
|
+
2. **Observe** → see what tools your agent actually uses
|
|
346
|
+
3. **Forbid the scary stuff** → block `rm`, `sudo`, exfiltration domains
|
|
347
|
+
4. **Lock down** → switch to `deny-all` and explicitly permit only what's needed
|
|
286
348
|
|
|
287
|
-
|
|
349
|
+
Most people should stay at step 3. Step 4 is for when you really understand your agent's tool surface.
|
|
288
350
|
|
|
289
|
-
|
|
290
|
-
|----------|--------|-------------|
|
|
291
|
-
| `/api/status` | GET | Server status, all tools, all policies |
|
|
292
|
-
| `/api/tools` | GET | List tools (optional `?server=` filter) |
|
|
293
|
-
| `/api/toggle` | POST | Enable/disable a resource `{"tool": "...", "enabled": true, "type": "tool\|shell\|api"}` |
|
|
294
|
-
| `/api/policy` | POST | Create/update a policy `{"id": "...", "raw": "..."}` |
|
|
295
|
-
| `/api/policy` | DELETE | Delete a policy `{"id": "..."}` |
|
|
296
|
-
| `/api/policies` | GET | List all policies |
|
|
297
|
-
| `/api/schema` | GET | Get Cedar schema (parsed + raw) |
|
|
298
|
-
| `/api/schema` | POST | Update Cedar schema `{"raw": "..."}` |
|
|
299
|
-
| `/api/verify` | POST | Verify all policies |
|
|
351
|
+
---
|
|
300
352
|
|
|
301
353
|
## Security
|
|
302
354
|
|
|
303
|
-
###
|
|
304
|
-
|
|
305
|
-
Carapace is designed to protect against:
|
|
306
|
-
|
|
307
|
-
1. **Overprivileged agents** — An agent configured with access to 50 MCP tools but only needing 5. Start with allow-all (safe install), then use the GUI to lock down what you don't need. Switch to `deny-all` for full least-privilege.
|
|
308
|
-
|
|
309
|
-
2. **Privilege escalation via tool chaining** — An agent using a permitted tool to accomplish what a forbidden tool would do. Cedar's `forbid`-always-wins semantics help here: you can blanket-permit and then surgically forbid dangerous operations.
|
|
310
|
-
|
|
311
|
-
3. **Configuration drift** — Tool permissions accumulating over time without review. The GUI provides a single view of all permissions, and policies are stored as auditable files.
|
|
312
|
-
|
|
313
|
-
### What Carapace Does NOT Protect Against
|
|
314
|
-
|
|
315
|
-
- **Malicious MCP servers** — Carapace trusts the upstream MCP servers to behave as described. It does not sandbox server execution.
|
|
316
|
-
- **Argument-level validation** — Carapace authorizes *which* operation can be performed (which tool, which binary, which domain), not the specific arguments. Cedar conditions can add argument-level checks, but this requires custom policies.
|
|
317
|
-
- **Shell argument injection** — Carapace gates by binary name (`git`, `npm`), not by the full command line. An agent permitted to run `git` could run `git push --force`. Use Cedar `when` conditions on `context.args` for finer control.
|
|
318
|
-
- **Network-level attacks** — The GUI runs on localhost without authentication. See [GUI Security](#gui-security) below.
|
|
355
|
+
### What Carapace protects against
|
|
319
356
|
|
|
320
|
-
|
|
357
|
+
- **Overprivileged agents** — Your agent has access to 50 tools but only needs 5. Carapace lets you restrict the other 45.
|
|
358
|
+
- **Prompt injection** — Someone tricks your agent into running dangerous commands. If the policy says `rm` is forbidden, it doesn't matter what the prompt says.
|
|
359
|
+
- **Data exfiltration** — Your agent tries to send sensitive data to an external service. If the domain isn't permitted, the request is blocked.
|
|
360
|
+
- **Privilege escalation** — An agent tries to use one permitted tool to accomplish what a forbidden tool would do. Cedar's forbid-always-wins makes this harder.
|
|
321
361
|
|
|
322
|
-
|
|
362
|
+
### What Carapace does NOT protect against
|
|
323
363
|
|
|
324
|
-
|
|
364
|
+
- **Malicious MCP servers** — Carapace trusts the MCP servers themselves. If a server lies about what a tool does, Carapace can't detect that.
|
|
365
|
+
- **Argument-level abuse** — Carapace checks *which* command runs (e.g., `git`), not *how* it's used (e.g., `git push --force`). You can add argument-level checks with Cedar `when` conditions, but it's not automatic.
|
|
366
|
+
- **Permitted binary abuse** — If you permit `node`, the agent can run `node -e "require('child_process').execSync('rm -rf /')"`. Permitting a language runtime is effectively permitting everything. See [Dangerous Permits](docs/SECURITY.md#dangerous-permits).
|
|
367
|
+
- **Code that runs outside the LLM** — OpenClaw hooks and plugins run directly in the process, not through the AI model. Carapace can't gate those. See [Enforcement Coverage](docs/SECURITY.md#enforcement-coverage).
|
|
325
368
|
|
|
326
|
-
|
|
369
|
+
### GUI security
|
|
327
370
|
|
|
328
|
-
|
|
371
|
+
The dashboard runs on `localhost` only — it's not accessible from the network. There's no authentication on the API. **Do not expose port 19820 to the internet.** If you need remote access, use an SSH tunnel or an authenticated reverse proxy.
|
|
329
372
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
```bash
|
|
333
|
-
chmod 700 ~/.openclaw/mcp-policies/
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
### Cedar Schema Trust
|
|
337
|
-
|
|
338
|
-
The Cedar schema defines what entity types and actions exist. A modified schema could allow policies to be written that appear restrictive but are actually permissive due to type mismatches. Treat the schema file with the same care as the policies themselves.
|
|
373
|
+
---
|
|
339
374
|
|
|
340
375
|
## Configuration Reference
|
|
341
376
|
|
|
377
|
+
### Plugin config
|
|
378
|
+
|
|
342
379
|
| Property | Type | Default | Description |
|
|
343
380
|
|----------|------|---------|-------------|
|
|
344
|
-
| `guiPort` | number | `19820` | Port for the
|
|
345
|
-
| `servers` | object | `{}` |
|
|
346
|
-
| `policyDir` | string | `~/.openclaw/mcp-policies/` |
|
|
347
|
-
| `defaultPolicy` | `"
|
|
348
|
-
| `verify` | boolean | `false` |
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
381
|
+
| `guiPort` | number | `19820` | Port for the control dashboard |
|
|
382
|
+
| `servers` | object | `{}` | MCP servers to connect to (see Quick Start) |
|
|
383
|
+
| `policyDir` | string | `~/.openclaw/mcp-policies/` | Where Cedar policy files are stored |
|
|
384
|
+
| `defaultPolicy` | `"allow-all"` or `"deny-all"` | `"allow-all"` | Starting posture. `allow-all` is safe to install — nothing breaks. `deny-all` requires explicit permits for every tool. |
|
|
385
|
+
| `verify` | boolean | `false` | Validate policies on every change |
|
|
386
|
+
| `proxy.enabled` | boolean | `false` | Enable the LLM proxy |
|
|
387
|
+
| `proxy.port` | number | `19821` | Port for the LLM proxy |
|
|
388
|
+
| `proxy.upstream.anthropic.apiKey` | string | — | Your real Anthropic API key |
|
|
389
|
+
| `proxy.upstream.anthropic.url` | string | `https://api.anthropic.com` | Anthropic API base URL |
|
|
390
|
+
| `proxy.upstream.openai.apiKey` | string | — | Your real OpenAI API key |
|
|
391
|
+
| `proxy.upstream.openai.url` | string | `https://api.openai.com` | OpenAI API base URL |
|
|
392
|
+
|
|
393
|
+
### MCP server config
|
|
353
394
|
|
|
354
395
|
| Property | Type | Description |
|
|
355
396
|
|----------|------|-------------|
|
|
356
|
-
| `transport` | `"stdio"`
|
|
357
|
-
| `command` | string |
|
|
358
|
-
| `args` | string[] | Command arguments |
|
|
397
|
+
| `transport` | `"stdio"` | How to connect (stdio is currently supported) |
|
|
398
|
+
| `command` | string | Program to run |
|
|
399
|
+
| `args` | string[] | Command-line arguments |
|
|
359
400
|
| `env` | object | Environment variables |
|
|
360
|
-
|
|
401
|
+
|
|
402
|
+
### CLI commands
|
|
403
|
+
|
|
404
|
+
```bash
|
|
405
|
+
openclaw carapace setup # Configure OpenClaw (proxy baseUrl + deny bypass tools)
|
|
406
|
+
openclaw carapace check # Check for bypass vulnerabilities
|
|
407
|
+
openclaw carapace status # Show connected servers, tool counts, proxy status
|
|
408
|
+
openclaw carapace tools # List all tools with enabled/disabled status
|
|
409
|
+
openclaw carapace verify # Validate all policies
|
|
410
|
+
openclaw carapace uninstall # Reverse all config changes, restore built-in tools
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
---
|
|
361
414
|
|
|
362
415
|
## Development
|
|
363
416
|
|
|
@@ -366,87 +419,97 @@ git clone https://github.com/clawdreyhepburn/carapace.git
|
|
|
366
419
|
cd carapace
|
|
367
420
|
npm install
|
|
368
421
|
|
|
369
|
-
# Run the test harness (
|
|
422
|
+
# Run the test harness (2 MCP servers + GUI on port 19820)
|
|
370
423
|
npx tsx test/harness.ts
|
|
371
424
|
|
|
372
425
|
# Type check
|
|
373
426
|
npx tsc --noEmit
|
|
374
427
|
|
|
375
|
-
# Run
|
|
376
|
-
|
|
428
|
+
# Run the full test suite
|
|
429
|
+
npx tsx test/test-shell-gate.mjs # Shell gating (9 tests)
|
|
430
|
+
npx tsx test/test-llm-proxy.mjs # LLM proxy filtering (10 tests)
|
|
431
|
+
npx tsx test/test-adversarial.mjs # Adversarial bypass attempts (30+9 tests)
|
|
432
|
+
npx tsx test/test-block-myself.mjs # End-to-end cp block demo
|
|
377
433
|
```
|
|
378
434
|
|
|
379
|
-
### Project
|
|
435
|
+
### Project structure
|
|
380
436
|
|
|
381
437
|
```
|
|
382
438
|
carapace/
|
|
383
439
|
├── src/
|
|
384
|
-
│ ├── index.ts # OpenClaw plugin entry
|
|
385
|
-
│ ├──
|
|
386
|
-
│ ├── cedar-engine.ts
|
|
387
|
-
│ ├──
|
|
440
|
+
│ ├── index.ts # OpenClaw plugin entry — registers tools, services, CLI
|
|
441
|
+
│ ├── llm-proxy.ts # LLM proxy — intercepts tool calls in AI responses
|
|
442
|
+
│ ├── cedar-engine-cedarling.ts # Cedarling WASM engine — real Cedar 4.4.2 evaluation
|
|
443
|
+
│ ├── cedar-engine.ts # Fallback engine (string matching, no WASM needed)
|
|
444
|
+
│ ├── mcp-aggregator.ts # Connects to MCP servers, discovers tools, proxies calls
|
|
388
445
|
│ ├── types.ts # Shared TypeScript types
|
|
389
446
|
│ └── gui/
|
|
390
|
-
│ ├── server.ts # HTTP server for the
|
|
391
|
-
│ └── html.ts #
|
|
447
|
+
│ ├── server.ts # HTTP server for the dashboard
|
|
448
|
+
│ └── html.ts # Dashboard UI (single HTML file, no build step)
|
|
392
449
|
├── test/
|
|
393
|
-
│
|
|
394
|
-
├──
|
|
450
|
+
│ ├── harness.ts # Standalone test environment
|
|
451
|
+
│ ├── test-shell-gate.mjs # Shell command authorization tests
|
|
452
|
+
│ ├── test-llm-proxy.mjs # LLM proxy interception tests
|
|
453
|
+
│ ├── test-adversarial.mjs # Adversarial bypass test suite
|
|
454
|
+
│ └── test-block-myself.mjs # End-to-end demo: block cp, try to copy, get denied
|
|
395
455
|
├── docs/
|
|
396
|
-
│
|
|
456
|
+
│ ├── SECURITY.md # Security hardening (macOS/Linux/Windows)
|
|
457
|
+
│ ├── RECOMMENDED-POLICIES.md # Policy examples for common use cases
|
|
458
|
+
│ └── screenshots/ # Dashboard screenshots
|
|
397
459
|
├── LICENSE # Apache-2.0
|
|
398
|
-
├── NOTICE #
|
|
399
|
-
└──
|
|
460
|
+
├── NOTICE # Trademark notice
|
|
461
|
+
└── openclaw.plugin.json # OpenClaw plugin manifest
|
|
400
462
|
```
|
|
401
463
|
|
|
464
|
+
---
|
|
465
|
+
|
|
402
466
|
## Learn More
|
|
403
467
|
|
|
404
|
-
|
|
468
|
+
### Cedar for AI Agents — blog series
|
|
469
|
+
|
|
470
|
+
The ideas behind Carapace, explained step by step:
|
|
405
471
|
|
|
406
|
-
1. [
|
|
407
|
-
2. [
|
|
408
|
-
3. [
|
|
409
|
-
4. [
|
|
472
|
+
1. [Why Your AI Agent Needs a Policy Language](https://clawdrey.com/blog/cedar-for-ai-agents-part-1-why-your-ai-agent-needs-a-policy-language.html) — why config files aren't enough
|
|
473
|
+
2. [Writing Your First Agent Policy](https://clawdrey.com/blog/cedar-for-ai-agents-part-2-writing-your-first-agent-policy.html) — modeling agents, tools, and actions in Cedar
|
|
474
|
+
3. [When Forbid Meets Permit](https://clawdrey.com/blog/cedar-for-ai-agents-part-3-when-forbid-meets-permit.html) — why "forbid always wins" matters for safety
|
|
475
|
+
4. [Proving It: SMT Solvers and Why I Trust Math More Than Tests](https://clawdrey.com/blog/proving-it-smt-solvers-and-why-i-trust-math-more-than-tests.html) — formally verifying that policies are correct
|
|
410
476
|
|
|
411
|
-
More
|
|
477
|
+
More at [clawdrey.com](https://clawdrey.com).
|
|
412
478
|
|
|
413
|
-
|
|
479
|
+
### Built with
|
|
414
480
|
|
|
415
|
-
- **[Cedar](https://www.cedarpolicy.com/)** — Policy language by AWS.
|
|
416
|
-
- **[Cedarling](https://github.com/JanssenProject/jans/tree/main/jans-cedarling)** — Cedar
|
|
417
|
-
- **[MCP
|
|
418
|
-
- **[OpenClaw](https://github.com/openclaw/openclaw)** — Open-source AI agent
|
|
481
|
+
- **[Cedar](https://www.cedarpolicy.com/)** — Policy language by AWS. Human-readable rules with formal guarantees.
|
|
482
|
+
- **[Cedarling](https://github.com/JanssenProject/jans/tree/main/jans-cedarling)** — Cedar engine by [Gluu](https://gluu.org/), compiled to WebAssembly for speed.
|
|
483
|
+
- **[MCP](https://modelcontextprotocol.io/)** — Open protocol for connecting AI agents to tools.
|
|
484
|
+
- **[OpenClaw](https://github.com/openclaw/openclaw)** — Open-source AI agent platform.
|
|
485
|
+
|
|
486
|
+
---
|
|
419
487
|
|
|
420
488
|
## Contributors
|
|
421
489
|
|
|
422
|
-
<!-- ALL-CONTRIBUTORS-LIST:START -->
|
|
423
490
|
| Avatar | Name | Role |
|
|
424
491
|
|--------|------|------|
|
|
425
|
-
| <img src="https://github.com/
|
|
492
|
+
| <img src="https://github.com/ClawdreyHepburn.png" width="50"> | **Clawdrey Hepburn** ([@ClawdreyHepburn](https://x.com/ClawdreyHepburn)) | Creator, primary author |
|
|
426
493
|
| <img src="https://github.com/Sarahcec.png" width="50"> | **Sarah Cecchetti** ([@Sarahcec](https://github.com/Sarahcec)) | Co-creator, product direction |
|
|
427
494
|
| <img src="https://github.com/nynymike.png" width="50"> | **Michael Schwartz** ([@nynymike](https://github.com/nynymike)) | Cedarling / Gluu |
|
|
428
|
-
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
|
429
|
-
|
|
430
|
-
## License
|
|
431
|
-
|
|
432
|
-
Copyright 2026 Clawdrey Hepburn LLC. All rights reserved.
|
|
433
495
|
|
|
434
|
-
|
|
496
|
+
---
|
|
435
497
|
|
|
436
|
-
|
|
498
|
+
## License
|
|
437
499
|
|
|
438
|
-
|
|
500
|
+
Copyright 2026 Clawdrey Hepburn LLC. Licensed under [Apache-2.0](LICENSE).
|
|
439
501
|
|
|
440
|
-
|
|
502
|
+
**"Carapace"** is a trademark of Clawdrey Hepburn LLC. See [NOTICE](NOTICE).
|
|
441
503
|
|
|
442
|
-
###
|
|
504
|
+
### Attribution
|
|
443
505
|
|
|
444
|
-
|
|
445
|
-
- "**Powered by Carapace**" — great for technical documentation
|
|
446
|
-
- "**Built with Carapace**" — great for project READMEs
|
|
447
|
-
- "**Uses Carapace for MCP tool authorization**" — great for blog posts
|
|
506
|
+
Using Carapace? Here's how to reference it:
|
|
448
507
|
|
|
449
|
-
|
|
508
|
+
- ✅ "**Protected by Carapace**" — for badges and footers
|
|
509
|
+
- ✅ "**Powered by Carapace**" — for technical docs
|
|
510
|
+
- ✅ "**Built with Carapace**" — for project READMEs
|
|
511
|
+
- ❌ ~~"Made by Carapace"~~ — implies we're liable for what your agent does
|
|
512
|
+
- ❌ ~~"Certified by Carapace"~~ — we don't certify anything
|
|
450
513
|
|
|
451
514
|
```markdown
|
|
452
515
|

|
|
@@ -454,18 +517,12 @@ We'd love for you to tell people you use Carapace! Here's how to reference it co
|
|
|
454
517
|
|
|
455
518
|

|
|
456
519
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
- ~~"**Made by Carapace**"~~ — Carapace is a policy engine, not a manufacturer. This implies liability on our part for what your agent does.
|
|
460
|
-
- ~~"**Certified by Carapace**"~~ — We don't certify anything. Carapace enforces policies you write.
|
|
461
|
-
- ~~"**Carapace-approved**"~~ — Same issue. The policies are yours; the enforcement is ours.
|
|
462
|
-
|
|
463
|
-
**The distinction matters:** Carapace enforces *your* policies. You are responsible for writing good policies. We are responsible for evaluating them correctly.
|
|
520
|
+
**You write the policies. We enforce them.**
|
|
464
521
|
|
|
465
522
|
---
|
|
466
523
|
|
|
467
524
|
<p align="center">
|
|
468
|
-
<em>A carapace is the hard upper shell of a crustacean — an immutable boundary that
|
|
525
|
+
<em>A carapace is the hard upper shell of a crustacean — an immutable boundary that protects the creature inside.</em>
|
|
469
526
|
</p>
|
|
470
527
|
<p align="center">
|
|
471
528
|
<strong>Your agent's exoskeleton.</strong>
|