Skip to content

How to Sandbox Your AI Tools with OpenClaw

OpenClaw is designed to keep your host system safe by isolating potentially risky operations through sandboxing. This ensures that even if a model makes a mistake or attempts an unauthorized action, your primary filesystem and processes remain protected.

  1. Tool execution for commands like exec, read, write, edit, apply_patch, and process are all handled within the sandbox.
  2. You can also enable an optional sandboxed browser by configuring agents.defaults.sandbox.browser.
  3. By default, the sandbox browser starts up automatically to ensure the CDP is reachable when a tool needs it, which you can manage via agents.defaults.sandbox.browser.autoStart and agents.defaults.sandbox.browser.autoStartTimeoutMs.
  4. These browser containers use a dedicated Docker network named openclaw-sandbox-browser rather than the standard bridge network, though you can customize this with agents.defaults.sandbox.browser.network.
  5. If you need to restrict access further, agents.defaults.sandbox.browser.cdpSourceRange allows you to set a CIDR allowlist for CDP ingress.
  6. For security, noVNC observer access is password-protected; OpenClaw provides a short-lived token URL that opens a local page and passes the password in the URL fragment to keep it out of logs.
  7. You can allow sandboxed sessions to explicitly target your host browser using the agents.defaults.sandbox.browser.allowHostControl setting.
  8. If you use target: "custom", you can control access using allowlists like allowedControlUrls, allowedControlHosts, and allowedControlPorts.

There are a few things that stay outside the sandbox:

  1. The Gateway process itself always runs on your host machine.
  2. Any tool you have specifically allowed to run outside the sandbox, such as those in tools.elevated.
  3. Elevated exec operations bypass the sandbox entirely and use your configured escape path, which defaults to gateway or node.
  4. If you have sandboxing turned off, tools.elevated doesn’t change how things run since they are already on the host. You can read more about this in the Elevated Mode documentation.

You can decide exactly when OpenClaw should trigger a sandbox by adjusting the agents.defaults.sandbox.mode setting. This gives you the flexibility to keep your main chats fast while protecting other sessions that might be more unpredictable.

  1. Setting the mode to "off" means no sandboxing will be used at all.
  2. The "non-main" setting sandboxes only sessions that aren’t your primary ones; this is the default and is great if you want your regular host chats to stay local.
  3. Choosing "all" ensures that every single session, regardless of its origin, runs inside a sandbox.
  4. Keep in mind that "non-main" is based on the session.mainKey (which defaults to "main"); because group or channel sessions use their own unique keys, they are treated as non-main and will be sandboxed.

The agents.defaults.sandbox.scope setting determines how many Docker containers or isolated environments OpenClaw spins up. This helps you balance your system’s resource usage against the level of isolation you need between different tasks.

  1. The "agent" scope is the default and creates one dedicated container for each agent you use.
  2. The "session" scope provides the highest isolation by creating a unique container for every single session.
  3. The "shared" scope is the most resource-efficient, using one single container that all your sandboxed sessions share.

OpenClaw supports multiple runtimes through the agents.defaults.sandbox.backend configuration. You can choose the one that best fits your infrastructure, whether you want to run things locally or offload them to a remote server.

  1. The "docker" backend is the default choice and uses a local Docker runtime to manage your containers.
  2. The "ssh" backend allows you to use any remote host that you can access via SSH.
  3. The "openshell" backend utilizes the OpenShell managed sandbox runtime for more advanced workflows.

You can find specific SSH configurations under agents.defaults.sandbox.ssh, while OpenShell settings are located in plugins.entries.openshell.config.

DockerSSHOpenShell
Where it runsLocal containerAny SSH-accessible hostOpenShell managed sandbox
Setupscripts/sandbox-setup.shSSH key + target hostOpenShell plugin enabled
Workspace modelBind-mount or copyRemote-canonical (seed once)mirror or remote
Network controldocker.network (default: none)Depends on remote hostDepends on OpenShell
Browser sandboxSupportedNot supportedNot supported yet
Bind mountsdocker.bindsN/AN/A
Best forLocal dev, full isolationOffloading to a remote machineManaged remote sandboxes with optional two-way sync

If you enable sandboxing without picking a specific backend, OpenClaw defaults to Docker. It communicates with the local Docker daemon socket at /var/run/docker.sock to execute your tools and manage sandbox browsers.

