Typical flow
Static methods
Sandbox.create()
Example
Example
SandboxConfig for the full set. Pulls the image if needed, boots the VM, starts the guest agent, and waits until it is ready to accept commands. Sandbox names must be non-empty and no longer than 128 UTF-8 bytes.
The returned Sandbox is an async context manager. Use async with to guarantee cleanup; on exit the sandbox is killed and its persisted state removed.
Parameters
namestr**kwargsSandboxConfigimage, cpus, memory, volumes, ports, network, secrets, detached, and more.Returns
Sandbox.create_with_progress()
Example
Example
create() but returns a PullSession that lets you track image pull progress before the sandbox is ready. This method is synchronous (not awaitable); the async work happens through the PullSession.
Parameters
namestr**kwargsSandboxConfigReturns
Sandbox.start()
Example
Example
Parameters
namestrdetachedboolTrue, the sandbox survives after your process exits. Default False.Returns
Sandbox.get()
Example
Example
Parameters
namestrReturns
Sandbox.list()
Example
Example
Returns
Sandbox.list_with()
Example
Example
Parameters
labelsMapping[str, str] | NoneNone returns every sandbox, like list().Returns
Sandbox.remove()
Example
Example
Parameters
namestrInstance properties
sb.name
Example
Example
await sb.name().
Returns
sb.owns_lifecycle
create() or start() owns lifecycle, including when created with detached=True, until you call detach(). Handles upgraded via SandboxHandle.connect() do not own lifecycle. This is an async property; use await sb.owns_lifecycle.
Returns
True if this handle owns the lifecycle.sb.fs
Example
Example
sb.fs (no await). See Filesystem for API details.
Returns
Instance methods
Command execution (exec, exec_stream, shell, shell_stream) is documented on the Execution page; SSH (ssh) on the SSH page. The lifecycle, attach, metrics, and logs methods follow.
sb.attach()
Example
Example
Parameters
cmdstrargslist[str] | Nonecwdstr | Noneuserstr | NoneenvMapping[str, str] | Nonedetach_keysstr | NoneReturns
sb.attach_shell()
Example
Example
Returns
sb.ping()
Example
Example
core.ping and waits for core.pong; it does not start stopped sandboxes and raises an error if the sandbox is not running or agentd cannot respond. After upgrading from a runtime that predates protocol generation 6, restart already-running sandboxes so the guest agent understands the message.
Returns
sb.touch()
Example
Example
core.touch, receives core.touched, and advances the guest activity sequence used by the runtime idle-timeout monitor. It does not start stopped sandboxes and it does not bypass max_duration.
Returns
sb.modify()
Example
Example
"live", "next start", "requires restart", or "unsupported", and apply is all-or-nothing.
cpus and memory resize live within the max_cpus / max_memory ceilings; raising a ceiling requires a restart. Env and workdir changes affect future execs only. On a stopped sandbox, changes are saved for the next boot.
Secret changes are Rust-SDK and CLI only for now. The CLI equivalent is msb modify.
The returned plan dict mirrors the canonical JSON shape:
| Key | Type | Description |
|---|---|---|
sandbox | str | Sandbox being modified |
status | str | Status used for classification ("running", "stopped", …) |
applied | bool | Whether the changes were applied; False with dry_run=True |
policy | str | Policy used to produce the plan |
changes | list[dict] | One entry per field: field, change ("added", "updated", "removed"), before, after, disposition, optional reason |
conflicts | list[dict] | Conflicts (field + message) that must be resolved before the patch can apply |
warnings | list[dict] | Non-fatal warnings (field + message), e.g. the future-execs-only env caveat |
resize_status | list[dict] | Live resize outcomes after apply, per resource: resource ("cpus" / "memory"), requested, actual, enforced, state ("accepted", "converging", "applied", "guest-refused", "failed"). Omitted when no live resize ran |
resize_status reports when the sandbox has finished adjusting.
Parameters
cpusint | Nonemax_cpus.max_cpusint | Nonememoryint | Nonemax_memory.max_memoryint | NoneenvMapping[str, str] | Noneenv_rmlist[str] | NonelabelsMapping[str, str] | Nonelabels_rmlist[str] | Noneworkdirstr | Nonepolicystr | None”no_restart” (default) applies only changes that can complete without restarting; “next_start” persists changes for the next start without mutating a running VM; “restart” restarts if needed so restart-required changes become active now.dry_runboolTrue, compute the plan without applying anything. Default False.Returns
dry_run=True.sb.metrics()
Example
Example
Returns
sb.metrics_stream()
Example
Example
MetricsStream supports both recv() and async for.
Parameters
intervalfloat1.0.Returns
sb.logs()
Example
Example
exec.log. Backed by an on-disk JSON Lines file the runtime writes via the relay tap. Works on running and stopped sandboxes alike; there is no protocol traffic. The same method is available on SandboxHandle for callers that don’t want to start the sandbox first.
The default sources are "stdout", "stderr", and "output" (PTY-merged). Pass "system" to also include synthetic lifecycle markers and runtime/kernel diagnostic lines, or "all" as shorthand for all four. Timestamps are exposed as float ms since the Unix epoch (UTC) for parity with SandboxMetrics.timestamp_ms.
Parameters
tailint | Nonesince_msfloat | Noneuntil_msfloat | Nonesourceslist[LogReadSource] | NoneNone = [“stdout”, “stderr”, “output”]. Add “system” to merge runtime/kernel diagnostics, or use “all” for all four.Returns
sb.log_stream()
Example
Example
LogStream. With follow=True the stream stays open and yields new entries as they are written, like tail -f. Resume an earlier stream by passing the cursor of the last entry you saw as from_cursor. Also available on SandboxHandle.
Parameters
sourceslist[LogReadSource] | Nonesince_msfloat | Nonefrom_cursorstr | Noneuntil_msfloat | NonefollowboolTrue, keep the stream open and yield new entries as they arrive. Default False.Returns
sb.stop()
Example
Example
timeout to override the graceful shutdown window before force-kill escalation.
Parameters
timeoutfloat | NoneNone uses the ten-second default.sb.request_stop()
Example
Example
wait_until_stopped() when the caller needs to observe the terminal state.
sb.kill()
Example
Example
fsync’d may be lost, same durability semantics as a sudden power loss on a physical machine. Prefer stop() for graceful shutdown that gives the workload a chance to flush.
Parameters
timeoutfloat | Nonesb.request_kill()
Example
Example
sb.request_drain()
Example
Example
exec calls are rejected; the sandbox transitions to stopped when all in-flight commands finish. Useful for zero-downtime rotation of worker sandboxes. Use wait_until_stopped() when the caller needs stopped-state observation.
sb.wait_until_stopped()
Example
Example
Returns
sb.detach()
Example
Example
Sandbox.get().
Patch
Factory class for rootfs patches passed toSandbox.create(..., patches=[...]). Each static method returns a PatchConfig. By default a patch that targets a path already present in the image errors at boot; pass replace=True on the operation to allow overwriting. mkdir and remove are idempotent. See Patches for conceptual context.
Patch.text()
Example
Example
path.
Parameters
pathstrcontentstrmodeint | None0o644.replaceboolTrue, overwrite an existing path.Patch.append()
content to an existing file at path. If the file lives in a lower image layer, it’s copied up first.
Parameters
pathstrcontentstrPatch.mkdir()
path. Idempotent: a no-op if the directory already exists.
Parameters
pathstrmodeint | None0o755.Patch.remove()
path. Idempotent: a no-op if the path doesn’t exist.
Parameters
pathstrPatch.copy_file()
src into the guest rootfs at dst.
Parameters
srcstrdststrmodeint | None0o644. None keeps the source mode.replaceboolTrue, overwrite an existing path at dst.Patch.copy_dir()
src into the guest rootfs at dst.
Parameters
srcstrdststrreplaceboolTrue, overwrite an existing path at dst.Patch.symlink()
link pointing to target.
Parameters
targetstrlinkstrreplaceboolTrue, overwrite an existing path at link.Types
SandboxConfig
Used by create() · create_with_progress()
The keyword arguments accepted bycreate() and create_with_progress(). There is no SandboxConfig object you construct directly; these are passed as **kwargs.
| Field | Type | Default | Description |
|---|---|---|---|
| image | str | ImageSource | - | OCI image, local path, or disk image. Required unless snapshot= is passed. Use Image.oci("python:3.12", upper_size_mib=8192) to set an OCI upper size |
| snapshot | str | os.PathLike | - | Snapshot artifact to boot from instead of image=. Mutually exclusive with image= |
| cpus | int | 1 | Virtual CPUs. This is a limit, not a reservation |
| max_cpus | int | same as cpus | Boot-time maximum possible virtual CPUs |
| memory | int | 512 | Guest memory in MiB. This is a limit, not a reservation |
| max_memory | int | same as memory | Boot-time maximum hotpluggable memory in MiB |
| workdir | str | - | Default working directory for commands |
| shell | str | "/bin/sh" | Shell for shell() calls |
| security | SecurityProfile | str | "default" | In-guest security profile. "restricted" sets no_new_privs, drops mount-admin capability from user commands, and forces nosuid,nodev on user mounts |
| hostname | str | - | Guest hostname |
| user | str | - | Default guest user |
| entrypoint | list[str] | - | Override the image’s stored ENTRYPOINT. Consulted by msb exec / msb run (CLI command resolution), not by sb.exec / sb.shell which pass cmd literally |
| init | str | dict | InitConfig | - | Hand off PID 1 to a guest init binary. See Custom init system and InitConfig for accepted shapes |
| replace | bool | False | Replace an existing sandbox with the same name (10s SIGTERM grace, then SIGKILL) |
| replace_with_timeout | float | 10 | Seconds to wait after SIGTERM before escalating to SIGKILL (0 skips SIGTERM). Implies replace=True |
| max_duration | float | - | Maximum sandbox lifetime in seconds |
| idle_timeout | float | - | Idle timeout in seconds |
| env | dict[str, str] | {} | Environment variables visible to all commands |
| scripts | dict[str, str] | {} | Named scripts mounted at /.msb/scripts/ and added to PATH |
| pull_policy | str | PullPolicy | "if-missing" | Image pull behavior |
| log_level | str | LogLevel | - | Override log verbosity |
| registry_auth | RegistryAuth | - | Private registry credentials |
| volumes | dict[str, MountConfig] | {} | Volume mounts. See Volumes |
| patches | list[PatchConfig] | [] | Rootfs modifications applied before boot |
| ports | dict[int, int] | Sequence[PortBinding] | {} | Port mappings. Dict form is TCP and binds to 127.0.0.1; use PortBinding for explicit bind addresses or UDP |
| network | Network | public_only | Network policy and configuration |
| secrets | list[SecretEntry] | [] | Secret injection |
| detached | bool | False | If True, spawn the sandbox in detached mode; call detach() before dropping the returned handle when it should keep running |
InitConfig
Used by create(init=…)
Custom init specification. Pass it (or one of the equivalent shorthand shapes) as theinit= kwarg to create() to hand PID 1 inside the guest off to your own init binary after agentd’s setup. Frozen dataclass. See Custom init system for image picks, shutdown semantics, and tradeoffs.
| Field | Type | Default | Description |
|---|---|---|---|
| cmd | str | - | Absolute path or "auto" to the init binary. Auto honors a known image ENTRYPOINT init before probing /sbin/init, /lib/systemd/systemd, and /usr/lib/systemd/systemd, and preserves attached init-entrypoint commands |
| args | tuple[str, ...] | () | Supplemental argv (argv[0] is implicitly cmd) |
| env | Mapping[str, str] | {} | Extra env vars merged on top of the inherited env |
init= kwarg follows the same shape as other structured create kwargs: a bare scalar for the simple case, or a dataclass / dict for the rich case.
| Form | Equivalent to |
|---|---|
init="auto" or init="/sbin/init" | InitConfig(cmd=...) |
init={"cmd": ..., "args": [...], "env": {...}} | dict equivalent of InitConfig |
init=InitConfig(cmd="/sbin/init", args=("--foo",)) | itself |
SecurityProfile
Used by create(security=…)
Sandbox-wide in-guest security profile. AStrEnum, so the string values are accepted directly.
| Value | Description |
|---|---|
"default" | Standard profile |
"restricted" | Sets no_new_privs, drops mount-admin capability from user commands, and forces nosuid,nodev on user mounts |
SandboxHandle
Returned by Sandbox.get() · Sandbox.list() · Sandbox.list_with()
A lightweight handle to an existing sandbox (running or stopped). Provides status, configuration, and lifecycle control without an active connection to the guest agent. You cannotexec or fs on a handle; call .start() or .connect() to upgrade to a full Sandbox.
| Property / Method | Type | Description |
|---|---|---|
| name | str | Sandbox name, up to 128 UTF-8 bytes |
| status | str | Current status. See SandboxStatus |
| config_json | str | Raw JSON configuration |
| created_at | float | None | Creation timestamp (ms since epoch) |
| updated_at | float | None | Last update timestamp (ms since epoch) |
| config() | dict[str, Any] | Parsed configuration |
| refresh() | Awaitable[SandboxHandle] | Re-fetch status and metadata, returning a fresh handle |
| ping() | Awaitable[SandboxPingResult] | Check agent reachability without refreshing idle activity; does not start stopped sandboxes |
| touch() | Awaitable[SandboxTouchResult] | Explicitly refresh idle activity; does not start stopped sandboxes |
| modify(…) | Awaitable[dict[str, Any]] | Plan or apply a configuration change; same kwargs as modify(). Does not start stopped sandboxes; changes persist for the next boot |
| connect(timeout=None) | Awaitable[Sandbox] | Connect to a running sandbox, optionally with an explicit timeout in seconds |
| start(*, detached=False) | Awaitable[Sandbox] | Start in attached or detached mode |
| stop(timeout=None) | Awaitable[None] | Gracefully shut down and wait until stopped state is observed |
| request_stop() | Awaitable[None] | Request graceful shutdown without waiting |
| kill(timeout=None) | Awaitable[None] | Force terminate and wait until stopped state is observed |
| request_kill() | Awaitable[None] | Request force termination without waiting |
| request_drain() | Awaitable[None] | Request graceful drain without waiting |
| wait_until_stopped() | Awaitable[SandboxStopResult] | Block until the sandbox reaches terminal state |
| remove() | Awaitable[None] | Delete sandbox and state |
| metrics() | Awaitable[SandboxMetrics] | Point-in-time resource metrics |
| logs(…) | Awaitable[list[LogEntry]] | Read captured exec.log (works without starting) |
| log_stream(…) | Awaitable[LogStream] | Stream captured log entries (works without starting) |
| snapshot(name) | Awaitable[Snapshot] | Create a named snapshot of the sandbox |
| snapshot_to(path) | Awaitable[Snapshot] | Create a snapshot at a path |
SandboxPingResult
Returned by ping()
Agent reachability result.| Property | Type | Description |
|---|---|---|
| name | str | Sandbox name |
| latency_ms | float | Round-trip latency in milliseconds |
SandboxTouchResult
Returned by touch()
Explicit idle-refresh result.| Property | Type | Description |
|---|---|---|
| name | str | Sandbox name |
| activity_seq | int | Monotonic activity sequence after the touch |
SandboxStopResult
Returned by wait_until_stopped()
Observed terminal sandbox state returned bywait_until_stopped().
| Property | Type | Description |
|---|---|---|
| name | str | Sandbox name |
| status | str | Terminal status that was observed. See SandboxStatus |
| exit_code | int | None | Process exit code when it is available |
| signal | int | None | Terminating signal number when the sandbox was killed by a signal |
| observed_at | float | When the terminal state was observed (ms since epoch) |
| source | str | None | Where the terminal observation came from |
SandboxStatus
Used by SandboxHandle.status · SandboxStopResult.status
The string status values a sandbox can report. AStrEnum, exposed as plain strings on status fields.
| Value | Description |
|---|---|
"running" | Guest agent is ready; exec, shell, fs work |
"stopped" | VM shut down; configuration persisted; can be restarted |
"crashed" | VM exited unexpectedly (kernel panic, OOM, etc.) |
"draining" | Graceful shutdown in progress; existing commands finish, new ones rejected |
"paused" | VM paused |
SandboxMetrics
Returned by metrics() · metrics_stream()
Point-in-time resource usage snapshot.| Field | Type | Description |
|---|---|---|
| cpu_percent | float | CPU usage as a percentage |
| vcpu_time_ns | int | Cumulative vCPU time consumed since boot, in nanoseconds |
| memory_bytes | int | Current memory usage in bytes |
| memory_available_bytes | int | None | Guest-reported available memory in bytes when known |
| memory_host_resident_bytes | int | None | Host-resident memory backing the guest in bytes when known |
| memory_limit_bytes | int | Memory limit in bytes |
| disk_read_bytes | int | Total bytes read from disk since boot |
| disk_write_bytes | int | Total bytes written to disk since boot |
| net_rx_bytes | int | Total bytes received over the network since boot |
| net_tx_bytes | int | Total bytes sent over the network since boot |
| upper_used_bytes | int | None | Guest-visible OCI upper filesystem used bytes when the protected reporter is available and fresh |
| upper_free_bytes | int | None | Guest-visible OCI upper filesystem free bytes when the protected reporter is available and fresh |
| upper_host_allocated_bytes | int | None | Host-allocated bytes for the writable OCI upper image when available |
| uptime_ms | int | Time since the sandbox was created (ms) |
| timestamp_ms | float | When this measurement was taken (ms since epoch) |
MetricsStream
Returned by metrics_stream()
Async stream for receiving periodic metrics snapshots.| Method | Returns | Description |
|---|---|---|
__aiter__ / __anext__ | SandboxMetrics | Use with async for |
LogEntry
Returned by logs() · iterated from LogStream
A single captured log entry returned bylogs() or iterated from a LogStream.
| Property / Method | Type | Description |
|---|---|---|
| timestamp_ms | float | Wall-clock capture time (ms since Unix epoch, UTC) |
| source | LogSource | Where the chunk came from |
| session_id | int | None | Relay-monotonic session id; None for "system" entries |
| cursor | str | Opaque resume token; pass back via log_stream(from_cursor=...) |
| data | bytes | The chunk’s raw bytes |
| text() | str | Convenience: UTF-8 decode of data (lossy; invalid bytes are replaced) |
LogStream
Returned by log_stream()
Async stream ofLogEntry values, returned by log_stream().
| Method | Returns | Description |
|---|---|---|
__aiter__ / __anext__ | LogEntry | Use with async for |
LogSource
Used by LogEntry.source · logs(sources=…)
The string values thesource field on a LogEntry can take, also accepted by logs(sources=[...]) and log_stream(sources=[...]). The read form additionally accepts "all".
| Value | Description |
|---|---|
"stdout" | Captured from a session’s stdout (pipe mode, streams stayed separated) |
"stderr" | Captured from a session’s stderr (pipe mode) |
"output" | Captured from a session running in PTY mode. PTY allocation merges stdout and stderr at the kernel level inside the guest, so they arrive as a single stream, tagged "output" rather than mislabeled as "stdout" |
"system" | Synthetic entry: lifecycle markers in exec.log plus runtime/kernel diagnostic lines merged in at read time when "system" is requested |
"all" | Read shorthand for all four sources (accepted by sources=, never returned on an entry) |
LogLevel
Used by create(log_level=…)
Sandbox process log verbosity. AStrEnum, so the string values are accepted directly.
| Value | Description |
|---|---|
"trace" | Most verbose, all diagnostic output |
"debug" | Debug and higher |
"info" | Info and higher |
"warn" | Warnings and errors only |
"error" | Errors only |
PullPolicy
Used by create(pull_policy=…)
Controls when the SDK fetches an OCI image from the registry. AStrEnum, so the string values are accepted directly.
| Value | Description |
|---|---|
"always" | Pull the image every time, even if cached locally |
"if-missing" | Pull only if the image is not already cached. This is the default |
"never" | Never pull; fail if the image is not cached locally |
RegistryAuth
Used by create(registry_auth=…)
Credentials for authenticating to a private container registry. Frozen dataclass; construct directly or viaRegistryAuth.basic(username, password).
| Field | Type | Description |
|---|---|---|
| username | str | Registry username |
| password | str | Registry password |
PatchConfig
Returned by Patch.* factory methods · used by create(patches=…)
A single rootfs patch. Produced by thePatch factory; you’d normally not construct one directly. Frozen dataclass.
| Field | Type | Description |
|---|---|---|
| kind | str | One of "text", "file", "copy_file", "copy_dir", "symlink", "mkdir", "remove", "append" |
| path | str | None | Absolute guest path (text / mkdir / remove / append) |
| content | str | None | Text content (text / append) |
| src | str | None | Host source path (copy_file / copy_dir) |
| dst | str | None | Guest destination path (copy_file / copy_dir) |
| target | str | None | Symlink target |
| link | str | None | Symlink path |
| mode | int | None | File / directory mode (e.g. 0o644) |
| replace | bool | When True, overwrite an existing path at the destination. Defaults to False |
PullSession
Returned by create_with_progress()
Returned bycreate_with_progress(). The factory itself is synchronous; use the returned session as an async context manager to track image pull progress.
PullEvent
Iterated from PullSession.progress
Native event object emitted byPullSession.progress. Inspect event_type and the fields relevant to that event; fields that do not apply to a particular event are None.
| Field | Type | Description |
|---|---|---|
| event_type | str | Event tag, e.g. "resolving", "resolved", "layer_download_progress", "complete" |
| reference | str | None | Image reference being pulled |
| manifest_digest | str | None | Resolved manifest digest |
| layer_count | int | None | Number of layers |
| total_download_bytes | int | None | Total bytes to download across layers |
| layer_index | int | None | Index of the layer this event concerns |
| digest | str | None | Layer blob digest |
| diff_id | str | None | Layer diff id |
| downloaded_bytes | int | None | Bytes downloaded so far for the layer |
| total_bytes | int | None | Total bytes for the layer |
| bytes_read | int | None | Bytes read during materialization |