Documentation Index
Fetch the complete documentation index at: https://docs.microsandbox.dev/llms.txt
Use this file to discover all available pages before exploring further.
New features
Native SSH and SFTP Sandboxes gain a first-class SSH surface across the CLI and every SDK without runningsshd inside the guest. msb ssh <name> opens an interactive session, msb ssh <name> -- <cmd> runs a one-shot command, and msb ssh serve exposes an external SSH transport that standard ssh and sftp clients can connect to after msb ssh authorize registers a key. The SDK SSH namespace in Rust, TypeScript, Python, and Go supports interactive attach, exec, and SFTP, plus an in-process server mode.
msb run --oci-upper-size 8G ... sets it from the CLI, and sandbox_defaults.oci.upper_size_mib sets the deployment-wide default. The Rust, TypeScript, Python, and Go SDKs gained matching surfaces. Fresh OCI roots default to 4096 MiB; snapshot upper layers are copied as-is.
msb copy and rootfs patch flags
A new msb copy (alias msb cp) moves files host-to-sandbox, sandbox-to-host, within a single sandbox, or across two sandboxes, including recursive directories and symlinks. msb run and msb create accept --copy, --copy-file, --copy-dir, --mkdir, and --rm so a fresh sandbox can be prepared without a separate setup step. Guest paths are validated before the sandbox is created so typos fail fast.
ro and noexec
Volume mounts now use the Docker-style source:guest:options shape everywhere and accept ro, rw, nosuid, noexec, and fstype=... (for disk-image volumes). The host-side passthroughfs enforces read-only mounts so the guest cannot remount them writable, and the runtime drops mount-admin capability before user execs so user commands cannot undo ro or noexec. Direct SDK configs are validated before create or start so unsafe guest paths and policy combinations fail early.
msb --secret accepts a new ENV@HOST form that reads the value from the same-named host environment variable, so common API keys no longer need to be inlined in command arguments. The existing ENV=VALUE@HOST form is preserved for explicit values and renames. Missing, empty, or non-UTF-8 sources produce a clear error.
- Sandbox name byte limit. Sandbox names are now validated as 1 to 128 UTF-8 bytes everywhere (CLI, all SDKs, metrics), with a typed error rather than a silent truncation. Names longer than 128 bytes are now rejected. See Sandbox lifecycle.
- Host UDP published ports. Published-port mappings now support UDP end to end, with bounded peer allocation and a VM round-trip test. See the networking overview.
- Typed Python network destinations. The Python SDK now accepts
Ip,Cidr,Domain,DomainSuffix,Group, andAnydestinations onRule, alongside the legacy string form. See the Python networking reference. - Guest clock sync. The runtime now sends a
core.clock.syncframe on startup, every 60 seconds, and after the host wall clock jumps by more than 6 seconds. Sandboxes that survive a host sleep or suspend resume with the correct wall time instead of drifting until restart.
Bug fixes
- Published-port traffic from the host no longer stalls for several seconds before the guest receives the connection; the host listener now wakes the smoltcp poll loop immediately after accepting.
- DNS-over-UDP responses are now delivered back to the guest as real Ethernet frames, so guest resolvers no longer occasionally time out even when the upstream query succeeded.
- TLS-intercepted uploads no longer hang or end with EOF on large request bodies; the upstream stream is flushed after each forwarded plaintext batch.
- TLS secret substitution is now tied to the original guest destination, DNS-cache binding, SNI, HTTP/1
Host, and observed HTTP/2:authority, so spoofed or fronted hosts cannot trick the proxy into injecting real secret values. HTTP/2 HEADERS are decoded and re-encoded with bounded HPACK state, and HTTP/1 chunked and fixed-length bodies are rewritten safely. - Body-continuation chunks on long-lived TLS connections no longer corrupt binary uploads with
U+FFFD, leak header-only secrets into request bodies, or skip substitution on pipelined follow-up requests. - SNI matching now enforces
denyrules even when the guest connects to a literal IP with no DNS-cache binding, closing a path that previously let denied domains through over direct-IP HTTPS. - Bind mounts of host-owned directories are now mapped to the guest’s resolved default user, so non-root guests can read and write project files mounted from the host. Other host owners surface as
65534:65534. - Sandboxes with very long names now boot reliably; the agent relay socket is placed under a fixed-length runtime path and validated against
SUN_LENbefore spawn, with the legacy socket path retained as a fallback. - Network policies in the Python and Go SDKs treat bare IPv4 and IPv6 literals as host CIDR matches instead of trying to resolve them as domains.
Sandbox.exec(cmd, options_dict)andexec_stream(cmd, options_dict)in the Python SDK now actually applyargsand other options, andshell_with(..., timeout=...)honors the same timeout path asexec_with().create_with_progress()is callable synchronously again.- Sandboxes started under microsandbox 0.4 keep working for exec and shell after upgrading to 0.5; filesystem and SFTP operations against a pre-0.5 live sandbox now fail with a clear restart hint instead of a protocol-level error, and legacy OCI config rows are migrated to the new shape on first contact.
- Split irqchip is re-enabled for x86 Linux VMs, restoring the previous interrupt routing path now that the underlying libkrun fix has shipped.
- Released binaries now ship with the SSH feature enabled, so the new
msb sshcommands work without rebuilding from source.