Skip to content

Security Hardening (Part Two): Tool Permissions and the Sandbox ​

One-sentence goal: change agents that handle untrusted content from "full access by default" to "least privilege + manual approval + OpenClaw sandbox," so that high-risk tools simply cannot be invoked.

Prerequisites ​

Follow Along ​

Step 1: Deny high-risk tools by default ​

For any agent or surface that will touch untrusted content, add a deny list to the configuration:

json5
{
  tools: {
    deny: ["gateway", "cron", "sessions_spawn", "sessions_send"],
  },
}

The rationale comes from the official documentation: gateway can read configuration (potentially exposing secrets and host topology), trigger updates, restarts, and cleanup of rollback copies; scheduled tasks created by cron keep running after the original session ends; sessions_spawn and sessions_send involve cross-session spawning and message passing.

Expected result: when this agent invokes these four tools, it is rejected outright, without even entering the approval flow.

Step 2: Close the restart and update command entry points ​

Set commands.restart to false in the configuration to seal things off at the command level as well:

json5
{
  commands: {
    restart: false,
  },
}

Expected result: /restart, /update, gateway update/restart actions from external chats, and external SIGUSR2 restart requests all stop working. Note: cleanup does not stop the Gateway and does not depend on this switch; it goes through the owner/operator and tool policy gates.

Step 3: Put restricted runs inside the OpenClaw sandbox ​

The OpenClaw sandbox is off by default: if you do not configure agents.defaults.sandbox (global) or agents.entries.*.sandbox (per agent), tool execution runs directly on the host machine. Once enabled, the Gateway process still stays on the host; only tool execution is moved into the sandbox backend. The officials also state plainly that this is not a perfect security boundary, but it can substantively limit the model's access to the file system and processes when it does something foolish.

First add a minimal enabling configuration:

json5
{
  agents: {
    defaults: {
      sandbox: {
        mode: "non-main",        // 群/渠道等非主会话进沙箱
        scope: "session",        // 沙箱环境按会话隔离
        workspaceAccess: "none", // 沙箱对 agent workspace 无访问权限
      },
    },
  },
}

Only want to enable it for a specific agent that touches untrusted content? Write the same sandbox block under agents.entries.<id>.sandbox.

Keep the relationship between the two layers clear: tool policy takes effect before sandbox rules, so the tools denied in Step 1 do not come back to life just because they are inside the sandbox; conversely, tools.elevated is an explicit escape hatch that lets exec execute outside the sandbox — do not enable it for this kind of agent.

Sandbox and approval also stack: set the agent's session permission mode to restricted (i.e., read-only, guarded, workspace — any non-Full Access mode), and persistent configuration or lifecycle changes it requests require manual approval; changes allowed under Full Access (including Default) execute directly without approval.

The four categories of restrictions — tools, file system, sandbox, and operations — are independent of one another and stack; the host also re-validates live permissions before execution.

@@I18N_KEEP_000022@@ sandbox backends include docker, podman, ssh, openshell, crabbox, and others; the specific configuration options and isolation levels of each backend were not within the scope of this collection, so refer to the corresponding sandbox pages on docs.openclaw.ai (docs/gateway/sandboxing/ and its subpages) as authoritative.

Once configured, use the CLI to confirm the sandbox is actually in effect:

bash
openclaw sandbox list                         # 列出沙箱容器、状态与对应会话/agent
openclaw sandbox explain --agent <agent-id>   # 查看生效的沙箱模式、workspace 与工具策略

Expected result: this agent's tool execution happens inside the sandbox, with its access to the host file system and processes restricted; when it requests persistent configuration or lifecycle changes, a manual approval prompt appears; openclaw sandbox list shows the corresponding sandbox container. Even if one layer of restriction is bypassed, the remaining layers still hold.

Verify ​

Try each item in turn:

  1. Have a restricted agent invoke gateway to read the configuration → rejected outright by the deny list.
  2. Send /restart → a message says it is disabled, or there is no response.
  3. Have a restricted agent request a persistent configuration change → a manual approval prompt appears instead of direct execution.
  4. Have the agent execute a tool once in a group/channel session (for example, fetch a web page), then run openclaw sandbox list → its sandbox container and status appear in the list.

Common Pitfalls ​

  • Treating deny as "needs approval": deny is a hard rejection; approval only happens within what restricted mode allows — do not mix them up.
  • Thinking that turning off commands.restart locks down updates: maintenance actions such as cleanup do not depend on this switch, do not stop the Gateway, and are still gated by owner/operator and tool policy.
  • Feeling safe because the agent defaults to Full Access: changes allowed under Full Access (including Default) do not trigger approval; the deny list from Step 1 is the real hard boundary.
  • Thinking that enabling the sandbox means you can remove the deny list: tool policy takes effect before sandbox rules, so denied tools do not come back just because of the sandbox; the tools.elevated escape hatch even lets exec run directly outside the sandbox. Do not remove the hard denials from Step 1 just because "there's a sandbox anyway."

Next Lesson ​

Tool permissions govern "what Claw can do," and the OpenClaw sandbox governs "where it runs and what it can touch"; the next lesson Security Hardening (Part Three): Prompt Injection Defense and Security Auditing turns to "what content can goad Claw into doing."