Typical flow
Static methods
Sandbox::builder()
Example
Example
SandboxBuilder for all available options.
Parameters
nameimpl Into<String>Returns
Sandbox::get()
Example
Example
Parameters
name&strReturns
Sandbox::list()
Example
Example
Returns
Sandbox::remove()
Example
Example
Parameters
name&strSandbox::start()
Example
Example
Parameters
name&strReturns
Sandbox::start_detached()
Parameters
name&strReturns
Instance methods
sb.config()
Example
Example
Returns
sb.detach()
Example
Example
Sandbox::get().
sb.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.
sb.request_drain()
wait_until_stopped() when the caller needs stopped-state observation.
sb.fs()
Example
Example
Returns
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.
sb.kill_with_timeout()
timeout for stopped-state observation.
sb.request_kill()
sb.metrics()
Example
Example
Returns
sb.metrics_stream()
Example
Example
interval duration.
Parameters
intervalDurationReturns
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 LogSource::System to also include synthetic lifecycle markers and runtime/kernel diagnostic lines. logs() is synchronous because it’s a pure file read.
Parameters
opts&LogOptionstail, since, until, sources. LogOptions::default() returns everything for the default sources.Returns
sb.ping()
Example
Example
core.ping, returns the SDK-measured round-trip latency, and does not refresh the sandbox idle timer.
Returns
sb.touch()
Example
Example
core.touch; use it when keeping an idle sandbox alive is intentional.
Returns
sb.modify()
Example
Example
dry_run() to preview or apply() to commit; both return a SandboxModificationPlan labeling each change live, next start, requires restart, or unsupported. Apply is all-or-nothing.
CPU 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.
See SandboxModificationBuilder for all setters and msb modify for the CLI.
Returns
dry_run() or apply().sb.name()
Returns
sb.owns_lifecycle()
true in attached mode (sandbox stops when your process exits), false in detached mode.
Returns
true if attached.sb.remove_persisted()
Example
Example
sb.request_stop()
wait_until_stopped() when the caller needs the terminal state.
sb.stop()
Example
Example
sb.stop_with_timeout()
Duration::ZERO skips graceful shutdown and force-kills immediately.
sb.stop_and_wait()
Example
Example
stop() or stop_with_timeout() when the caller only needs stopped-state observation.
Returns
sb.wait()
Example
Example
Returns
sb.wait_until_stopped()
| Type | Description |
|---|---|
SandboxStopResult | Observed terminal sandbox state |
SandboxBuilder
Builder for configuring a sandbox before creation. Obtained viaSandbox::builder(name). Every setter returns Self, so calls chain. Examples are shown on the methods where usage is non-obvious; simple setters are demonstrated by the Typical flow above.
.build()
SandboxConfig without booting the sandbox. Validates the configuration and, if from_snapshot was called, opens the snapshot manifest to pin its image reference and upper-layer source. For booting, use create instead; call detached(true) first for background mode. create() calls build internally.
Returns
.cpus()
1.
Parameters
countu8.max_cpus()
Parameters
countu8.create()
Returns
.detached()
Example
Example
false.
Parameters
detachedbooltrue, create the sandbox in detached mode..create_detached()
Example
Example
.detached(true).create(). Prefer detached(true) with create() for new code so attached and detached creation use the same flow.
Returns
.disable_network()
.entrypoint()
msb exec / msb run against this sandbox from the terminal. Sandbox::exec and Sandbox::shell do not consult it; they pass cmd literally to the guest agent. Use this when configuring a sandbox via the SDK for later CLI attachment.
Parameters
cmdimpl IntoIterator.env()
exec_with) are merged on top.
Parameters
keyimpl Into<String>valueimpl Into<String>.hostname()
Parameters
hostnameimpl Into<String>.idle_timeout()
Parameters
secsu64.init()
Example
Example
cmd after agentd finishes its boot-time setup. The agent forks; the parent execs the init and becomes PID 1, the agent continues as a child process. See Custom init system for image picks, shutdown semantics, and tradeoffs.
cmd is either an absolute path inside the guest rootfs or the literal "auto". Auto first honors a known init at the start of the image ENTRYPOINT, such as /init in s6-overlay images, then falls back to probing /sbin/init, /lib/systemd/systemd, and /usr/lib/systemd/systemd inside the guest. When attached msb run uses an image-declared init entrypoint, the remaining ENTRYPOINT plus CMD or trailing command is passed to that init instead of direct-executed through agentd. For init binaries that take argv or extra env (rare), use init_with.
Parameters
cmdimpl Into<PathBuf>“auto”..init_with()
Example
Example
init, but with a closure-builder for argv and env vars. Mirrors exec_with in shape. The builder exposes arg, args, env, and envs. Calling init or init_with more than once overwrites, unlike env, which appends. The init is one-shot pre-boot.
Parameters
cmdimpl Into<PathBuf>fFnOnce(InitOptionsBuilder).image()
Parameters
imageimpl IntoImage.image_with()
Example
Example
Parameters
fFnOnce(ImageBuilder).log_level()
Parameters
levelLogLevel.max_duration()
Parameters
secsu64.memory()
512 MiB.
Parameters
sizeimpl Into<Mebibytes>.max_memory()
Parameters
sizeimpl Into<Mebibytes>.network()
Parameters
.patch()
PatchBuilder for the operations.
Parameters
.port()
127.0.0.1.
Parameters
host_portu16guest_portu16.port_bind()
0.0.0.0.
Parameters
host_bindIpAddrhost_portu16guest_portu16.port_udp()
127.0.0.1.
Parameters
host_portu16guest_portu16.port_udp_bind()
Parameters
host_bindIpAddrhost_portu16guest_portu16.pull_policy()
Parameters
policyPullPolicy.registry()
Example
Example
Parameters
.replace()
.script()
/.msb/scripts/ inside the guest. Scripts are added to PATH and can be called by name via exec() or shell().
Parameters
nameimpl Into<String>contentimpl Into<String>.secret()
Parameters
.secret_env()
.secret(|s| s.env(env_var).value(value).allow_host(allowed_host)).
Parameters
env_varimpl Into<String>= or NUL).valueimpl Into<String>allowed_hostimpl Into<String>.shell()
Sandbox::shell(). Default: /bin/sh.
Parameters
shellimpl Into<String>“/bin/bash”)..user()
Parameters
userimpl Into<String>.volume()
Parameters
guest_pathimpl Into<String>.workdir()
Parameters
pathimpl Into<String>PatchBuilder
Fluent builder for the ordered list of pre-boot rootfs patches. Used inSandboxBuilder::patch(|p| p...). Each method appends one operation; calls are chainable. By default a method 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.
.append()
content to an existing file at path. If the file lives in a lower image layer, it’s copied up first.
Parameters
pathimpl Into<String>contentimpl Into<String>.copy_dir()
src into the guest rootfs at dst.
Parameters
srcimpl Into<PathBuf>dstimpl Into<String>replacebooltrue, overwrite an existing path at dst..copy_file()
src into the guest rootfs at dst.
Parameters
srcimpl Into<PathBuf>dstimpl Into<String>modeOption<u32>Some(0o644). None keeps the source mode.replacebooltrue, overwrite an existing path at dst..file()
path.
Parameters
pathimpl Into<String>contentimpl Into<Vec<u8>>modeOption<u32>Some(0o644).replacebooltrue, overwrite an existing path..mkdir()
path. Idempotent: a no-op if the directory already exists.
Parameters
pathimpl Into<String>modeOption<u32>Some(0o755)..remove()
path. Idempotent: a no-op if the path doesn’t exist.
Parameters
pathimpl Into<String>.symlink()
link pointing to target.
Parameters
targetimpl Into<String>linkimpl Into<String>replacebooltrue, overwrite an existing path at link..text()
path.
Parameters
pathimpl Into<String>contentimpl Into<String>modeOption<u32>Some(0o644).replacebooltrue, overwrite an existing path.SandboxModificationBuilder
Fluent builder for changing an existing sandbox’s configuration. Obtained viasb.modify() or SandboxHandle::modify(). Nothing happens until you finish with dry_run() or apply(); both return a SandboxModificationPlan that labels each change live, next start, requires restart, or unsupported.
Apply is all-or-nothing: if any change conflicts, is unsupported, or needs a restart you did not allow, the call fails and nothing changes.
CPU and memory changes take effect immediately on a running sandbox as long as the new values stay within max_cpus / max_memory; raising those limits requires a restart, so reserve headroom at create time. Env and workdir changes affect future execs only; running processes keep their current environment (the plan notes this as a warning). The CLI equivalent is msb modify.
.apply()
next_start(), are saved and take effect on the next start. With restart(), the sandbox is stopped and started so that restart-required changes take effect.
A live CPU or memory resize can take a moment to settle. The returned plan’s resize_status reports progress per resource; see ResourceResizeStatus.
Returns
applied: true and live resize outcomes in resize_status..cpus()
max_cpus; otherwise it requires a restart.
Parameters
cpusu8.max_cpus()
Parameters
max_cpusu8.dry_run()
Example
Example
Returns
applied: false..env()
Parameters
keyimpl Into<String>valueimpl Into<String>.remove_env()
env().
Parameters
keyimpl Into<String>.label()
Parameters
keyimpl Into<String>valueimpl Into<String>.remove_label()
Parameters
keyimpl Into<String>.memory()
max_memory; otherwise it requires a restart.
Parameters
sizeimpl Into<Mebibytes>.memory_mib()
memory() with an explicit unit.
Parameters
memory_mibu32.max_memory()
Parameters
sizeimpl Into<Mebibytes>.max_memory_mib()
max_memory() with an explicit unit.
Parameters
max_memory_mibu32.next_start()
next start.
.restart()
apply() stops the sandbox, persists the config, and starts it again so the changes become active now.
.secret()
Example
Example
SecretPatchBuilder closure. The spec mirrors the create-time SecretBuilder vocabulary, and the planner diffs it against the existing config to infer the change: a secret that does not exist yet is added, material on an existing secret rotated, and host or placeholder differences update those aspects. Declaring the same secret again replaces the earlier spec; removal is always explicit through remove_secret().
Parameters
fFnOnce(SecretPatchBuilder).remove_secret()
Parameters
nameimpl Into<String>.workdir()
Parameters
pathimpl Into<String>Types
LogEntry
Returned by logs()
A single captured log entry returned bylogs().
| Field | Type | Description |
|---|---|---|
| timestamp | DateTime<Utc> | Wall-clock capture time on the host |
| source | LogSource | Where the chunk came from |
| session_id | Option<u64> | Relay-monotonic session id; None for System entries |
| data | Bytes | The chunk’s bytes (UTF-8 lossy decoded by default; raw bytes if --raw mode was used) |
LogLevel
Used by log_level()
Sandbox process log verbosity.| Value | Description |
|---|---|
Error | Errors only |
Warn | Warnings and errors only |
Info | Info and higher |
Debug | Debug and higher |
Trace | Most verbose - all diagnostic output |
LogOptions
Used by logs()
Filters passed tologs(). All fields optional. LogOptions::default() returns everything for the default sources (Stdout + Stderr + Output).
| Field | Type | Description |
|---|---|---|
| tail | Option<usize> | Show only the last N entries after other filters apply |
| since | Option<DateTime<Utc>> | Inclusive lower bound on entry timestamp |
| until | Option<DateTime<Utc>> | Exclusive upper bound on entry timestamp |
| sources | Vec<LogSource> | Sources to include. Empty = [Stdout, Stderr, Output] (the default user-program sources). Add System to merge runtime/kernel diagnostics. |
LogSource
Used by LogEntry.source · LogOptions.sources
Tag indicating where a captured log entry came from.| 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. |
SandboxPingResult
Returned by ping() · SandboxHandle.ping()
Result of a successful agent reachability check.| Field | Type | Description |
|---|---|---|
| name | String | Sandbox name that was pinged |
| latency | Duration | SDK-measured round-trip latency |
SandboxTouchResult
Returned by touch() · SandboxHandle.touch()
Result of an explicit idle-timer refresh.| Field | Type | Description |
|---|---|---|
| name | String | Sandbox name that was touched |
| activity_seq | u64 | Agent activity sequence after the touch was recorded |
PullPolicy
Used by pull_policy()
Controls when the SDK fetches an OCI image from the registry.| Value | Description |
|---|---|
Always | Pull the image every time, even if cached locally |
IfMissing | 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 registry()
Credentials for authenticating to a private container registry.| Variant | Fields | Description |
|---|---|---|
Basic | - username: String - password: String | Username and password authentication |
RegistryConfigBuilder
Used by registry()
Builder passed toregistry() for per-sandbox registry connection settings.
| Method | Description |
|---|---|
auth(auth: RegistryAuth) | Set explicit credentials for the image registry |
insecure() | Use plain HTTP for the registry |
ca_certs(pem_data: Vec<u8>) | Trust additional PEM-encoded CA certificates |
SandboxConfig
Returned by config() · build()
The full configuration of a sandbox. Obtained viaconfig() or built via SandboxBuilder. Contains all settings used to create the sandbox.
| Field | Type | Description |
|---|---|---|
| cpus | u8 | Number of virtual CPUs |
| env | Vec<(String, String)> | Environment variables |
| idle_timeout_secs | Option<u64> | Idle timeout |
| image | RootfsSource | Root filesystem source (OCI, bind, or disk image) |
| max_duration_secs | Option<u64> | Maximum lifetime |
| max_cpus | u8 | Boot-time maximum possible virtual CPUs |
| max_memory_mib | u32 | Boot-time maximum hotpluggable memory in MiB |
| memory_mib | u32 | Guest memory in MiB |
| name | String | Sandbox name, up to 128 UTF-8 bytes |
| patches | Vec<Patch> | Rootfs patches |
| scripts | Vec<(String, String)> | Named scripts |
| shell | Option<String> | Shell for shell() calls |
| volumes | Vec<VolumeMount> | Volume mounts |
| workdir | Option<String> | Default working directory |
SandboxHandle
Returned by Sandbox::get() · Sandbox::list()
A lightweight handle to an existing sandbox (running or stopped). Obtained viaSandbox::get() or Sandbox::list(). Provides status, configuration, and lifecycle control without an active connection to the guest agent. You cannot exec or fs on a handle - call .start() or .connect() to upgrade to a full Sandbox.
| Property / Method | Type | Description |
|---|---|---|
| config() | Result<SandboxConfig> | Parsed configuration |
| config_json() | &str | Raw JSON configuration |
| connect() | Result<Sandbox> | Connect to a running sandbox; returns an error if it doesn’t respond within ten seconds |
| connect_with_timeout(timeout) | Result<Sandbox> | Same as connect() with an explicit timeout |
| created_at() | Option<DateTime<Utc>> | Creation timestamp |
| kill() | Result<()> | Force terminate and wait until stopped state is observed |
| kill_with_timeout(timeout) | Result<()> | Same as kill() with an explicit observation timeout |
| logs() | Result<Vec<LogEntry>> | Read captured exec.log (works without starting) |
| metrics() | Result<SandboxMetrics> | Point-in-time resource metrics |
| modify() | SandboxModificationBuilder | Start planning a configuration change (works without starting; changes on a stopped sandbox persist for the next boot) |
| name() | &str | Sandbox name, up to 128 UTF-8 bytes |
| ping() | Result<SandboxPingResult> | Check agent reachability without refreshing idle activity |
| remove() | Result<()> | Delete sandbox and state |
| request_drain() | Result<()> | Request graceful drain without waiting |
| request_kill() | Result<()> | Request force termination without waiting |
| request_stop() | Result<()> | Request graceful shutdown without waiting |
| start() | Result<Sandbox> | Start in attached mode |
| start_detached() | Result<Sandbox> | Start in detached mode |
| status() | SandboxStatus | Current status |
| stop() | Result<()> | Gracefully shut down. Waits up to ten seconds for pending writes to flush, then force-kills |
| stop_with_timeout(timeout) | Result<()> | Same as stop() with an explicit timeout; Duration::ZERO force-kills immediately |
| touch() | Result<SandboxTouchResult> | Explicitly refresh the sandbox idle timer |
| updated_at() | Option<DateTime<Utc>> | Last update timestamp |
| wait_until_stopped() | Result<SandboxStopResult> | Block until terminal state is observed |
SandboxModificationPlan
Returned by dry_run() · apply()
Dry-run or apply plan for a sandbox modification. Values never appear in a plan: secret entries carry only guest-visible references.| Field | Type | Description |
|---|---|---|
| sandbox | String | Sandbox being modified |
| status | String | Sandbox status used for classification ("running", "stopped", …) |
| applied | bool | Whether the changes were applied; false for dry runs |
| policy | ModificationPolicy | Policy used to produce the plan: NoRestart (default), NextStart, or Restart |
| changes | Vec<PlannedChange> | Planned changes, one entry per field or secret |
| conflicts | Vec<ModificationConflict> | Conflicts (field + message) that must be resolved before the patch can apply |
| warnings | Vec<ModificationWarning> | Non-fatal warnings (field + message) about the patch or current runtime capabilities, e.g. the future-execs-only env caveat |
| resize_status | Vec<ResourceResizeStatus> | Live resource resize outcomes, populated by apply() when a live change ran |
SecretPatchBuilder
Used by secret()
Fluent builder for one declarative secret patch insideSandboxModificationBuilder::secret(). It shares the create-time SecretBuilder vocabulary: name the secret, provide material by source reference or raw value, set the placeholder when needed, and declare the allowed hosts.
Import path: microsandbox::sandbox::SecretPatchBuilder.
Prefer source(...) over value(...) when the value can be referenced; see the at-rest note on secret_env() and Secrets for the full model.
.env()
Parameters
nameimpl Into<String>.source()
SecretSource reference. The durable config records only the reference, and the value is resolved host-side when the change applies. Mutually exclusive with value(...).
Parameters
sourceSecretSource.value()
Debug, and never enters the plan. Applying a value persists it into the durable config until a later source-based rotate migrates it to a reference, the same at-rest property as secret_env(). Mutually exclusive with source(...).
Parameters
valueimpl Into<String>.placeholder()
requires restart on a running sandbox.
Parameters
placeholderimpl Into<String>.allow_host()
api.example.com, *.example.org, or *. A non-empty list replaces the secret’s current allow-list; an empty list leaves it unchanged. A new secret needs at least one.
Parameters
hostimpl Into<String>*.SecretSource
Used by SecretPatchBuilder.source()
Host-side source for secret material. The source is resolved when the modification applies, and plans only show guest-visible references. Import path:microsandbox::sandbox::SecretSource.
| Variant | Field | Description |
|---|---|---|
Env | var: String | Read the value from a host environment variable at apply time |
Store | reference: String | Reserved for a host-side secret store reference; current modifiers report it as unsupported |
PlannedChange
Used by SandboxModificationPlan.changes
One planned modification entry. This enum has aConfig variant for ordinary configuration fields and a Secret variant for secret changes.
| Variant | Type | Description |
|---|---|---|
Config | ConfigPlannedChange | Ordinary config change |
Secret | SecretPlannedChange | Secret change. Values are omitted by construction; references are guest-visible only |
ConfigPlannedChange
Variant of PlannedChange::Config
Ordinary configuration change in a modification plan.| Field | Type | Description |
|---|---|---|
| field | String | Config field being changed |
| change | ChangeKind | Added, Updated, or Removed |
| before | Option<String> | Previous safe visible state |
| after | Option<String> | New safe visible state |
| disposition | ModificationDisposition | When or whether the change can take effect |
| reason | Option<String> | Human-readable reason for the classification, when useful |
SecretPlannedChange
Variant of PlannedChange::Secret
Secret change in a modification plan. Values are omitted by construction;before_ref and after_ref are guest-visible references.
| Field | Type | Description |
|---|---|---|
| field | String | Always "secret" |
| name | String | Stable secret identity, usually the environment variable name |
| change | SecretChangeKind | Added, Rotated, Removed, Renamed, HostsUpdated, or PlaceholderUpdated |
| before_ref | Option<String> | Previous guest-visible reference or placeholder |
| after_ref | Option<String> | New guest-visible reference or placeholder |
| disposition | ModificationDisposition | When or whether the change can take effect |
| allow_hosts | Vec<String> | Allowed hosts after the requested change |
| reason | Option<String> | Human-readable reason for the classification, when useful |
ModificationDisposition
Used by ConfigPlannedChange.disposition · SecretPlannedChange.disposition
When or whether a planned change can take effect. Serializes as the quoted strings below.| Value | Description |
|---|---|
Live ("live") | Applies to the running VM now |
NextStart ("next start") | Persists to the desired config and applies the next time the sandbox starts |
RequiresRestart ("requires restart") | Needs a restart before it can take effect; apply() refuses it unless the restart() policy is selected |
Unsupported ("unsupported") | Cannot be changed by modify |
ResourceResizeStatus
Used by SandboxModificationPlan.resize_status
Runtime convergence status for a live resource resize. Enforcement applies immediately; the guest converges asynchronously (onlining CPUs, plugging memory blocks).| Field | Type | Description |
|---|---|---|
| resource | ResourceKind | Cpus or Memory |
| requested | String | Requested value |
| actual | String | Actual value observed in the guest/runtime |
| enforced | String | Host/VMM-enforced value |
| state | ResourceConvergenceState | Convergence state, see below |
| State | Description |
|---|---|
Accepted | The runtime accepted the request |
Converging | The guest and VMM are still converging on the requested state |
Applied | Desired, actual, and enforced state match |
GuestRefused | The guest would not cooperate; the host enforces the new limit anyway |
Failed | The resize failed |
SandboxStopResult
Observed terminal sandbox state returned bywait_until_stopped().
| Field | Type | Description |
|---|---|---|
| name | String | Sandbox name |
| status | SandboxStatus | Terminal status that was observed |
| exit_code | Option<i32> | Process exit code when available from an owned child process |
| signal | Option<i32> | Terminating signal when available from an owned child process |
| observed_at | DateTime<Utc> | When the terminal state was observed |
| source | Option<String> | Description of the observation source |
SandboxMetrics
Returned by metrics() · metrics_stream()
Point-in-time resource usage snapshot.| Field | Type | Description |
|---|---|---|
| cpu_percent | f32 | CPU usage as a percentage |
| disk_read_bytes | u64 | Total bytes read from disk since boot |
| disk_write_bytes | u64 | Total bytes written to disk since boot |
| memory_bytes | u64 | Current memory usage in bytes |
| memory_limit_bytes | u64 | Memory limit in bytes |
| net_rx_bytes | u64 | Total bytes received over the network since boot |
| net_tx_bytes | u64 | Total bytes sent over the network since boot |
| upper_used_bytes | Option<u64> | Guest-visible OCI upper filesystem used bytes when the protected reporter is available and fresh |
| upper_free_bytes | Option<u64> | Guest-visible OCI upper filesystem free bytes when the protected reporter is available and fresh |
| upper_host_allocated_bytes | Option<u64> | Host-allocated bytes for the writable OCI upper image when available |
| timestamp | DateTime<Utc> | When this measurement was taken |
| uptime | Duration | Time since the sandbox was created |
SandboxStatus
Used by SandboxHandle.status()
| Value | Description |
|---|---|
Crashed | VM exited unexpectedly (kernel panic, OOM, etc.) |
Draining | Graceful shutdown in progress; existing commands finish, new ones rejected |
Running | Guest agent is ready; exec, shell, fs work |
Stopped | VM shut down; configuration persisted; can be restarted |