Skip to main content

Docker Sandboxes — Integration Reference

Specter Agent supports Docker Sandboxes as a preferred execution runtime over raw Codex CLI. When sbx is installed and healthy, Specter routes agent tasks through isolated microVM sandboxes instead of running Codex directly on the host.

Privacy guarantee: your source code and data never leave your machine. All sandboxes run locally in a microVM on your host. No code is uploaded to Docker, Anthropic, OpenAI, or any Specter server as part of execution.

Official references:


What Docker Sandboxes Is​

Docker Sandboxes runs coding agents (Codex, Claude Code, Cursor, Gemini CLI, Copilot CLI, Kiro, and others) inside disposable microVM environments. Each sandbox:

  • Has a hard hypervisor-level boundary from the host
  • Mounts only the project workspace — nothing else from the host filesystem
  • Gets its own isolated Docker daemon (no access to the host Docker daemon)
  • Can install packages, run services, and modify files without touching the host
  • Is ephemeral — deleted after the task completes

This makes it safe to run agents in --dangerously-skip-permissions / unattended mode without risk to the host machine.

Docker Desktop is not required. The sbx CLI is a standalone install.

Linux is not yet supported (macOS and Windows only as of mid-2026).


Installation​

# macOS
brew install docker/tap/sbx

# Windows
winget install Docker.sbx

Authentication​

sbx requires a Docker account (free tier works). You must sign in once — the session persists until it expires, after which you re-run sbx login.

# Sign in to Docker (opens browser)
sbx login

Then authenticate each agent's credentials inside sandboxes:

# Codex (OpenAI)
sbx secret set -g openai --oauth

# Cursor
sbx secret set -g cursor

Claude Code — one-time interactive login​

Claude Code uses a subscription OAuth token that cannot be extracted as a static API key. Instead, you need to log in once interactively inside an sbx sandbox:

# Open an interactive Claude Code sandbox
sbx run --name claude-login claude /path/to/any-project

# Inside the sandbox, run:
/login

Follow the browser OAuth flow. Once complete, exit the sandbox — credentials are stored in the sbx secret store and persist across all future Specter runs. You will not need to repeat this unless you reset your sbx secrets.

If a Specter sandbox test returns "Claude Code sandbox requires a one-time login", this is the step you need to complete.

Alternative: if you have an Anthropic API key (not subscription), you can use: sbx secret set -g anthropic and enter the key — no interactive login needed.

You only need to authenticate the agents you intend to use.

Session expiry: if the Specter Models page shows daemon_unavailable or the sandbox status turns red unexpectedly, run sbx diagnose in your terminal. If it reports "not signed in", run sbx login — the daemon is still running, only your Docker auth token has expired.


Sandbox Lifecycle in Specter Agent​

Specter's host runner manages the full lifecycle via run_sandbox_agent_task():

sbx run --clone --name <sandbox-name> <agent> <workspace-path> -- <prompt>
↓
(agent runs inside microVM, stdout streamed back)
↓
sbx rm --force <sandbox-name> ← always runs, even on error/timeout
  • Sandbox name is derived from the job token or <workspace>-<timestamp>, sanitized to alphanumeric + hyphens by safe_sandbox_name().
  • The agent key (codex, claude, cursor) selects the base image and run command from _SANDBOX_AGENTS in the host runner.
  • Only read-only sandbox mode is currently supported.

Shared Daemon​

sbx runs a single shared daemon regardless of how many agents are configured. There is no per-agent daemon — Codex, Claude Code, and Cursor all run through the same daemon, each in their own isolated microVM using different base images. The daemon status card on the Models page reflects the shared daemon health; the agent selector (Codex / Claude Code / Cursor) only affects which template is used.


Network Policy​

Three policies, set via sbx policy set-default and exposed in the Models page:

PolicyBehaviour
deny-allNo outbound network from inside the sandbox
balancedLimited outbound — blocks sensitive endpoints (recommended)
allow-allFull outbound network access

