# mvm gives the guest no network device at all

> tinylabscom/mvm is a Rust CLI and a set of language SDKs that boot hardware-isolated microVMs from OCI images, Nix flakes or decorated functions. The design decision everything else follows from is that a guest has no NIC, so the host originates every outbound byte over vsock and can enforce default-deny egress from a signed plan.

**tinylabscom/mvm** — Manage secure microVMs — one command from zero to secure sessions, locally and remotely.

- Repository: https://github.com/tinylabscom/mvm
- Website: https://gomicrovm.com/
- Stars: 46 · Forks: 4
- Language: Rust
- License: Apache-2.0
- Published: 2026-08-23 · Updated: 2026-08-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/tinylabscom-mvm

## No NIC in the guest, so the host originates every connection

The architectural claim is stated before anything else, and it is easy to skim past. Every machine boots its own Linux kernel under a real hypervisor. There is no Docker on the runtime path, no SSH in any guest, and no guest network device at all on any workload backend. Every byte a workload sends crosses vsock. Because the guest has no network interface, the host originates every outbound connection, and that is what makes three guarantees mechanically enforceable instead of merely intended: default-deny egress, no raw secret reaching the guest, and an audit chain. On the vsock path the host can audit flows, substitute secrets so the workload never sees raw credentials, and detect and replace secrets and structured PII on owned cleartext egress paths, all driven by a signed execution plan.

## Two backends, picked by the host you are on

There is no portable code path and no fallback mode. The mapping is two lines:

```
macOS 26+ (Apple Silicon)  →  in-house HVF VMM (Hypervisor.framework, zero extra deps)
Linux + /dev/kvm           →  Firecracker
```

On Apple Silicon the project runs its own VMM on the Hypervisor framework, and the README describes that backend and its builder as dependency-free. On Linux the backend is Firecracker, which mvm manages on your behalf. Host requirements follow directly: macOS 26 or later on Apple Silicon needs nothing installed, while Linux needs a working /dev/kvm device. One detail worth checking before you build from source: standard source builds and release artifacts do not install, link or require libkrun, even though a libkrun-sys crate exists in the workspace as a dependency. If a host is missing something, mvmctl doctor diagnoses it and prints exact install hints.

## The root crate is a facade, and policy lives in the workspace

The repository root is itself the mvmctl Cargo package, which is unusual enough to explain. Its binary is a thin process entry point that initialises platform-specific main-thread behaviour and calls mvm_cli::run(). Its library is a convenience facade that re-exports the core, runtime, build, guest-agent and host-daemon crates, aimed at embedders who want a single dependency. The CLI is the main consumer of that package, while external Rust automation can use the facade and mvm-conformance uses the built binary plus selected library surfaces in end-to-end tests. The rule the project states for itself is that implementation stays in the narrower workspace crates so each layer can be tested independently, and the root crate should hold composition and re-exports rather than a second implementation of lifecycle or security policy.

## Eighteen numbered claims, and CI is what holds them up

The security posture is described as enforced by CI rather than by documentation, which is a different kind of promise from a policy page. The numbered claims number more than eighteen and include signed execution plans, a chain-signed audit log, dm-verity boot, default-deny egress, run-shaped agent-verb grants, sealed production images that refuse interactive access, and secret substitution over vsock. Two of those deserve a note. dm-verity is a filesystem integrity mechanism verified by the kernel rather than a check the tool performs, and a sealed production image that refuses interactive access is what stops a hardened workload from being handed a shell. The conformance suite is a separate workspace member, mvm-conformance, and the repository ships CONFORMANCE.md at the top level alongside SECURITY.md and a CHANGELOG.md.

## Transient by default: a command, then the machine is gone

The default shape of machine run is a machine that does not survive the command. A transient machine boots, runs one argument vector after the double dash, and is torn down on exit: nothing is registered and nothing persists. The shortest example runs a shell command in Alpine:

```bash
mvmctl machine run --image alpine -- sh -c "echo hello from a microVM && uname -a"
```

A comment above it in the README spells out the two rules that surprise newcomers. Network access is off by default, under the default-deny egress policy, and the arguments after the double dash are the argv rather than a shell string the host expands. For a quick arithmetic check against a Python image, the documented form is mvmctl machine run --image python:3.12 -- python -c "print(2 + 2)". For an interactive shell you want a workload machine rather than the builder, run mvmctl machine run --image alpine -it -- /bin/sh against a dev-tier image.

