OpenShell Sandbox Backend for OpenClaw Agents
Learn how to configure OpenShell as a managed sandbox backend for OpenClaw agents, including prerequisites and setup steps. This guide is for developers seeking remote sandboxing via SSH.
Read this when
- You want OpenShell-managed local or remote sandboxes
- You are setting up the OpenShell plugin
- You need to choose between mirror and remote workspace modes
OpenShell functions as a managed sandbox backend. Rather than spinning up Docker containers on your local machine, OpenClaw hands off sandbox lifecycle duties to the openshell CLI, which provisions remote environments and runs commands through SSH.
The same SSH transport and remote filesystem bridge used by the generic SSH backend are reused by this plugin, which also layers on OpenShell lifecycle management (sandbox create/get/delete/ssh-config) and an optional mirror workspace sync mode.
Prerequisites
- The OpenShell plugin must be installed (
openclaw plugins install @openclaw/openshell-sandbox) openshellCLI present onPATH(alternatively, a custom location viaplugins.entries.openshell.config.command)- OpenSSH client installed on the Gateway host
- OpenShell
v0.0.88or a newer release when an OpenShell workspace is being configured - An OpenShell account that has sandbox access enabled
- OpenClaw Gateway running on the host machine
Quick start
openclaw plugins install @openclaw/openshell-sandbox
{
agents: {
defaults: {
sandbox: {
mode: "all",
backend: "openshell",
scope: "session",
workspaceAccess: "rw",
},
},
},
plugins: {
entries: {
openshell: {
enabled: true,
config: {
from: "openclaw",
mode: "remote",
},
},
},
},
}
After restarting the Gateway, OpenClaw will create an OpenShell sandbox on the next agent turn and direct tool execution through it. You can confirm this with:
openclaw sandbox list
openclaw sandbox explain
Workspace modes
This choice carries the most weight for OpenShell.
A separate control-plane resource called a workspace also exists within OpenShell. It is distinct from the filesystem workspace covered below: it governs sandbox scoping, providers, policies, inference routes, and membership. To point at an existing non-default OpenShell workspace, set plugins.entries.openshell.config.workspace. Workspace creation and membership management are not handled by the plugin. If this setting remains unset, the plugin keeps whatever ambient OPENSHELL_WORKSPACE selection the OpenShell CLI has, falling back to the CLI's default when no ambient selection is present.
mirror (default)
With plugins.entries.openshell.config.mode: "mirror", the local workspace stays authoritative:
- A sync of the local workspace into the sandbox happens before
exec. - After
exec, the remote workspace is synced back to local. - File tools route through the sandbox bridge, yet local remains the source of truth between turns.
This suits development workflows: edits made locally outside OpenClaw appear on the following exec, and sandbox behavior closely mirrors the Docker backend.
The downside: every exec turn incurs both upload and download costs.
remote
Under mode: "remote", the OpenShell workspace becomes authoritative:
- When the sandbox is first created, OpenClaw does a one-time seed of the remote workspace from local.
- From that point on,
exec,read,write,edit, andapply_patchact directly on the remote workspace. No sync of remote changes back to local is performed by OpenClaw. - Media reads at prompt time still function, since file and media tools read through the sandbox bridge.
Ideal for long-running agents and CI: per-turn overhead drops, and host-local edits cannot silently overwrite remote state.
Warning
After the initial seed, host-side edits made outside OpenClaw remain invisible to the remote sandbox. To re-seed, run
openclaw sandbox recreate.
Choosing a mode
mirror | remote | |
|---|---|---|
| Canonical workspace | Local host | Remote OpenShell |
| Sync direction | Bidirectional (every exec) | One-time seed |
| Per-turn overhead | Higher (upload + download) | Lower (direct remote ops) |
| Local edits visible? | Yes, on next exec | No, until recreate |
| Best for | Development workflows | Long-running agents, CI |
Configuration reference
Every piece of OpenShell configuration is stored under plugins.entries.openshell.config:
| Key | Type | Default | Description |
|---|---|---|---|
mode | "mirror" or "remote" | "mirror" | How the workspace syncs |
command | string | "openshell" | The openshell CLI's path or name |
from | string | "openclaw" | Source used for the sandbox when it is first created |
gateway | string | unset | Gateway name for OpenShell (top-level --gateway) |
gatewayEndpoint | string | unset | Gateway endpoint for OpenShell (top-level --gateway-endpoint) |
workspace | string | unset | Existing control-plane workspace used by OpenShell for every CLI call |
policy | string | unset | Policy ID OpenShell applies when creating sandboxes |
providers | string[] | [] | Providers attached on sandbox creation (deduplicated, each entry gets one --provider flag) |
gpu | boolean | false | Ask for GPU resources (--gpu) |
autoProviders | boolean | true | Supply --auto-providers during create (or --no-auto-providers when false) |
remoteWorkspaceDir | string | "/sandbox" | Main writable workspace located inside the sandbox |
remoteAgentWorkspaceDir | string | "/agent" | Where the agent workspace is mounted (read-only unless workspace access is rw) |
timeoutSeconds | number | 120 | How long openshell CLI operations may take |
Both remoteWorkspaceDir and remoteAgentWorkspaceDir need to be absolute paths, and they have to fall
within the managed roots /sandbox or /agent. Any other absolute path gets
turned away.
workspace has to follow OpenShell's current naming rules for workspaces: 1-19
lowercase alphanumeric characters or single hyphens, with no hyphen at the
start, end, or in a row. Create it beforehand with
openshell workspace create --name <name>. If the chosen workspace is missing or in the middle of deletion,
OpenShell blocks sandbox actions. Use "default" to explicitly override an
ambient non-default Workspace.
This setting governs every OpenShell sandbox this plugin instance manages; you cannot assign different OpenShell workspaces per OpenClaw agent or session. Switching it does not move existing sandboxes. Remove OpenClaw's OpenShell sandboxes while the old workspace is still in place, then apply the new setting and restart the Gateway.
Sandbox-level options (mode, scope, workspaceAccess) sit under
agents.defaults.sandbox just like any other backend. The full matrix is in
Sandboxing.
Examples
Minimal remote setup
{
agents: {
defaults: {
sandbox: {
mode: "all",
backend: "openshell",
},
},
},
plugins: {
entries: {
openshell: {
enabled: true,
config: {
from: "openclaw",
mode: "remote",
},
},
},
},
}
Mirror mode with GPU
{
agents: {
defaults: {
sandbox: {
mode: "all",
backend: "openshell",
scope: "agent",
workspaceAccess: "rw",
},
},
},
plugins: {
entries: {
openshell: {
enabled: true,
config: {
from: "openclaw",
mode: "mirror",
gpu: true,
providers: ["openai"],
timeoutSeconds: 180,
},
},
},
},
}
Per-agent OpenShell with custom gateway
{
agents: {
defaults: {
sandbox: { mode: "off" },
},
entries: {
researcher: {
default: true,
sandbox: {
mode: "all",
backend: "openshell",
scope: "agent",
workspaceAccess: "rw",
},
},
},
},
plugins: {
entries: {
openshell: {
enabled: true,
config: {
from: "openclaw",
mode: "remote",
gateway: "lab",
gatewayEndpoint: "https://lab.example",
workspace: "research",
policy: "strict",
},
},
},
},
}
Lifecycle management
# List all sandbox runtimes (Docker + OpenShell)
openclaw sandbox list
# Inspect effective policy
openclaw sandbox explain
# Recreate (deletes remote workspace, re-seeds on next use)
openclaw sandbox recreate --all
Recreate carries special weight in remote mode: it removes the canonical remote workspace tied to that scope, and the subsequent use pulls a fresh one from local. In mirror mode, recreate mostly resets the remote execution environment, since local remains the source of truth.
After an upgrade, OpenClaw keeps the registered sandbox's shipped legacy runtime name so the remote workspace stays reachable. Recreating that scope wipes the legacy runtime; the next use generates the current 19-character runtime name.
OpenShell v0.0.92 can still locate a sandbox record from v0.0.68, but a Docker-backed sandbox might stay in a non-Ready phase after the gateway upgrade. OpenClaw preserves the registered runtime identity, declines to create a replacement implicitly, and reports the scoped openclaw sandbox recreate command. In remote mode, treat that recreation as destructive because the remote workspace holds canonical data.
Recreate after modifying any of:
agents.defaults.sandbox.backendplugins.entries.openshell.config.fromplugins.entries.openshell.config.modeplugins.entries.openshell.config.policy
Security hardening
The mirror-mode filesystem bridge pins the local workspace root and rechecks canonical paths (via realpath) before each read, write, mkdir, remove, and rename, rejecting symlinks in the middle of a path. A symlink swap or remounted workspace cannot redirect file access outside the mirrored tree.
Custom image contract
The OpenShell source image controls the remote operating system and package set. OpenClaw does not apply Docker image, root-filesystem, network, user, or package settings to this backend.
Custom images used with the OpenClaw filesystem bridge must include:
/bin/shpython3orpythonfor pinned write, edit, rename, and remove operations- GNU-compatible
statandfind - standard
mkdir,mv,rm, andrmdirutilities
Package installation and private certificate roots must be baked into the source image or installed from inside the sandbox. The selected OpenShell policy must allow the required network destinations, and the sandbox user and filesystem must permit the writes. sandbox.docker.network, sandbox.docker.readOnlyRoot, sandbox.docker.user, and sandbox.docker.setupCommand do not configure OpenShell.
Current limitations
- Sandbox browser is unsupported on the OpenShell backend.
- One plugin instance uses one OpenShell workspace; per-agent or per-session OpenShell workspace selection is unsupported.
sandbox.docker.bindsdoes not apply to OpenShell; sandbox creation fails if binds are configured.- Docker-specific runtime knobs under
sandbox.docker.*(other thanenv) apply only to the Docker backend. - Native plugin code and Gateway RPC stay on the Gateway host. Plugin-owned and MCP tools are available to sandboxed sessions only when sandbox tool policy allows them.
How it works
- OpenClaw runs
sandbox getfor the sandbox name (with the selected OpenShell workspace and any configured--gateway/--gateway-endpoint); if that fails, it creates one in the same OpenShell workspace withsandbox create, passing--name,--from,--policywhen set,--gpuwhen enabled,--auto-providers/--no-auto-providers, and one--providerflag per configured provider. - OpenClaw runs
sandbox ssh-configfor the sandbox name to fetch SSH connection details. - Core writes the SSH config to a temp file and opens an SSH session through the same remote filesystem bridge as the generic SSH backend.
- In
mirrormode: sync local to remote before exec, run, sync back after. - In
remotemode: seed once on create, then operate directly on the remote workspace.
Related
- Sandboxing - modes, scopes, and backend comparison
- Sandbox vs Tool Policy vs Elevated - debugging blocked tools
- Multi-Agent Sandbox and Tools - per-agent overrides
- Sandbox CLI -
openclaw sandboxcommands