On this page
๐ก๏ธ Why sandbox?
Without sandboxing, OpenClaw tools (exec, filesystem, browser) run directly on your host. If the AI hallucinates a destructive command โ rm -rf /, delete a database, overwrite config โ it happens on your actual system.
Sandboxing runs tool execution inside Docker containers. The gateway stays on the host; only tool execution is isolated. This is not perfect security, but it materially limits filesystem and process access.
๐ How it works
โโโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Gateway (Host) โ โ Sandbox Container โ
โ โโโโโโบโ โ
โ - AI model calls โ โ - exec (shell commands) โ
โ - Session management โ โ - filesystem read/write โ
โ - Channel routing โ โ - browser (optional) โ
โ โโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Host stays safe Damage contained here
Tools sandboxed: exec, read, write, edit, apply_patch, process, and optionally the browser.
โ๏ธ Sandbox modes
| Mode | What's sandboxed | Use case |
|---|---|---|
off | Nothing (default) | Trusted, single-user setup |
"non-main" | Sub-agents + cron sessions | Protect host from automated tasks |
"all" | All sessions including main | Maximum isolation |
{
"agents": {
"defaults": {
"sandbox": {
"mode": "non-main"
}
}
}
}
โ
Recommended: Start with "non-main". This sandboxes sub-agents and cron jobs (automated, less trusted) while keeping your main interactive session on the host (faster, full access).
๐ Configuration
{
"agents": {
"defaults": {
"sandbox": {
"mode": "non-main",
"docker": {
"image": "openclaw-sandbox:bookworm-slim",
"network": "none",
"readOnlyRoot": true,
"user": "1000:1000",
"workspaceAccess": "rw",
"binds": [],
"env": {}
}
}
}
}
}
Build the sandbox image
# Build once (required before enabling sandbox)
openclaw sandbox build
# Or manually:
docker build -t openclaw-sandbox:bookworm-slim \
-f ~/.openclaw/sandbox/Dockerfile .
โ ๏ธ The default image doesn't include Node.js. If skills need Node (or other runtimes), bake a custom image or use setupCommand.
๐ Network isolation
By default, sandbox containers have no network access (network: "none").
| Setting | Access | Use case |
|---|---|---|
"none" | No network (default, safest) | File processing, code analysis |
"bridge" | Docker bridge network | Skills that need API access |
"host" | Full host network | โ ๏ธ Defeats isolation purpose |
# Allow network for skills that need API calls
{
"sandbox": {
"docker": {
"network": "bridge"
}
}
}
โ ๏ธ Package installs fail with network: "none". If using setupCommand to install packages, you need "bridge" during setup.
๐ Bind mounts
Mount host directories into the sandbox:
{
"sandbox": {
"docker": {
"binds": [
"/home/user/source:/source:ro",
"/var/data/myapp:/data:ro"
]
}
}
}
Security rules:
- OpenClaw blocks dangerous sources:
docker.sock,/etc,/proc,/sys,/dev - Use
:rofor read-only access wherever possible - Sensitive mounts (SSH keys, secrets) should always be
:ro - Global and per-agent binds are merged (not replaced)
- Under
scope: "shared", per-agent binds are ignored
๐ Browser sandboxing
The browser tool can also run in a separate sandboxed container:
{
"agents": {
"defaults": {
"sandbox": {
"browser": {
"enabled": true,
"autoStart": true,
"autoStartTimeoutMs": 30000
}
}
}
}
}
- Sandbox browser uses a dedicated Docker network (
openclaw-sandbox-browser) browser.bindsoverridesdocker.bindsfor the browser container specifically- Browser auto-starts when the browser tool first needs it
๐ง Setup command
Run a one-time setup command when the sandbox container is created:
{
"sandbox": {
"docker": {
"setupCommand": "apt-get update && apt-get install -y python3 git",
"network": "bridge",
"readOnlyRoot": false,
"user": "0:0"
}
}
}
Pitfalls:
network: "none"โ package installs fail (no network)readOnlyRoot: trueโ writes fail (can't install)user: "1000:1000"โ no sudo access for installs (use"0:0")- Runs once after creation, not on every run
- Sandbox exec does not inherit host
process.envโ usedocker.envfor API keys
๐ Per-agent overrides
{
"agents": {
"defaults": {
"sandbox": { "mode": "all" }
},
"list": [
{
"id": "main",
"sandbox": { "mode": "off" }
},
{
"id": "public-bot",
"sandbox": {
"mode": "all",
"docker": {
"network": "none",
"readOnlyRoot": true,
"binds": []
}
}
},
{
"id": "coding",
"sandbox": {
"docker": {
"binds": ["/mnt/projects:/projects:rw"]
}
}
}
]
}
}
Pattern: main agent unsandboxed (trusted), public bot fully locked down, coding agent with project access.
๐ง Troubleshooting
| Problem | Fix |
|---|---|
| Sandbox image not found | Run openclaw sandbox build first. |
| Package install fails | Set network: "bridge", readOnlyRoot: false, user: "0:0". |
| Skill API key not available | Sandbox doesn't inherit host env. Add keys to docker.env. |
| Filesystem writes blocked | Check readOnlyRoot and workspaceAccess settings. |
| Container won't start | Check Docker is running: docker info. Check disk space. |
| Bind mount permission denied | Check host directory permissions. Use user: "0:0" for root access. |
dangerouslyAllowContainerNamespaceJoin | Break-glass only. Required for network: "container:<id>". Avoid if possible. |