docs/changelog/2026-07-24.mdx
Composable network profiles
Network policy is now built from named profiles instead of ad-hoc presets. Pass one or more of public, private, and host to --net on the CLI, or to NetworkPolicy.from_profiles() / fromProfiles() / FromProfiles() in the SDKs. --net is repeatable and accepts a comma-separated list, plus the terminal values all and none. Explicit --net-rule entries keep first-match precedence and now understand allow@dns / deny@dns targets, so DNS answers are policy-aware instead of implicitly allowed.
The IPv4 and IPv6 unspecified addresses are excluded from public, closing a DNS-rebinding gap. This is a breaking change for pre-1.0 callers: the legacy public_only and non_local presets are removed. Migrate to from_profiles("public") or the CLI equivalent.
msb run --net public,private --net-rule 'allow@dns:api.example.com' python
from microsandbox import NetworkPolicy, Rule
policy = NetworkPolicy.from_profiles("public", "private").with_rules(
Rule.allow_dns("api.example.com"),
Rule.deny_dns("telemetry.example.com"),
)
const policy = NetworkPolicy.fromProfiles("public").withRules(
Rule.allowDns("api.example.com"),
Rule.denyDns("telemetry.example.com"),
);
See the networking overview.
Bidirectional snapshot migration with msb self downgrade
Microsandbox now treats snapshots created on v0.6.6 and v0.6.7 as fully interchangeable. It migrates older manifest.json artifacts to the finalized snapshot.json descriptor on startup, explicit open, reindex, and archive load, enforces sparse payload integrity, and rejects duplicate keys. It also retains the original descriptor bytes so a downgrade produces the exact prior artifact.
msb self downgrade 0.6.6 --yes performs a durable, journaled downgrade with SHA-256 verification and a database backup. If the process is interrupted, startup refuses to continue until recovery finishes, so you cannot end up with a half-migrated store.
Each SDK also exposes the new projections, so tooling can tell the current snapshot state and any pending migration apart. In Rust these are Snapshot::state_kind() and migration_state(); in Python, snapshot.state_kind and snapshot.migration_state; in TypeScript, .stateKind and .migrationState; in Go, .StateKind() and .MigrationState(). Migration errors now surface as a dedicated SnapshotMigration error kind (Python SnapshotMigrationError).
msb self downgrade 0.6.6 --yes
See Snapshots.
msb run -d honors the image CMD
Detached runs now resolve and launch the same OCI command as an attached msb run. If you omit the command, the image's CMD is used; if you pass a command after --, it replaces CMD while the image's entrypoint is preserved. Previously, msb run -d would boot the sandbox without executing the image's default process, which surprised users running images like docker:dind.
For an idle sandbox you can exec into later, use msb create instead. Both flows are documented under Sandbox commands.
msb run -d --script start='exec dockerd' --entrypoint start docker:dind
msb create --name devbox python
msb exec devbox -- python -c "print('hello')"
Other features
ExecHandle.resize(rows, cols) (Go: Resize(ctx, rows, cols)) is now available on every SDK, matching the existing Rust API. Signal, kill, and resize operations run through cloneable exec controls, so they work while a recv() is pending. This is what interactive proxies and remote-terminal integrations need. See the Python execution guide.msb.exe and libkrunfw.dll, and skips Unix-only symlinks. Home directories with non-ASCII characters are handled correctly. See the Go SDK installation guide.status_reason on cloud sandbox responses. While a cloud sandbox is starting, the response includes a machine-readable status_reason of scheduling or insufficient_capacity. Clients can now distinguish "waiting in the scheduler" from "no capacity" without parsing prose. The human-readable field is renamed from last_error to last_failure_message to make the split between machine enums (*_reason) and prose (*_message) consistent. Rust callers should rename Sandbox::last_error() to Sandbox::last_failure_message(), and SandboxHandle::last_error_snapshot() to last_failure_message_snapshot().