docs/gateway/sandbox-vs-tool-policy-vs-elevated.md
OpenClaw has three related (but different) controls:
agents.defaults.sandbox.* / agents.list[].sandbox.*) decides where tools run (sandbox backend vs host).tools.*, tools.sandbox.tools.*, agents.list[].tools.*) decides which tools are available/allowed.tools.elevated.*, agents.list[].tools.elevated.*) is an exec-only escape hatch to run outside the sandbox when you’re sandboxed (gateway by default, or node when the exec target is configured to node).Use the inspector to see what OpenClaw is actually doing:
openclaw sandbox explain
openclaw sandbox explain --session agent:main:main
openclaw sandbox explain --agent work
openclaw sandbox explain --json
It prints:
Sandboxing is controlled by agents.defaults.sandbox.mode:
"off": everything runs on the host."non-main": only non-main sessions are sandboxed (common “surprise” for groups/channels)."all": everything is sandboxed.See Sandboxing for the full matrix (scope, workspace mounts, images).
docker.binds pierces the sandbox filesystem: whatever you mount is visible inside the container with the mode you set (:ro or :rw).:ro for source/secrets.scope: "shared" ignores per-agent binds (only global binds apply)./workspace/alias-out/new-file resolves through a symlinked parent to a blocked path or outside the configured allowed roots, the bind is rejected./var/run/docker.sock effectively hands host control to the sandbox; only do this intentionally.workspaceAccess: "ro"/"rw") is independent of bind modes.Two layers matter:
tools.profile and agents.list[].tools.profile (base allowlist)tools.byProvider[provider].profile and agents.list[].tools.byProvider[provider].profiletools.allow/tools.deny and agents.list[].tools.allow/agents.list[].tools.denytools.byProvider[provider].allow/deny and agents.list[].tools.byProvider[provider].allow/denytools.sandbox.tools.allow/tools.sandbox.tools.deny and agents.list[].tools.sandbox.tools.*Rules of thumb:
deny always wins.allow is non-empty, everything else is treated as blocked./exec cannot override a denied exec tool./exec only changes session defaults for authorized senders; it does not grant tool access.
Provider tool keys accept either provider (e.g. google-antigravity) or provider/model (e.g. openai/gpt-5.4).Tool policies (global, agent, sandbox) support group:* entries that expand to multiple tools:
{
tools: {
sandbox: {
tools: {
allow: ["group:runtime", "group:fs", "group:sessions", "group:memory"],
},
},
},
}
Available groups:
group:runtime: exec, process, code_execution (bash is accepted as
an alias for exec)group:fs: read, write, edit, apply_patchgroup:sessions: sessions_list, sessions_history, sessions_send, sessions_spawn, sessions_yield, subagents, session_statusgroup:memory: memory_search, memory_getgroup:web: web_search, x_search, web_fetchgroup:ui: browser, canvasgroup:automation: cron, gatewaygroup:messaging: messagegroup:nodes: nodesgroup:agents: agents_listgroup:media: image, image_generate, video_generate, ttsgroup:openclaw: all built-in OpenClaw tools (excludes provider plugins)Elevated does not grant extra tools; it only affects exec.
/elevated on (or exec with elevated: true) runs outside the sandbox (approvals may still apply)./elevated full to skip exec approvals for the session.host=auto; it follows the normal exec target rules and only preserves node when the configured/session target is already node./exec is separate from elevated. It only adjusts per-session exec defaults for authorized senders.Gates:
tools.elevated.enabled (and optionally agents.list[].tools.elevated.enabled)tools.elevated.allowFrom.<provider> (and optionally agents.list[].tools.elevated.allowFrom.<provider>)See Elevated Mode.
Fix-it keys (pick one):
agents.defaults.sandbox.mode=off (or per-agent agents.list[].sandbox.mode=off)tools.sandbox.tools.deny (or per-agent agents.list[].tools.sandbox.tools.deny)tools.sandbox.tools.allow (or per-agent allow)In "non-main" mode, group/channel keys are not main. Use the main session key (shown by sandbox explain) or switch mode to "off".