Sandbox
Create, find, connect to and control sandboxes, locally, in the cloud or by address.
Create, find, connect to and control sandboxes, locally, in the cloud or by address.
cua.sandboxes() returns the Sandboxes collection; each sandbox is a Sandbox handle. The same options run locally and in the cloud: on is the switch (local, cloud, direct:<addr>), kind and runtime pick the machine.
Python programs usually use the high-level API instead: cua_sandbox.Sandbox.
A sandbox's id() is its ref, and every call that takes a sandbox name accepts one:
| Ref | Meaning |
|---|---|
local:<name> | A sandbox on this machine |
cloud:<name> | A cloud sandbox |
direct:<host:port> | A machine reached by address |
relay:<machine-id> | An account machine reached through the relay (a Space) |
<name> | A bare name, searched across locations; AmbiguousSandbox when it matches more than one |
Readiness never assumes a guest agent: the provider reports the sandbox running, then the wait_for probes run, and creation fails fast if the sandbox exits.
Sandboxes#Creates, finds and manages sandboxes.
Returned by Cua.sandboxes.
| Method | Description |
|---|---|
cancel_create | Cancels the create of the named sandbox name that is still running (in this process or the daemon): the work in flight stops (an image download, a boot, a claim) and what the create made is deleted; a sandbox of that name that existed before is never touched. |
connect | Reattaches to a sandbox by ref (local:<name>, cloud:<name>, direct:<host:port>, a legacy id) or by a name that is unique across locations (else AmbiguousSandbox, listing the qualified refs). |
connect_url | Connects directly to a machine by URL (http(s)://host:port, bare host:port, a Fleet service URL or a relay URL) with an optional spacesd token. |
create | Creates (Fleet, local) or connects (direct) a sandbox and waits for the provider and every readiness probe. |
delete | Deletes a sandbox by ref or unique name. |
get | One sandbox's info, by ref or unique name. |
list | Sandboxes, each tagged with its location. |
list_all | Deprecated: Sandboxes.list with no location lists everything. |
list_with_warnings | Sandboxes.list with what the listing left out (for example "cloud sandboxes not listed: <reason>"). |
Sandboxes.cancel_create#Cancels the create of the named sandbox name that is still
running (in this process or the daemon): the work in flight stops
(an image download, a boot, a claim) and what the create made is
deleted; a sandbox of that name that existed before is never
touched. Finished image downloads stay cached. Returns what was
removed, or None when no create of that name was running. The
create itself fails with Cancelled.
async def cancel_create(self, name: str) -> Optional[str]| Parameter | Type | Default |
|---|---|---|
name | String | required |
Returns Option<String> · Async · Raises CuaError (Cancelled)
Sandboxes.connect#Reattaches to a sandbox by ref (local:<name>, cloud:<name>,
direct:<host:port>, a legacy id) or by a name that is unique across
locations (else AmbiguousSandbox, listing the qualified refs).
async def connect(self, name: str) -> Sandbox| Parameter | Type | Default |
|---|---|---|
name | String | required |
Returns Sandbox · Async · Raises CuaError (AmbiguousSandbox)
Sandboxes.connect_url#Connects directly to a machine by URL (http(s)://host:port, bare
host:port, a Fleet service URL or a relay URL) with an optional
spacesd token. No daemon is assumed and nothing is probed.
async def connect_url(self, url: str, token: Optional[str], name: Optional[str]) -> Sandbox| Parameter | Type | Default |
|---|---|---|
url | String | required |
token | Option<String> | required |
name | Option<String> | required |
Returns Sandbox · Async · Raises CuaError
Example
import asyncio
import cua
async def main():
sb = await cua.embedded().sandboxes().connect_url(URL, TOKEN, "dev") # your spacesd's address and token
guest = await sb.spacesd(None)
out = await guest.run(cua.SpacesdCommand(program="echo", args=["hi"]))
print(out.stdout)
asyncio.run(main())Sandboxes.create#Creates (Fleet, local) or connects (direct) a sandbox and waits for the provider and every readiness probe.
async def create(self, options: SandboxCreateOptions) -> Sandbox| Parameter | Type | Default |
|---|---|---|
options | SandboxCreateOptions | required |
Returns Sandbox · Async · Raises CuaError
Example
import asyncio
import cua
async def main():
c = cua.embedded()
sb = await c.sandboxes().create(cua.SandboxCreateOptions(
on="local", # or "cloud"
image=cua.canonical_image("linux", None),
name="dev",
wait_for=[cua.ReadinessProbe(service="env")], # until its spacesd answers
))
guest = await sb.spacesd(None)
print((await guest.sh("uname -a", None)).stdout.decode())
await sb.delete()
asyncio.run(main())Sandboxes.delete#Deletes a sandbox by ref or unique name.
async def delete(self, name: str) -> None| Parameter | Type | Default |
|---|---|---|
name | String | required |
Async · Raises CuaError
Sandboxes.get#One sandbox's info, by ref or unique name.
async def get(self, name: str) -> SandboxInfo| Parameter | Type | Default |
|---|---|---|
name | String | required |
Returns SandboxInfo · Async · Raises CuaError
Sandboxes.list#Sandboxes, each tagged with its location. None (the default):
all of them, local, direct and the account's live cloud sandboxes,
whatever the default location is. "local", "cloud" or
"direct": only those.
Cloud sandboxes never fail the listing: without Fleet credentials
they are left out silently, and when Fleet fails or takes longer than
5 s they are left out with a warning (logged here;
Sandboxes.list_with_warnings returns it).
async def list(self, location: Optional[str]) -> List[SandboxInfo]| Parameter | Type | Default |
|---|---|---|
location | Option<String> | required |
Returns Vec<SandboxInfo> · Async · Raises CuaError
Sandboxes.list_all#Deprecated: Sandboxes.list with no location lists everything.
async def list_all(self) -> List[SandboxInfo]Returns Vec<SandboxInfo> · Async · Raises CuaError
Sandboxes.list_with_warnings#Sandboxes.list with what the listing left out (for example
"cloud sandboxes not listed: <reason>").
async def list_with_warnings(self, location: Optional[str]) -> SandboxListing| Parameter | Type | Default |
|---|---|---|
location | Option<String> | required |
Returns SandboxListing · Async · Raises CuaError
Sandbox#A sandbox handle.
Returned by Sandboxes.connect, Sandboxes.connect_url, Sandboxes.create.
| Method | Description |
|---|---|
overlay | Injects binaries (see Overlay): each replaces its guest file atomically, is recorded under /var/lib/cua/overlays with its sha256, and what runs it is restarted. |
spacesd | Attaches to cua-spacesd inside the sandbox (the env service or guest port 3211). |
viewer_url | A browser link to this sandbox's desktop in the cua-spacesd HTML5 viewer (/viewer on the env service): video, audio, input, clipboard, file drop and folder sharing, in any modern browser. |
agents | Coding agents inside this sandbox (needs cua-spacesd): run a harness over ACP, stream normalized events, follow up, interrupt, collect results; runs outlive this handle. |
delete | Deletes (Fleet: releases the claim and an ephemeral pool). |
detach | Managed Fleet claims: stop renewing the claim and forget the handle; the claim runs until its current shutdown time. |
forward | Forwards a loopback port to guest port: a TCP forward locally (and over cua-spacesd's tunnel when the image has it); in the cloud without cua-spacesd, a loopback HTTP/WebSocket proxy through the Fleet gateway. |
guest_display | The guest display without cua-spacesd: the VM's VNC endpoint and a host command that opens it (lume attach). |
guest_screenshot | Captures the guest framebuffer as PNG without cua-spacesd. |
guest_sh | Runs line with /bin/sh -c in the guest without cua-spacesd, to completion (default timeout 120 s). |
keep_alive | Extends a Fleet lease by seconds. |
mcp | An MCP client (the official Rust SDK) for the MCP server behind service at path (default /mcp). |
mcp_config | Where the MCP server behind service is (URL of its endpoint at path, default /mcp, plus the headers every request needs), for any MCP client. |
open_media_bridge | Opens a media session and returns a loopback WebSocket bridge for a webview (daemon mode). |
public_url | A shareable URL for service that stops working after ttl_seconds (60 s to 24 h, default 1 h). |
refresh | Fresh info (status from the provider). |
restart | Restarts. |
resume | Resumes. |
revoke_public_url | Revokes a URL from public_url. |
service | A named service (for example "server" or "env"). |
suspend | Suspends. |
wait_ready | Waits until every probe passes. |
| Accessor | Returns | Description |
|---|---|---|
id() | String | Qualified ref (local:<name>, cloud:<name>, direct:<host:port>), the same kind of value local and in the cloud; it round-trips through Sandboxes.connect. |
image_info() | Option<ImageInfo> | The image this sandbox runs, as resolved and pinned at create time: the digest and variant that actually ran. None for direct (URL) connections, claims on a named pool, images not resolved from a registry, and the daemon topology. |
info() | SandboxInfo | Info as of creation / connection. |
is_ephemeral() | bool | Whether the sandbox is torn down on delete and has no state file. |
kind() | String | What kind of machine: container or vm (empty when not known). |
location() | String | Where it runs: local, cloud, direct or relay. |
name() | String | Name. |
runtime() | String | The engine that runs it (gvisor, runc, qemu, lume, kubevirt; empty when not known). |
runtime_type() | String | runtime_type. |
Sandbox.overlay#Injects binaries (see Overlay): each replaces its guest file
atomically, is recorded under /var/lib/cua/overlays with its
sha256, and what runs it is restarted. Local containers go through
the container engine; other sandboxes need cua-spacesd and root (or
passwordless sudo) in the guest. timeout_ms
bounds a cua-spacesd restart (default 180 s).
async def overlay(self, overlays: List[Overlay], timeout_ms: Optional[int] = None) -> List[OverlayResult]| Parameter | Type | Default |
|---|---|---|
overlays | Vec<Overlay> | required |
timeout_ms | Option<u32> | None |
Returns Vec<OverlayResult> · Async · Raises CuaError
Sandbox.spacesd#Attaches to cua-spacesd inside the sandbox (the env service or
guest port 3211). Fails with SpacesdNotAvailable when none
answers; sandbox lifecycle never depends on it.
async def spacesd(self, probe_timeout_ms: Optional[int]) -> SpacesdClient| Parameter | Type | Default |
|---|---|---|
probe_timeout_ms | Option<u32> | required |
Returns SpacesdClient · Async · Raises CuaError (SpacesdNotAvailable)
Sandbox.viewer_url#A browser link to this sandbox's desktop in the cua-spacesd HTML5
viewer (/viewer on the env service): video, audio, input,
clipboard, file drop and folder sharing, in any modern browser. The
link carries a scoped viewer ticket, never the sandbox token. Needs
cua-spacesd in the sandbox.
async def viewer_url(self, options: Optional[ViewerOptions] = None) -> ViewerLink| Parameter | Type | Default |
|---|---|---|
options | Option<ViewerOptions> | None |
Returns ViewerLink · Async · Raises CuaError
SandboxInfo record#A sandbox as listed.
Returned by Sandbox.info, Sandbox.refresh, Sandboxes.get, Sandboxes.list, Sandboxes.list_all.
| Field | Type | Default | Description |
|---|---|---|---|
name | String | Name. | |
kind | String | What kind of machine: container or vm (empty when not known: an existing machine, or a cloud sandbox this client did not create). | |
runtime | String | The engine that runs it: gvisor, runc, qemu, lume or kubevirt (empty when not known). | |
runtime_type / runtimeType | String | runtime_type as persisted (fleet, direct, gvisor, qemu, ...); prefer location, kind and runtime. | |
status | SandboxStatus | Status. | |
status_detail / statusDetail | Option<String> | Provider's word for an unknown status. | |
ephemeral | bool | No state file; torn down on delete. | |
services | HashMap<String, u16> | Declared services: name → guest port (0 = only the name is known). | |
endpoints | HashMap<String, String> | Service base URLs by name (Fleet: gateway URLs that need the Fleet bearer). | |
image | Option<String> | Image, when known. | |
id | String | Qualified ref, the same kind of value local and in the cloud: local:<name>, cloud:<name> or direct:<host:port>. Every call that takes a sandbox name accepts it. | |
phase | SandboxPhase | Portable phase: provisioning, starting, ready or stopped. | |
location | String | Where it runs: local, cloud, direct (a machine by address) or relay. | |
expires_at_unix / expiresAtUnix | Option<i64> | When it expires unless kept alive (unix seconds), when known. | |
provider_details / providerDetails | HashMap<String, String> | Provider internals (cloud: pool, namespace, claim; local: backend, container_id). Not part of the portable API. | |
image_info / imageInfo | Option<ImageInfo> | None | The image as resolved and pinned at create time (digest, variant). None for direct connections, named pools, images not resolved from a registry, and the daemon topology. |
SandboxListing record#A sandbox listing and what it left out.
Returned by Sandboxes.list_with_warnings.
| Field | Type | Default | Description |
|---|---|---|---|
sandboxes | Vec<SandboxInfo> | Sandboxes, each with its location. | |
warnings | Vec<String> | Sources left out, for example "cloud sandboxes not listed: ...". |
SandboxPhase enum#Portable lifecycle phase, the same words local and in the cloud.
SandboxPhase.PROVISIONING
SandboxPhase.STARTING
SandboxPhase.READY
SandboxPhase.STOPPED| Variant | Description |
|---|---|
Provisioning | Being created (cloud: capacity is being provisioned). |
Starting | Booting; readiness probes have not passed yet. |
Ready | Running and ready. |
Stopped | Stopped or suspended. |
SandboxStatus enum#Coarse lifecycle status.
SandboxStatus.RUNNING
SandboxStatus.SUSPENDED
SandboxStatus.STOPPED
SandboxStatus.PROVISIONING
SandboxStatus.UNKNOWN| Variant | Description |
|---|---|
Running | Running (or bound). |
Suspended | Suspended or scaled to zero. |
Stopped | Stopped. |
Provisioning | Starting. |
Unknown | Unknown; see SandboxInfo.status_detail. |
parse_sandbox_ref#Parses a sandbox ref: local:<name>, cloud:<name>,
direct:<host:port>, relay:<machine-id>, a legacy spelling
(space://fleet/<ns>/<claim>, fleet:<ns>:<claim>, url:<addr>, a
URL), or a bare name.
def parse_sandbox_ref(input: str) -> SandboxRefParts| Parameter | Type | Default |
|---|---|---|
input | String | required |
Returns SandboxRefParts · Raises CuaError
Example
import cua
print([cua.parse_sandbox_ref(r).id for r in ("space://fleet/ns/box", "url:10.0.0.5:3211", "box")])
# ['cloud:box', 'direct:10.0.0.5:3211', 'box']qualify_sandbox_ref#Qualifies name for a lookup: local = true narrows a bare name to
local:<name>, false to cloud:<name>, None keeps it (a bare name
is then searched across locations). A qualified ref elsewhere than
local asks is an InvalidArgument.
def qualify_sandbox_ref(name: str, local: Optional[bool] = None) -> str| Parameter | Type | Default |
|---|---|---|
name | String | required |
local | Option<bool> | None |
Returns String · Raises CuaError (InvalidArgument)
Example
import cua
print([cua.qualify_sandbox_ref("box", True), cua.qualify_sandbox_ref("box", False), cua.qualify_sandbox_ref("box", None)])
# ['local:box', 'cloud:box', 'box']ambiguous_sandbox_candidates#The qualified candidates an AmbiguousSandbox message lists (empty
for any other message).
def ambiguous_sandbox_candidates(message: str) -> List[str]| Parameter | Type | Default |
|---|---|---|
message | String | required |
Returns Vec<String>
SandboxRefParts record#A parsed sandbox ref.
Returned by parse_sandbox_ref.
| Field | Type | Default | Description |
|---|---|---|---|
location | Option<String> | local, cloud, direct, relay or a contrib provider (e2b); None for a bare name. | |
name | String | The name, host:port or relay machine id. | |
id | String | The canonical form (location:name, or the bare name). |
Overlay record#A binary to inject into a sandbox.
| Field | Type | Default | Description |
|---|---|---|---|
name | String | cua-driver, cua-spacesd, or any name (then target is required). Letters, digits, ., _, -. | |
path | String | The local file to inject. | |
target | Option<String> | None | Guest path to replace. Default: resolved for cua-driver and cua-spacesd. |
source | Option<String> | None | Provenance recorded with it (for example the git sha it was built from). Default: the local path. |
OverlayResult record#What an overlay did.
Returned by Sandbox.overlay.
| Field | Type | Default | Description |
|---|---|---|---|
name | String | Overlay name. | |
target | String | Guest path that was replaced. | |
sha256 | String | sha256 (hex) of the injected file (pass it to cua doctor --expect NAME=sha256:<hex>). | |
previous_sha256 / previousSha256 | String | sha256 of the file it replaced, empty when there was none. | |
size | u64 | Bytes. | |
restarted | String | How the running program was restarted (supervisor:cua-spacesd, systemd:cua-spacesd.service, stopped:<pids>), empty when nothing ran it. |
ViewerLink record#A link to the sandbox desktop in the cua-spacesd HTML5 viewer.
Returned by Sandbox.viewer_url.
| Field | Type | Default | Description |
|---|---|---|---|
url | String | Open this in any modern browser. The credential is in the fragment (#ticket=), which browsers never send to a server. | |
expires_at_unix / expiresAtUnix | i64 | When the link stops working for new connections (unix seconds). |
ViewerOptions record#Options for Sandbox.viewer_url.
| Field | Type | Default | Description |
|---|---|---|---|
ttl_seconds / ttlSeconds | Option<u32> | None | Lifetime of the link in seconds (60 to 86400). Default 3600. |
view_only / viewOnly | bool | false | Watch only: no input, clipboard, files or microphone. |
clipboard | bool | true | Two-way clipboard sync. |
files_root / filesRoot | Option<String> | None | Guest directory for uploads and folder sharing (~ is the desktop user's home). None means ~; an empty string turns files off. |
microphone | bool | true | Allow the microphone (also subject to the sandbox's uplink policy). |
contrib_providers_built#The contrib providers this build includes (empty unless built with the
contrib feature).
def contrib_providers_built() -> List[str]Returns Vec<String>
sandbox_locations#Every location word on= accepts, in display order: local, cloud,
then the contrib providers (e2b, daytona, modal, ...) and your own
clouds (aws, gcp). A word is listed whether or not this build
includes that provider (see contrib_providers_built).
def sandbox_locations() -> List[str]Returns Vec<String>