If you are running the OpenClaw Gateway itself as a Docker container, you are using a setup known as Docker-out-of-Docker (DooD), which has a few important constraints:

  1. Your openclaw.json workspace configuration must use the absolute path from the Host machine, not the internal path inside the Gateway container.
  2. You must maintain FS Bridge Parity, which means your Gateway deployment needs a volume map that links the host namespace natively (for example, -v /home/user/.openclaw:/home/user/.openclaw).
  3. If you don’t match these paths, OpenClaw will throw an EACCES permission error because it won’t be able to find the correct location to write its heartbeat and bridge files.

The "ssh" backend is the way to go when you want OpenClaw to sandbox tool execution and file reads on a completely separate machine. This is a remote-canonical model, meaning the remote machine becomes the real state of your workspace.

{
agents: {
defaults: {
sandbox: {
mode: "all",
backend: "ssh",
scope: "session",
workspaceAccess: "rw",
ssh: {
target: "user@gateway-host:22",
workspaceRoot: "/tmp/openclaw-sandboxes",
strictHostKeyChecking: true,
updateHostKeys: true,
identityFile: "~/.ssh/id_ed25519",
certificateFile: "~/.ssh/id_ed25519-cert.pub",
knownHostsFile: "~/.ssh/known_hosts",
// Or use SecretRefs / inline contents instead of local files:
// identityData: { source: "env", provider: "default", id: "SSH_IDENTITY" },
// certificateData: { source: "env", provider: "default", id: "SSH_CERTIFICATE" },
// knownHostsData: { source: "env", provider: "default", id: "SSH_KNOWN_HOSTS" },
},
},
},
},
}
  1. OpenClaw creates a remote root directory based on your sandbox.ssh.workspaceRoot for each scope.
  2. On the first use, OpenClaw seeds that remote workspace by copying your local workspace files over once.
  3. After that, tools like exec, read, write, and edit run directly against the remote workspace over SSH.
  4. OpenClaw does not automatically sync any changes made on the remote machine back to your local workspace.
  5. For authentication, you can use local files like identityFile or provide raw data via identityData, which will take priority.
  6. Any edits you make locally on your host after the initial seed won’t be visible on the remote side until you run openclaw sandbox recreate.
  7. Note that browser sandboxing and sandbox.docker.* settings are not supported when using the SSH backend.

If you want to use OpenShell to manage your remote environments, set your backend to "openshell". This backend reuses the SSH transport but adds specialized lifecycle management and workspace syncing options. You can find more details on the OpenShell page.

{
agents: {
defaults: {
sandbox: {
mode: "all",
backend: "openshell",
scope: "session",
workspaceAccess: "rw",
},
},
},
plugins: {
entries: {
openshell: {
enabled: true,
config: {
from: "openclaw",
mode: "remote", // mirror | remote
remoteWorkspaceDir: "/sandbox",
remoteAgentWorkspaceDir: "/agent",
},
},
},
},
}
  1. In mirror mode, your local workspace remains the source of truth, and OpenClaw syncs files back and forth before and after tool execution.
  2. In remote mode, the OpenShell workspace becomes the source of truth after an initial seed from your local files.
  3. OpenClaw automatically handles the SSH configuration by requesting it from OpenShell via the CLI.
  4. Currently, browser sandboxing and Docker bind mounts are not supported in this backend.

The choice between mirror and remote is the most significant part of working with OpenShell. It determines how your local files interact with the remote sandbox.

  1. Use mirror if you want your local workspace to stay canonical and reflect all changes made in the sandbox immediately after a tool runs.
  2. Use remote if you want to treat the OpenShell environment as the primary workspace and reduce the overhead of syncing files on every turn.
  3. If you choose remote and edit files locally on your host, those changes will not be seen by the sandbox unless you recreate it.
  4. Running openclaw sandbox recreate will delete the remote workspace and re-seed it from your local files the next time it is used.

You can manage your OpenShell sandboxes using the same standard commands you use for Docker sandboxes. The Gateway handles the backend-specific logic behind the scenes.

  1. You can see all your active runtimes, including OpenShell, by running openclaw sandbox list.
  2. If you need to reset an environment, openclaw sandbox recreate will delete the current runtime so it can be rebuilt.
  3. The system’s pruning logic is fully aware of the backend, ensuring that old or unused sandboxes are cleaned up correctly.

You can control exactly what your agent sees by configuring OpenClaw workspace access settings. This ensures your environment stays secure while giving the agent the files it needs to work.

The agents.defaults.sandbox.workspaceAccess setting determines the visibility of your files:

  1. "none" (default): Tools see a sandbox workspace located under ~/.openclaw/sandboxes.
  2. "ro": This mounts the agent workspace as read-only at /agent, which automatically disables tools like write, edit, and apply_patch.
  3. "rw": This mounts the agent workspace with read and write permissions at /workspace.

