Sandbox backends

Use this page to pick the sandbox backend for your Sagewai workers. If you need to choose between Docker, Kubernetes, or Lambda — or decide whether a heterogeneous fleet makes sense — this is where to start.

Before you start

Useful background:

Two kinds of "backend"

Sagewai has two pluggable backend types and they're independent. Always say which one you mean.

  • Sandbox backend — where the sandbox container, pod, or function lives. Docker, Kubernetes, Lambda, Null. This page is about this one.
  • Identity backend — where Sealed credentials are sourced from. Builtin file store, HashiCorp Vault, 1Password, AWS Secrets Manager, SOPS, Bitwarden. See Vault backend.

The two are orthogonal. A Kubernetes sandbox backend can run alongside a Vault identity backend. Docker sandboxes can run alongside the builtin file store. A single deployment can mix freely.

Available backends

Sagewai ships Null, Docker, and Kubernetes today. Lambda is on the roadmap for event-driven workloads. Firecracker and gVisor are tracked as future work for ultra-isolated tenants.

BackendUsed forModes supportedCold-startPool supportStatus
Nullbare mode only — no sandboxbaren/an/ashipped
Dockerlocal dev, single-VM ops, simple productionall modes2-8swarm container poolshipped
Kubernetesproduction at scale, multi-tenant clustersall modes5-15sDeployment with min-replicasshipped
Lambdaevent-driven, scale-to-zero, short toolsbare, sandboxed, identity (no CLI agent)~ms warm / 1-3s cold; provisioned concurrency for hot pathsprovisioned concurrencyroadmap
Firecrackerultra-isolated tenants on shared hostsall modes<1swarm microVM poolfuture
gVisorenhanced isolation over Dockerall modessimilar to Dockersimilar to Dockerfuture

Mode × backend compatibility

Every workflow's requires_sandbox_mode must be supported by at least one available worker's backend.

ModeNullDockerKubernetesLambda
Bare
Sandboxed (no identity)
Identity
Full CLI agent
Full CLI agent + JIT callback

Why Lambda doesn't run full CLI agent mode

  • 15-minute hard execution timeout — too short for typical CLI agent sessions (Claude Code can run 30+ minutes on complex prompts).
  • No persistent filesystem (10 GB ephemeral, gone at function end) — multi-step CLI sessions can't accumulate work.
  • No interactive shell, no long-lived RPC daemon — the bidirectional callback channel is awkward to maintain over Lambda's request-response model.
  • Each invocation is a fresh container — the pool reset model is "the runtime always discards"; provisioned concurrency mitigates cold-start cost but doesn't change the model.

Why Kubernetes runs every mode

  • Pods can run for hours (matches CLI agent durations).
  • Multi-container pod pattern (CLI agent + sidecar tool runner) is clean.
  • Kubernetes NetworkPolicy resources map cleanly to Sagewai's NetworkPolicy enum.
  • StatefulSet supports persistence-across-runs if a workflow benefits from it.
  • Cluster autoscaler handles capacity for pool scaling.

How each backend implements the abstract primitives

Sagewai expresses sandbox concepts (start, stop, env injection, network policy, pool reuse, cleanup) as a single interface; each backend translates them to its native API.

PrimitiveDockerKubernetesLambda
Sandbox lifecyclecontainer start / stoppod create / delete (or Job)function invoke
Imageghcr.io/sagewai/sandbox-base:VERSIONsame image, pulled to podcontainer image deployed to Lambda or zip
Env injection--env K=V on container startenv: field on pod spec or projected secretfunction configuration env
Tool runner execdocker execkubectl exec (or pod-init script that starts the daemon)function payload (single-shot RPC)
NetworkPolicy.NONEiptables drop / no networkNetworkPolicy egress: [], ingress: []VPC isolated subnet, no NAT gateway
NetworkPolicy.EGRESS_ONLYbridge network, no inboundNetworkPolicy egress to allowed CIDRsVPC with NAT gateway, no inbound
NetworkPolicy.FULLhost network or default bridgedefault networkingnormal Lambda networking
Pool reusewarm container pool, reset env between runswarm pod pool via Deployment with min-replicas, reset envprovisioned concurrency (limited reuse model)
Per-run cleanupper-exec env reset in-memoryper-exec env reset in-memoryn/a (every invoke is fresh; nothing to scrub)
Resource limits--memory --cpusresources.limits.memory/cpufunction memory configuration (CPU is a function of memory)
Workdir mount--mount bind to host path or named volumevolumeMounts + volumes (PVC, emptyDir, hostPath)/tmp (ephemeral 10 GB max)
Image digest pinningimage@sha256:...samecontainer image URI with digest

Heterogeneous fleets

Sagewai supports a fleet where different workers run different sandbox backends. Each worker advertises its backend via capability labels:

{
    "sandbox.backend": "docker",       # or "kubernetes" or "lambda" or "null"
    "sandbox.image_variants": "base,claude-code,codex",
    "models_supported": "claude-3-5-sonnet,gpt-4",
    "pool": "production",
}

The fleet dispatcher matches a run's requirements against worker labels. A run that requires full-CLI-agent mode with the claude-code image variant won't route to a Lambda-backend worker; it will route to a Docker or Kubernetes worker that advertises the variant.

This means a deployment can:

  • Use Docker workers for dev/CI (low overhead, shared tooling).
  • Use Kubernetes workers for production scale.
  • Use Lambda workers for sporadic short jobs that benefit from scale-to-zero economics.

All in the same fleet, with workflows automatically routed appropriately.

Picking a backend

Most operators land in one of these patterns:

  • Single VM / dev laptop → Docker.
  • Self-managed production → Docker (small) or Kubernetes (scale).
  • Multi-project self-managed deployment at scale → Kubernetes. Per-namespace isolation, RBAC, NetworkPolicy.
  • Sporadic batch workloads with cost sensitivity → Lambda for the short Sandboxed/Identity portion + Docker/Kubernetes for the full-CLI-agent portion.
  • Highest-isolation tenants → wait for Firecracker, or use a dedicated Kubernetes cluster per tenant.

A single deployment can mix: most workers on Kubernetes, a few Lambda workers for cost-optimised small tasks.

Decision tree

Are you on a single VM / laptop?
  └── YES → Docker.

Do you have an existing Kubernetes cluster?
  └── YES → Kubernetes (production scale + multi-tenant ready).

Is your workload primarily short, sporadic Sandboxed/Identity jobs (event-driven)?
  └── YES → Lambda for those jobs (CLI-agent steps still need Docker/Kubernetes).

Do you need workloads beyond OCI-container isolation?
  └── YES → wait for Firecracker, or accept the gap. Docker + Kubernetes are
            the supported defaults today.

Common pitfalls

  1. Conflating "backend" in conversation. Always say "sandbox backend" or "identity backend" — never just "backend." The two are independent and the confusion costs hours.

  2. Forcing one sandbox backend across the fleet. Heterogeneous fleets are supported; using only one backend everywhere because "that's how we started" leaves performance and cost wins on the table.

  3. Building features that assume a specific sandbox backend. The warm-pool, per-run cleanup, and redaction all sit on the abstract sandbox interface. New features should specify behavior in terms of the interface, not in terms of docker exec.

See also

This page picks the backend; the sandboxing handbook walks through the worker-side configuration once you've chosen.