Sandbox API

Desktop architecture

How Sandboxes routes Linux pods, Windows VMs, and external Mac desktops.

Desktop profiles share one trainer-facing API. The catalog driver_hint selects the substrate; the viewer mode selects how the browser connects.

Layer split

PieceResponsibility
Sandboxes L3Lifecycle, workspace checkpoint, signed viewer.url, HTTP/WS proxy, evidence
viewer_ui (L4)Embeddable GUI; mode adapters (novnc, guacamole, provider)
SubstratesActual OS + streamer (TigerVNC in pod, Guacamole to VM, vendor Mac stream)

Sandboxes does not ship the product UI — only the proxy and evidence routes.

Profile → substrate → viewer

Profiledriver_hintSubstrateviewer.modeUpstream
desktop-ubuntuk8sKubernetes podnovncwebsockify :8080 in pod
desktop-windowsec2-vmCloud VMguacamoleGuacamole HTML + WebSocket tunnel
desktop-macosexternalExternal MacproviderProvider stream (reference: aws-ec2-mac)

ProfileRoutingBackend treats gce-vm, ec2-vm, and vm as the VM backend family.

Request flow

  1. POST /sandbox/sandboxes/v1 with profile=desktop-* (async create for desktop).
  2. Router reads catalog driver_hint → k8s / VM / external backend.
  3. Backend start() provisions the substrate; viewer_endpoint() returns the private stream host:port.
  4. Runtime waits until the stream port accepts TCP (skipped when CLOUD=fake).
  5. GET …/{id} returns the viewer descriptor when status=running.
  6. Browser opens viewer.url → sandboxes proxy → upstream streamer.

The browser never receives your API key — only the signed viewer URL.

Workspace durability

/workspace (or C:\workspace on Windows) is the durable path. On stop, workspace bytes checkpoint to object storage under the tenant/project prefix.

Hexagonal boundaries

Cloud SDKs (boto3, etc.) stay in provider adapters under infrastructure/external_desktop/providers/*. Application and domain layers import ports, not drivers.