Skip to main content
A sandbox is the execution session an agent or a sandbox_exec preset runs code in. The sandbox slot is a scalar single holder: install exactly one provider, and which one you install is the execution mode. The consuming agents keep one code path either way. Each provider’s full setup — its <PREFIX>_* settings and its engine contract — lives on its own plugin page under the Plugins section: plugins/tai42/sandbox-docker and plugins/tai42/sandbox-local. This page is the operator narrative that gets you to them.

Install and wire sandbox-docker

Install the provider, name its sandbox_module in the manifest, and point it at an engine:
  • Set SANDBOX_DOCKER_HOST to the engine: a unix:///var/run/... socket path, a bare socket path, or a tcp://host:port endpoint (also written http:// or https://). A network host that names no port is dialled on 2376 over TLS (under mTLS, or an https:// host) and on 2375 when dialled plain. A Windows named pipe (npipe://), a unix:// that names no socket path, and any other form are refused.
  • Mount the mTLS client certificates at the fixed path /certs/client (a volume mount, not an env var).
  • No TAI_MCP_SANDBOX selector is needed — installing the plugin patches the sandbox_module in.
  • A session image must provide sh, the setsid, mkfifo, mv, rm, cat, kill, readlink, ls and sleep commands (sleep taking a fractional time), /proc, and a writable /tmp: every command runs under a small shell wrapper that starts it in a process group of its own and records its process id in /tmp, so a stop can kill that group, and a stop looks through /proc for a process that still holds the command’s output. An image without a shell cannot run any command. The image needs no init of its own: the session container runs the engine’s init as its main process.

Install and wire sandbox-local

sandbox-local runs the agent’s code directly on the host, with no isolation.
  • Name the sandbox_module, then set SANDBOX_LOCAL_ROOT to the host workspace root. A persistent session lives at <SANDBOX_LOCAL_ROOT>/<workspace_key>.
  • It provides isolation none only and rejects a container or vm isolation floor. A deployment that keeps the default sandbox_isolation="container" must lower the floor to none to run under it.
  • It keeps a small shell process in each command’s process group so a stop still reaches what the command started. For an interactive command it keeps that shell until kill() or the session’s teardown, so a consumer done with a handle calls kill(). The shell ends when the provider lets the group go, and the init process (PID 1) reaps it. The published image runs tai under tini, so tini reaps it. A container that runs the server itself as PID 1 needs an init: docker run --init, or an init as the entrypoint.
sandbox-local runs the code on the host with no isolation. The code holds the credentials the operator injects into the session and, under the default open egress, reaches the full host network. Lower sandbox_isolation to none deliberately, and tighten sandbox_egress if the workload does not need the internet.
Both agents’ session_image settings stay required and digest-validated under sandbox-local, but they are inert: the host is the environment, so the value is only recorded in session labels and never pulled. Any well-formed ...@sha256: digest reference satisfies them — for example the published image’s own digest, even though it is never used.

Running claude_code direct-on-host

Running claude_code under sandbox-local requires the operator to install the Claude runtime on the host first — the claude-agent-sdk wheel (it bundles the Claude Code CLI, no separate Node.js) — because the shipped server image stays lean and only the container sandbox carries the runtime out of the box. langchain_deep_agent needs no extra runtime direct-on-host. Under sandbox-docker both agents run from the pinned session image with nothing extra to install.

The engine under Compose and Kubernetes

Under Compose the engine is opt-in: the profiles: ["sandbox"] engine on a sandbox-ctrl control network. A session is an inner container of the rootless-dind daemon — NAT’d out for internet egress only, never on the deployment network, and unable to address serve, the backend, the datastores, or the engine itself. On Kubernetes, run the engine as its own workload (its privilege isolated to the engine pod, the app pod untouched) or point the provider at an external endpoint.

Durability

An ephemeral session’s scratch dies with it. A persistent session binds the durable tai-sbx-<workspace_key> volume.
A persistent session needs real, node-independent block storage from the distribution layer — a PVC on Kubernetes, a named volume in Compose. Without it, a session’s data does not survive a node move.

Security posture

The engine control endpoint is code-execution authority. Keep it behind mTLS, never bare.
Egress defaults open, so tool-result data is exfiltratable under it. The hardening path — a tighter network level plus an Anthropic-only proxy — is offered, not forced. An in-session model credential lives for the session lifetime.
Set SANDBOX_DOCKER_READINESS_PROBE_ENABLED to have the provider PROVE, on every session create, that the engine’s egress firewall is in force before it returns a session — a throwaway probe container on the egress tier that must not reach the engine control address and must reach its own resolver — and refuse the create loudly when it cannot. It is defense in depth for the window an engine restart opens under a running app; the engine’s own healthcheck-gated start order remains the primary guarantee. See the sandbox-docker plugin page for the SANDBOX_DOCKER_READINESS_* settings.
The platform tools an agent uses are adapter-proxied: the agent uses exactly the tool_names the caller grants, executed under the run’s own identity, with no credential or MCP endpoint exposed to the session. There is no scoped mount or key to configure for them. (The sandbox_exec contrast — code that runs inside the session with the injected credentials — is on the sandbox concept page.)

See also

  • Sandbox — the contract, isolation floor, and durability model.
  • Use the ready-made agents — claude_code and langchain_deep_agent, the shipped sandbox-driving agents.
  • Plugins — the sandbox-docker and sandbox-local plugin pages and their full engine setup.