Sandboxes
A sandbox is an isolated environment where an agent runs bash commands. Reach for one whenever an
agent needs a shell: file work, scripts, curl against the sixb API
gateway. The sandbox keeps that work off your host — its filesystem, network, and processes are
walled off from the machine the runtime runs on.
You pick a provider once and wire it into createSixb. Everything above the sandbox — the agent,
its bash tool, its run lifecycle — is written against one provider-agnostic contract, so swapping
providers never touches agent code.
The contract
Two interfaces define the whole surface. A SandboxFactory holds the provider's defaults and is
passed once to createSixb. A Sandbox is one isolated environment that runs commands.
interface SandboxFactory {
create(options?: CreateSandboxOptions): Promise<Sandbox>
}
interface Sandbox {
readonly id: string
readonly provider: string // "local" | "apple-container" | "smolvm" | "vercel"
readonly status: "running" | "stopped" | "failed"
readonly workingDirectory: string
runCommand(
command: string,
args?: readonly string[],
options?: RunCommandOptions
): Promise<CommandResult>
// Materialize files into the sandbox; a later runCommand can read them. Parent dirs are created.
writeFiles(files: readonly SandboxFileRecord[]): Promise<void>
stop(): Promise<void> // mark stopped; later runCommand rejects. Idempotent.
destroy(): Promise<void> // stop and reclaim provider resources. Idempotent.
}
The worker calls factory.create() once per agent run, writeFiles(...) to install the run's
skills and context, and runCommand(...) per command, then destroy() on teardown.
File materialization
writeFiles is how bytes get into a sandbox — the worker never writes to the host filesystem
directly. Each provider decides how a SandboxFileRecord ({ path, contents, mode? }) reaches the
guest: the local provider writes straight to the host filesystem it shares with the guest, while
smolvm executes an in-guest script that decodes the payload inside the VM. The only guarantee the
contract makes is observable: after writeFiles, the files exist at their paths for a subsequent
runCommand.
runCommand resolves with a CommandResult rather than throwing on a non-zero exit — a failed
command is data, not an exception:
| Field | Meaning |
|---|---|
exitCode | Process exit code (0 on success) |
stdout | Captured standard output |
stderr | Captured standard error |
durationMs | Wall-clock run time |
timedOut | true when the command was killed for exceeding its timeout |
RunCommandOptions overrides the sandbox-level defaults for a single call:
| Option | Meaning |
|---|---|
cwd | Working directory for this command |
env | Env merged on top of the sandbox env; per-call wins on collision |
timeout | Timeout in milliseconds; on expiry the command is killed and timedOut is set |
signal | An AbortSignal to cancel an in-flight command |
CreateSandboxOptions sets the per-run defaults at create() time: workingDirectory, env,
timeout, and network.
Wiring
Construct a factory and pass it as sandboxes:
import { createSixb } from "@sixb/core"
import { LocalSandboxFactory } from "@sixb/sandboxes-local"
export const sixb = await createSixb({
// ...broker, storage, queues, ontology, agents
sandboxes: new LocalSandboxFactory(),
})
Switching to stronger isolation is a one-line change — the rest of the app is unaffected:
import { SmolvmSandboxFactory } from "@sixb/sandboxes-smolvm"
createSixb({ sandboxes: new SmolvmSandboxFactory() })
Or use Vercel-hosted Firecracker microVMs when the agent worker already has Vercel Sandbox credentials and the Sixb API gateway is reachable from Vercel:
import { VercelSandboxFactory } from "@sixb/sandboxes-vercel"
createSixb({ sandboxes: new VercelSandboxFactory() })
On Apple silicon Macs, Apple Container is another local option:
import { AppleContainerSandboxFactory } from "@sixb/sandboxes-apple-container"
createSixb({ sandboxes: new AppleContainerSandboxFactory() })
Network policy
Every provider speaks the same SandboxNetworkPolicy. It is set per-run at create(...) (or as a
factory default) and governs what the sandbox can reach over the network:
| Mode | Meaning |
|---|---|
{ mode: "none" } | No outbound network (the default when none is set) |
{ mode: "restricted", allow: [...] } | Only the listed origins are reachable |
{ mode: "all" } | Unrestricted egress (discouraged in production) |
Each restricted entry is a { name, origin } target, for example
{ name: "sixb-api", origin: "http://10.0.0.5:3002" }.
Providers differ in how precisely they can enforce restricted. The smolvm provider
enforces a real per-host allow list inside the microVM. The Vercel provider maps
restricted HTTPS origins to Vercel's TLS/SNI firewall and IP origins to CIDR rules. The
local and Apple Container providers are all-or-nothing today:
none blocks outbound network, any other mode allows host/default network. The contract is the same;
read each provider page for what it actually enforces.
How agents use a sandbox
You rarely call runCommand yourself. The agent worker does it:
- When a run starts, the worker calls
factory.create(...)with a restricted network policy whose only allowed origin is the sixb API gateway. The agent can reach the gateway and nothing else. - Sandbox boot overlaps the model's first response — it is provisioned concurrently and the bash tool awaits it lazily on the first command, so boot latency does not block the turn.
- Each
bashtool call becomesrunCommand("bash", ["-lc", script], ...). - On run teardown the worker calls
destroy().
Because egress is locked to the gateway, the agent's only way to read or write app data is through that gateway — there is no open internet. See Agent tools and the gateway for what the gateway exposes.
Choosing a provider
| Provider | Package | Isolation | Use when |
|---|---|---|---|
| Local | @sixb/sandboxes-local | OS sandboxing (seatbelt / bwrap) or passthrough | Development and local iteration |
| Apple Container | @sixb/sandboxes-apple-container | Local Apple Container runtime | Local Mac testing with container isolation |
| smolvm | @sixb/sandboxes-smolvm | Hardware-isolated microVM | Production on hosts where you can run smolvm |
| Vercel | @sixb/sandboxes-vercel | Vercel-hosted Firecracker microVM | Production on Vercel, or hosted workers with Vercel Sandbox credentials |
Rule of thumb: local or Apple Container for dev, smolvm or Vercel for stronger isolation in prod. The local provider is friction-free and always boots. Apple Container gives Mac users a local containerized runtime. smolvm gives each run its own microVM with a true per-host egress allow list. Vercel gives you remote managed microVMs, but the Sixb API gateway must be reachable from Vercel (usually a public HTTPS origin, not localhost).
Related
- Local sandbox — OS-level isolation backends and auto-detection
- Apple Container sandbox — local Apple Container-backed sandboxes
- smolvm sandbox — hardware-isolated microVMs
- Vercel sandbox — managed Vercel-hosted microVMs
- Agent tools and the gateway — what the bash tool can reach