-
Notifications
You must be signed in to change notification settings - Fork 3k
Expand file tree
/
Copy pathopenclaw-sandbox.yaml
More file actions
233 lines (218 loc) · 9.87 KB
/
Copy pathopenclaw-sandbox.yaml
File metadata and controls
233 lines (218 loc) · 9.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Default policy for the OpenClaw sandbox.
# Principle: deny by default, allow only what's needed for core functionality.
# Dynamic updates (network_policies, inference) can be applied post-creation
# via `openshell policy set`. Static fields are effectively creation-locked.
#
# Policy tiers (future):
# default — this file. Minimum for onboard + basic agent operation.
# relaxed — adds third-party model providers, broader web access.
#
# To add endpoints: update this file and re-run `nemoclaw onboard`
# or apply dynamically via `openshell policy set`.
version: 1
filesystem_policy:
# Home directory writable (matches Hermes). Agents can create dotfiles,
# caches, etc. natively. Immutability is opt-in via `shields up` (DAC +
# chattr only — Landlock can't be toggled at runtime).
include_workdir: true
read_only:
- /usr
- /lib
- /proc
- /dev/urandom
- /app
- /run/nemoclaw/managed-startup-ca-bundle.pem
- /etc
- /var/log
- /var/lib/dpkg # Allow package-version inspection without package mutation.
read_write:
- /tmp
- /dev/null
- /dev/pts # PTY multiplexer + slave devices (devpts).
# OpenClaw's bundled tmux-session flow — and
# any PTY allocation (tmux, script, expect,
# interactive shells) — opens /dev/ptmx
# (-> /dev/pts/ptmx) and a /dev/pts/<n> slave
# via forkpty(). Without this grant landlock
# denies the open with EACCES, which tmux
# surfaces as `create window failed: fork
# failed: Permission denied` (#4513). Grant
# the directory, not /dev/ptmx itself — the
# supervisor refuses to chown that symlink.
- /sandbox/.openclaw # Agent config (lockable via shields up)
- /sandbox/.nemoclaw # Plugin state and config (state.ts, config.ts).
# Blueprints are root-owned; sticky bit (1755)
# on parent prevents rename/delete (#1607).
- /home/linuxbrew # Homebrew prefix. The brew core is baked into
# the sandbox base image at /home/linuxbrew/
# .linuxbrew (#3913); runtime writes here let
# `brew install <formula>` extract bottles
# and manage Cellar/opt symlinks.
# TODO: evaluate landlock enforce mode — currently best_effort because
# enforce can break things in unpredictable ways. Needs thorough testing
# across different kernel versions before we flip this. (ref #516 item 3)
landlock:
compatibility: best_effort
# Note: tool-level write/edit restrictions for openclaw.json are intentionally
# NOT declared here. OpenShell's PolicyFile schema does not support a
# `tool_policy` section (serde deny_unknown_fields — only version, filesystem_policy,
# landlock, process, network_policies are accepted). Config protection when
# shields are up is achieved via DAC (444 root:root) and chattr +i.
# Ref: https://github.com/NVIDIA/NemoClaw/pull/654#pullrequestreview-…
process:
run_as_user: sandbox
run_as_group: sandbox
network_policies:
nvidia:
name: nvidia
endpoints:
- host: integrate.api.nvidia.com
port: 443
protocol: rest
enforcement: enforce
rules:
- allow: { method: POST, path: "/v1/chat/completions" }
- allow: { method: POST, path: "/v1/completions" }
- allow: { method: POST, path: "/v1/embeddings" }
- allow: { method: GET, path: "/v1/models" }
- allow: { method: GET, path: "/v1/models/**" }
binaries:
- { path: /usr/local/bin/openclaw }
# ── Managed inference route ──────────────────────────────────────────
# inference.local is the OpenShell gateway's internal virtual hostname;
# the gateway proxies it to the configured provider (OpenAI, NVIDIA, etc.).
# Every sandbox uses this route regardless of provider, so it belongs in
# the base policy rather than an optional preset.
# Ref: https://github.com/NVIDIA/NemoClaw/issues/2663
managed_inference:
name: managed_inference
endpoints:
- host: inference.local
port: 443
protocol: rest
enforcement: enforce
rules:
- allow: { method: GET, path: "/**" }
- allow: { method: POST, path: "/**" }
binaries:
- { path: /usr/local/bin/openclaw }
- { path: /usr/local/bin/node }
- { path: /usr/bin/node }
- { path: /usr/bin/curl }
- { path: /usr/bin/python3 }
# ── Gateway dial-back (sessions_spawn) ──────────────────────────────
# Spawned sub-agent runtimes connect back to the OpenClaw gateway over
# WebSocket at OPENCLAW_GATEWAY_URL. The L7 proxy intercepts traffic
# from the enforced process tree even on the sandbox's own interfaces,
# and loopback destinations are always-blocked regardless of policy —
# so the dial must target the sandbox's eth0 address (the gateway
# listens on 0.0.0.0; nemoclaw-start.sh derives the URL host
# accordingly). Raw L4 tunnel (`access: full, tls: skip`): a
# `protocol: rest` endpoint would terminate/inspect HTTP and break the
# 101 WebSocket upgrade. Without this entry every sessions_spawn child
# fails its gateway connection with `1006 abnormal closure (no close
# frame)` and multi-agent delegation is unusable.
#
# Defaults cover the standard sandbox bridge address (10.200.0.2) and
# both common gateway ports (18789 default, 18790 NemoClaw onboard).
# A custom NEMOCLAW_PROXY_HOST subnet or NEMOCLAW_DASHBOARD_PORT needs
# a matching `openshell policy update`.
openclaw_gateway_dialback:
name: openclaw_gateway_dialback
endpoints:
- host: 10.200.0.2
port: 18789
access: full
tls: skip
allowed_ips:
# SSRF guard rejects private resolved addresses unless
# explicitly allowlisted (same pattern as local-inference).
- 10.200.0.2
- host: 10.200.0.2
port: 18790
access: full
tls: skip
allowed_ips:
- 10.200.0.2
binaries:
- { path: /usr/local/bin/openclaw }
- { path: /usr/local/bin/node }
- { path: /usr/bin/node }
# NOTE: github.com / api.github.com and the git/gh binaries used to
# live in this base policy and were therefore granted to every
# sandbox regardless of user opt-in. They have been moved into a
# discoverable preset (`presets/github.yaml`) so a sandbox only gets
# GitHub access when the user explicitly selects the `github` preset
# during onboard. See #1583.
# ── OpenClaw "phone home" ────────────────────────────────────────────
# Minimum viable set for OpenClaw to authenticate, discover plugins,
# and reach ClawHub. Restricted to openclaw and node (skill flows run on Node).
# Docs access is read-only (GET). ClawHub and openclaw.ai are
# restricted to GET+POST (auth flows, plugin discovery).
clawhub:
name: clawhub
endpoints:
- host: clawhub.ai
port: 443
protocol: rest
enforcement: enforce
# ClawHub addresses scoped packages as @scope%2Fname. Keep strict
# canonicalization everywhere else while allowing that registry form.
# TODO(#4104): Remove if ClawHub stops encoding scope separators or
# OpenShell can preserve this route without an endpoint-level opt-in.
allow_encoded_slash: true
rules:
- allow: { method: GET, path: "/**" }
- allow: { method: POST, path: "/**" }
binaries:
- { path: /usr/local/bin/openclaw }
- { path: /usr/local/bin/node }
openclaw_api:
name: openclaw_api
endpoints:
- host: openclaw.ai
port: 443
protocol: rest
enforcement: enforce
rules:
- allow: { method: GET, path: "/**" }
- allow: { method: POST, path: "/**" }
binaries:
- { path: /usr/local/bin/openclaw }
- { path: /usr/local/bin/node }
openclaw_docs:
name: openclaw_docs
endpoints:
- host: docs.openclaw.ai
port: 443
protocol: rest
enforcement: enforce
rules:
- allow: { method: GET, path: "/**" }
binaries:
- { path: /usr/local/bin/openclaw }
# npm registry — needed for `openclaw plugins install` only.
# Restricted to the openclaw binary so agents cannot use npm directly.
# Users who need npm/node access should add the npm policy preset during onboard.
# Ref: https://github.com/NVIDIA/NemoClaw/issues/1458
npm_registry:
name: npm_registry
endpoints:
- host: registry.npmjs.org
port: 443
protocol: rest
enforcement: enforce
rules:
- allow: { method: GET, path: "/**" }
binaries:
- { path: /usr/local/bin/openclaw }
# Messaging endpoints (telegram, discord, slack) are intentionally NOT in
# the baseline — #1705 removed them so every sandbox does not silently
# egress to third-party IM platforms without user opt-in. The messaging
# presets (presets/{telegram,discord,slack}.yaml) are the opt-in path:
# users enable a channel in step [5/8] of onboard and the matching preset
# is applied on top of this baseline. Keep this comment so the entries
# are not casually re-added during a merge-conflict resolution. See #2180.