Skip to content

Architecture

Control surfaces

The supported local ways to control mvm sandboxes, plus the surfaces that are partial or not claimed.

mvm has several local control surfaces. They all drive the same runtime model: build or select an artifact, admit a plan, boot a microVM, talk to the guest agent where available, and record evidence for security-relevant actions.

This page helps you choose the right surface without assuming that every product entry point is shipped everywhere.

SurfaceBest forCurrent status
mvmctl CLILocal operation, scripting, CI, debugging, build/run lifecycle.Shipped and broadest surface.
Runtime SDKApplication-owned sandbox lifecycle from Python or TypeScript.Partial; see lifecycle matrix.
Declaration SDKCode-first workload declarations compiled into Workload IR.Shipped for supported literal declarations.
ConsoleHuman debugging in development images.Shipped where backend/image policy permits it.
Guest RPCProcess, filesystem, readiness, and telemetry operations.Backend/image dependent.
REST APIHTTP management surface.Not claimed in these local docs.
Web dashboardBrowser-based management UI.Not claimed in these local docs.

The CLI remains the stable automation boundary when an SDK helper does not yet cover an operation.

Use mvmctl for the full local lifecycle:

Terminal window
mvmctl machine build --flake ./agent
mvmctl machine run --flake ./agent --name agent-dev -d
mvmctl machine exec agent-dev -- python /work/task.py
mvmctl machine logs agent-dev
mvmctl machine stop agent-dev

Prefer JSON where available:

Terminal window
mvmctl machine ls --json
mvmctl machine boot-report agent-dev --json
mvmctl run --dry-run --json -- python task.py

CLI automation should use argv arrays, explicit timeouts, and receipts for security-relevant runs.

Use the runtime SDK when application code should own a sandbox lifecycle:

import mvm
with mvm.Sandbox.create("python-3.12", workload_id="tool") as sandbox:
sandbox.files.write("/app/main.py", "print('hello')")
sandbox.commands.start(["python", "/app/main.py"])

Current SDKs expose create, command start, file write, record mode, live mode, and cleanup helpers. Higher-level command results, file read/list/remove, logs, ports, snapshots, cold mode, detach, and destroy remain parity targets.

Use Lifecycle matrix before depending on a method in a language SDK.

Use declarations when the workload should be reviewed and compiled before it runs:

import mvm
@mvm.app(
name="worker",
source=mvm.local_path("."),
image=mvm.nix_packages(["python312"]),
resources=mvm.resources(cpu_cores=1, memory_mb=256, rootfs_size_mb=512),
network=mvm.network(mode="none"),
)
def run() -> str:
return "ok"

The declaration workflow is the safer authoring path for deployable workloads because supported declarations are extracted without importing the module.

Use console access for human debugging:

Terminal window
mvmctl machine console agent-dev
mvmctl machine console agent-dev --command "uname -a"

Console access is broad authority inside the guest. Development images can enable it; sealed production-style images should refuse it and rely on declared entrypoints, logs, guest RPC, and audit records instead.

Guest RPC is the underlying controlled path for operations such as process start, filesystem access, readiness probes, console PTY traffic, and telemetry where the backend and image permit them.

Use the high-level CLI or SDK surface unless you are debugging a protocol-level issue. Protocol frames and guest payloads are not a substitute for receipts or audit-chain evidence.

These local docs do not claim a shipped HTTP management API or browser dashboard. Scripts should use mvmctl JSON output or the current SDK surfaces instead of assuming a long-running local server.

If an integration needs language-neutral automation today, prefer subprocess calls to mvmctl with JSON output and explicit state directories.

  • Choose the narrowest surface that fits the task.
  • Use static declarations for reviewable deployable workloads.
  • Use runtime SDK live mode only for trusted SDK scripts.
  • Keep console access out of production-style paths.
  • Treat stdout, stderr, logs, console bytes, and screenshots as sensitive.
  • Store receipts or audit identifiers with higher-level automation traces.