If you are using the OpenShell backend, these rules still apply:

  1. In mirror mode, the local workspace remains the canonical source between execution turns.
  2. In remote mode, the remote OpenShell workspace becomes the canonical source after the initial seed.
  3. Setting workspaceAccess to "ro" or "none" will restrict write behavior in the same way.
  4. Any inbound media you use is copied directly into the active sandbox workspace at media/inbound/*.

Regarding skills, the read tool is rooted in the sandbox. If you set access to "none", OpenClaw mirrors eligible skills into the sandbox workspace at .../skills so they can be read. If you use "rw", your workspace skills are readable from /workspace/skills.

If you need to share specific host folders with your agent, you can set up custom Docker bind mounts. This allows for flexible data sharing between your local machine and the sandbox environment.

The agents.defaults.sandbox.docker.binds setting allows you to mount extra host directories into the container using the host:container:mode format, such as "/home/user/source:/source:rw".

  1. Global and per-agent binds are merged together rather than being replaced.
  2. If you use scope: "shared", any per-agent binds are ignored.
  3. You can use agents.defaults.sandbox.browser.binds to mount directories specifically for the sandbox browser container.
  4. When you set this (even as an empty list []), it replaces the standard Docker binds for the browser. If you omit it, the browser container uses the default agents.defaults.sandbox.docker.binds for backward compatibility.

Here is an example of how to configure a read-only source and an extra data directory in your JSON configuration:

{
agents: {
defaults: {
sandbox: {
docker: {
binds: ["/home/user/source:/source:ro", "/var/data/myapp:/data:ro"],
},
},
},
list: [
{
id: "build",
sandbox: {
docker: {
binds: ["/mnt/cache:/cache:rw"],
},
},
},
],
},
}
  1. Keep in mind that the default image does not include Node.js. If a skill needs Node.js or other runtimes, you should either create a custom image or install them via sandbox.docker.setupCommand. This requires network egress, a writable root, and the root user.
  2. If you want a more functional sandbox image that includes common tools like curl, jq, Node.js, python3, and git, you should build this version instead:
Terminal window
scripts/sandbox-common-setup.sh
  1. After building it, set your agents.defaults.sandbox.docker.image configuration to openclaw-sandbox-common:bookworm-slim.
  2. To set up the sandboxed browser image, run this script:
Terminal window
scripts/sandbox-browser-setup.sh
  1. By default, Docker sandbox containers run with no network access. You can change this by overriding the agents.defaults.sandbox.docker.network setting.

The bundled sandbox browser image uses specific Chromium startup defaults to keep containerized workloads stable. These defaults include:

  1. --remote-debugging-address=127.0.0.1
  2. --remote-debugging-port=<derived from OPENCLAW_BROWSER_CDP_PORT>
  3. --user-data-dir=${HOME}/.chrome
  4. --no-first-run
  5. --no-default-browser-check
  6. --disable-3d-apis
  7. --disable-gpu
  8. --disable-dev-shm-usage
  9. --disable-background-networking
  10. --disable-extensions
  11. --disable-features=TranslateUI
  12. --disable-breakpad
  13. --disable-crash-reporter
  14. --disable-software-rasterizer
  15. --no-zygote
  16. --metrics-recording-only
  17. --renderer-process-limit=2
  18. --no-sandbox and --disable-setuid-sandbox when noSandbox is enabled.

The three graphics hardening flags (--disable-3d-apis, --disable-software-rasterizer, and --disable-gpu) are optional and are useful when containers lack GPU support. You should set OPENCLAW_BROWSER_DISABLE_GRAPHICS_FLAGS=0 if your workload requires WebGL or other 3D features. Additionally, --disable-extensions is enabled by default, but you can disable it with OPENCLAW_BROWSER_DISABLE_EXTENSIONS=0 for flows that rely on extensions. You can also control the renderer process limit by setting OPENCLAW_BROWSER_RENDERER_PROCESS_LIMIT=<N>, where 0 keeps the Chromium default.

If you require a different runtime profile, you should use a custom browser image and provide your own entrypoint. For local Chromium profiles that are not in a container, use browser.extraArgs to add additional startup flags.

Security is handled with these defaults:

  1. Both network: "host" and network: "container:<id>" are blocked by default to prevent security risks like namespace join bypass.
  2. You can use a break-glass override by setting agents.defaults.sandbox.docker.dangerouslyAllowContainerNamespaceJoin: true if necessary.

You can find Docker installs and the containerized Gateway at Docker. For Docker Gateway deployments, the scripts/docker/setup.sh script can help bootstrap your sandbox configuration. Set OPENCLAW_SANDBOX=1 (or true, yes, or on) to enable that path. You can also override the socket location with OPENCLAW_DOCKER_SOCKET. You can find the full setup and environment reference at Docker.

Use setupCommand for One-Time OpenClaw Container Configuration

Section titled “Use setupCommand for One-Time OpenClaw Container Configuration”

The setupCommand is a tool that runs exactly once after your sandbox container is created, rather than on every run. It executes inside the container using sh -lc to prepare the environment.

You can configure these paths:

  1. Global configuration: agents.defaults.sandbox.docker.setupCommand
  2. Per-agent configuration: agents.list[].sandbox.docker.setupCommand

When using this feature, you should be aware of these common pitfalls:

  1. The default docker.network is set to "none", which means there is no egress and package installs will fail.
  2. Using docker.network: "container:<id>" requires you to set dangerouslyAllowContainerNamespaceJoin: true and should only be used as a break-glass option.
  3. If readOnlyRoot is set to true, it prevents any writes; you must set readOnlyRoot: false or use a custom image.
  4. The user must be root for package installs, so you should either omit the user field or set it to user: "0:0".
  5. The sandbox execution does not inherit environment variables from the host process.env. You should use agents.defaults.sandbox.docker.env or a custom image to manage your skill API keys.

Manage OpenClaw tool policy and escape hatches

Section titled “Manage OpenClaw tool policy and escape hatches”

You need to understand how OpenClaw tool policy and sandbox rules work together to keep your setup safe. Even if you have sandbox rules active, the tool allow or deny policies always take priority first.

If a tool is denied globally or for a specific agent, the sandbox cannot bring it back. You can use tools.elevated as an explicit escape hatch to run exec outside the sandbox. By default, this uses the Gateway, or it uses Node.js when the exec target is set to node. Keep in mind that /exec directives only work for authorized senders and stay active for that session. If you want to completely disable exec, you should use the tool policy deny settings. You can find more details on this in the Sandbox vs Tool Policy vs Elevated guide.

If you need to debug your setup, follow these steps:

  1. Use the CLI command openclaw sandbox explain to check your current sandbox mode, tool policy, and fix-it configuration keys.
  2. Review the Sandbox vs Tool Policy vs Elevated documentation to understand the mental model of why a specific action might be blocked.
Terminal window
openclaw sandbox explain

It is always best to keep your environment locked down as much as possible.

When you are running multiple agents, you might want different security levels for each one. OpenClaw lets you define specific overrides so each agent has exactly the permissions it needs.

Each agent in your list can have its own settings for the sandbox and tools. You can configure these using agents.list[].sandbox and agents.list[].tools. If you need to set a specific tool policy within a sandbox for an agent, use agents.list[].tools.sandbox.tools. To understand which rules take priority when you have multiple layers of configuration, check out the Multi-Agent Sandbox & Tools documentation.

Enable OpenClaw Sandbox with a Minimal Config

Section titled “Enable OpenClaw Sandbox with a Minimal Config”

Setting up a secure environment for your agents is straightforward when you use the right defaults. You can activate the OpenClaw sandbox features by defining a basic structure in your configuration file to ensure your environment stays isolated.

  1. Locate the agents section in your JSON or configuration file.
  2. Insert the defaults key if it isn’t already there to manage global settings for all your agents.
  3. Apply the sandbox configuration with mode set to "non-main" and workspaceAccess set to "none".
  4. Save your changes to enable the session-based isolation for your workflows.
{
agents: {
defaults: {
sandbox: {
mode: "non-main",
scope: "session",
workspaceAccess: "none",
},
},
},
}

Explore More OpenClaw Sandbox Documentation

Section titled “Explore More OpenClaw Sandbox Documentation”

Once you have the basics running, you might want to look into more advanced setups for your Gateway. These links cover everything from specific OpenShell backends to complex security policies that help you manage how tools interact with your system.

  1. OpenShell — managed sandbox backend setup, workspace modes, and config reference
  2. Sandbox Configuration
  3. Sandbox vs Tool Policy vs Elevated — debugging “why is this blocked?”
  4. Multi-Agent Sandbox & Tools — per-agent overrides and precedence
  5. Security
Terminal window
scripts/sandbox-setup.sh
OpenClaw

OpenClaw Expert

Still stuck?

If this page didn't answer your case, ask OpenClaw Expert for step-by-step guidance.