Policy is read from sbx policy ls and stored/applied through:

  • Host runner: docker_sandbox_policy_status() / set_docker_sandbox_policy()
  • Backend: GET/POST /api/runtime-adapters/docker-sandbox/policy
  • UI: policy selector on the Models page (admin only)

Runtime Preference Logic​

The Models page computes preferredRuntime:

  1. If Docker Sandbox status is ready → Docker (preferred)
  2. Else if Codex CLI status is ready → Codex
  3. Else → host runner offline / neither available

When Docker Sandbox is preferred, workflow execution routes through /runtimes/docker-sandbox/run on the host runner.


Status Checks​

The host runner's docker_sandbox_status() probes sbx and returns:

sandbox_health_statusMeaningUI message
missingsbx not found on PATH"Install Docker Sandboxes CLI."
daemon_unavailablesbx installed but daemon not running"Start Docker Sandboxes daemon."
cli_availableInstalled and daemon healthysbx <version>
readyFull status, sandbox runnableReady for agent tasks

Common causes of daemon_unavailable:

  • sbx session expired → run sbx login
  • Daemon stopped → run sbx daemon start
  • Run sbx diagnose for a full breakdown

Data Privacy — Your Code Never Leaves Your Machine​

All execution is local. Your source code, files, and workspace data are processed entirely on your own machine inside a microVM. Nothing is uploaded to Docker, Anthropic, OpenAI, or any third-party service as part of running a task.

Specifically:

  • The sandbox mounts your local workspace directory directly — no copy is made to any remote server
  • Agent output (stdout, logs, results) is written to local SQLite only
  • The Specter backend runs in Docker on your machine; there is no cloud backend
  • specter serve binds to localhost by default and spawns agents itself — there is no separate runner process and no second port

The only external network calls made during a run are by the agent itself (e.g. to call an LLM API with your prompt). Those calls go from inside the sandbox directly to the API provider — your code is not included unless your prompt explicitly references it. With deny-all network policy, even those calls are blocked.


Security Model​

PropertyDetail
IsolationMicroVM hypervisor boundary (not OS-level containers)
FilesystemOnly the approved project workspace is mounted — no host home dir, secrets, or other files
DockerIsolated Docker daemon inside sandbox; no access to the host Docker daemon
Credentialssbx secret stores API keys outside the sandbox via a local proxy — never sent to Specter
NetworkConfigurable via sbx policy; deny-all blocks all outbound traffic from the sandbox
RecoverySandbox deleted after every run; no persistent state left on the host
Code & dataNever transmitted to any Specter or Docker server — stays on your machine

Specter Agent adds its own layer on top:

  • Workspace must be explicitly approved before any sandbox run
  • All runs are recorded in local SQLite with status, output, and workspace path
  • Approval gates in the workflow graph are enforced before task dispatch

Key Files​

FileRole
internal/hostops/sandbox.gosandbox detection, daemon start, policy, agent templates
internal/api/runtime.go/docker-sandbox/status and /docker-sandbox/policy routes
src/pages/Models.tsxStatus card, agent selector, install dialog, policy selector
src/lib/api.tsdockerSandboxRuntimeStatus(), dockerSandboxPolicy(), setDockerSandboxPolicy()

Supported Agents​

Specter Agent supports three sandbox agents, selectable per workflow node or test run:

Agent keyTemplateAuth command
codexdocker/sandbox-templates:codexsbx secret set -g openai --oauth
claudedocker/sandbox-templates:claude-codesbx secret set -g anthropic
cursordocker/sandbox-templates:cursorsbx secret set -g cursor

The agent is set via "agent": "codex" | "claude" | "cursor" on each workflow node (data.agent field in the graph JSON). The host runner selects the correct template and run command from _SANDBOX_AGENTS. The Models page exposes an agent selector that persists to localStorage and is sent with each test run.

To use a specific agent in a workflow, set the agent field on any specialistAgent node in the workflow builder.