## Host directories arrive as ext4 images, not virtio-fs

Mounting a host directory works on every backend, but not through the mechanism most container runtimes use. The README states that the directory is materialised into an ext4 image and attached as a block device, which is why there is no virtio-fs in the path. The mount is read-only, and the flag is repeated for additional host directories. The practical difference matters in two directions. Because the guest sees a real block device with a filesystem, the mount behaves the same under the HVF backend and under Firecracker, so a workload does not need to know which one booted it. And because it is read-only by default, a workload that wants to write has to say so as an explicit launch decision, which then lands in the signed execution plan alongside egress and secrets.

## Persistent machines have an on-disk spec you can patch

A named machine is created once and then started, inspected, reconfigured and removed against a spec on disk. The whole lifecycle is a short sequence:

```bash
mvmctl machine create web --image nginx --cpus 2 --memory 512M
mvmctl machine start web
mvmctl machine exec  web -- nginx -v
mvmctl machine logs  web
mvmctl machine reconfigure web --memory 1G     # patch + relaunch
mvmctl machine stop  web && mvmctl machine rm web
```

Two behaviours are documented inline. A request above the backend's vCPU ceiling is clamped to it with a warning rather than refused, so a spec written for one backend will quietly get less than it asked for on another. And display is gated rather than open: for a workload admitted with host.display.view.v1, frames are served at a single-use URL bound to 127.0.0.1 only. Listing works through machine ls with ps as an alias, and machine inspect prints the resolved spec.

## The builder VM has no shell, and bootstrap is rerunnable

Nix builds do not happen on your host. They run inside a headless builder VM that mvm manages, which exists only to run nix build, offers no interactive shell, and is debugged through its logs. It auto-bootstraps on the first machine build or machine run, and you can prepare it in advance with two commands:

```bash
mvmctl bootstrap      # host setup + builder VM, kernel, overlay, initramfs, guest shims
mvmctl doctor         # diagnose host deps + the resolved builder/runtime backend
```

Rerunning bootstrap is safe: it verifies warm artifacts and rebuilds or downloads only what is missing or invalid. Three provenance rules are stated, and they are the ones to read before trusting a binary. Official release binaries download published, verified artifacts and never infer a local build just because the command happens to run inside a source checkout. Contributor binaries build source-matched artifacts when that source is available. And if a Stage 0 source build is interrupted, the incomplete output is never installed, so a rerun resumes with the persistent Nix store still warm.

## Conclusion

mvm suits a team that needs a hard isolation boundary around untrusted or agent-driven code and wants its egress policy to be mechanical rather than aspirational. It does not suit someone who needs an interactive shell on the build host's behalf or a fast path that assumes network access inside the workload. Before adopting it, check four things: which backend your host resolves to, whether your workload can accept default-deny egress, whether the source build path is the one you want given that release binaries refuse to infer a local build, and what the SDK decorator surface looks like for your language.

## FAQ

### What does mvm need installed on my machine?

macOS 26 or later on Apple Silicon needs nothing extra, because the in-house HVF backend and builder are dependency-free. Linux needs a working /dev/kvm device, and Firecracker is managed for you. Standard source builds and release artifacts do not install, link or require libkrun, and mvmctl doctor diagnoses the host and prints exact install hints.

### How do I install mvmctl and the language SDKs?

The pre-built route is curl -fsSL https://runmvm.com/install.sh | sh, for macOS Apple Silicon and Linux x86_64 or aarch64. From source, clone the repository, run cargo build --release, and copy target/release/mvmctl into ~/.local/bin. The SDKs install separately: pip install mvm for Python, npm install @runmvm/mvm for TypeScript.

### Does an mvm workload get network access by default?

No. Network access is off by default, and the guest has no network device at all on any workload backend. Filesystem sharing, egress and secrets are explicit launch decisions recorded in the signed execution plan, so a machine run without them cannot reach the network.

## Sources

- [Official documentation](https://gomicrovm.com/)
- [Official README](https://github.com/tinylabscom/mvm#readme)
- [Project repository](https://github.com/tinylabscom/mvm)
- [Release notes](https://github.com/tinylabscom/mvm/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/tinylabscom-mvm
