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)
  • openshell CLI present on PATH (alternatively, a custom location via plugins.entries.openshell.config.command)
  • OpenSSH client installed on the Gateway host
  • OpenShell v0.0.88 or 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, and apply_patch act 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

mirrorremote
Canonical workspaceLocal hostRemote OpenShell
Sync directionBidirectional (every exec)One-time seed
Per-turn overheadHigher (upload + download)Lower (direct remote ops)
Local edits visible?Yes, on next execNo, until recreate
Best forDevelopment workflowsLong-running agents, CI

Configuration reference

Every piece of OpenShell configuration is stored under plugins.entries.openshell.config:

KeyTypeDefaultDescription
mode"mirror" or "remote""mirror"How the workspace syncs
commandstring"openshell"The openshell CLI's path or name
fromstring"openclaw"Source used for the sandbox when it is first created
gatewaystringunsetGateway name for OpenShell (top-level --gateway)
gatewayEndpointstringunsetGateway endpoint for OpenShell (top-level --gateway-endpoint)
workspacestringunsetExisting control-plane workspace used by OpenShell for every CLI call
policystringunsetPolicy ID OpenShell applies when creating sandboxes
providersstring[][]Providers attached on sandbox creation (deduplicated, each entry gets one --provider flag)
gpubooleanfalseAsk for GPU resources (--gpu)
autoProvidersbooleantrueSupply --auto-providers during create (or --no-auto-providers when false)
remoteWorkspaceDirstring"/sandbox"Main writable workspace located inside the sandbox
remoteAgentWorkspaceDirstring"/agent"Where the agent workspace is mounted (read-only unless workspace access is rw)
timeoutSecondsnumber120How 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.backend
  • plugins.entries.openshell.config.from
  • plugins.entries.openshell.config.mode
  • plugins.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/sh
  • python3 or python for pinned write, edit, rename, and remove operations
  • GNU-compatible stat and find
  • standard mkdir, mv, rm, and rmdir utilities

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.binds does not apply to OpenShell; sandbox creation fails if binds are configured.
  • Docker-specific runtime knobs under sandbox.docker.* (other than env) 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

  1. OpenClaw runs sandbox get for 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 with sandbox create, passing --name, --from, --policy when set, --gpu when enabled, --auto-providers/--no-auto-providers, and one --provider flag per configured provider.
  2. OpenClaw runs sandbox ssh-config for the sandbox name to fetch SSH connection details.
  3. 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.
  4. In mirror mode: sync local to remote before exec, run, sync back after.
  5. In remote mode: seed once on create, then operate directly on the remote workspace.
1,730 words · updated Aug 10, 2026