Rune Box docs

Native microVMs

Run each sandbox in its own Firecracker or libkrun microVM with `host.type = "microvm"`.

host.type = "microvm" boots one microVM per sandbox itself: no container engine, Kata or Kubernetes. Both monitors share one guest design.

host.runtime Monitor Guest kernel Hosts
firecracker Firecracker (firecracker --no-api --config-file) the operator's (RUNEWARD_MICROVM_KERNEL) Linux with /dev/kvm
libkrun (krun) libkrun, loaded by the runeward-krun helper libkrunfw's bundled kernel Linux with /dev/kvm; macOS on Apple silicon

An empty host.runtime takes RUNEWARD_MICROVM_VMM, else Firecracker when it is configured, else libkrun.

[host]
type    = "microvm"
runtime = "firecracker"          # or "libkrun"
image   = "curlimages/curl:8.11.1"

[network]
default = "deny"
[[network.rule]]
hostname = "example.com"

[workspace]
persist = true

[isolation]
minimum = "vm"

How it works

  • Image. Pulled anonymously from its registry for linux/<host arch>, layers verified against their digests, unpacked without root into an ext4 disk cached by manifest digest under RUNEWARD_MICROVM_DIR/images and shared read-only by every VM of that image. An unresolvable tag falls back to the disk it last resolved to. gzip and uncompressed layers only.
  • Guest. The static runeward-vmagent is PID 1. It mounts the image disk read-only under an in-memory overlay, plus /proc, /sys, /dev and the workspace disk, and chroots into it, so any image boots unmodified. host.read_only = true makes the root read-only with a 512 MiB tmpfs /tmp; the supervisor state and broker CA directories stay writable.
  • Protocol. The host reaches the agent over vsock, one stream per operation (exec, TTY, files, workspace tar, probe, shutdown). Commands and file operations run in a helper that drops to the sandbox user first.
  • Workspace. A per-sandbox sparse ext4 disk (RUNEWARD_MICROVM_DISK_SIZE, default 8g).
  • Sleep and wake. stop shuts the guest down (killing the monitor after 15 s); the disk and sandbox id stay, guest memory is lost. start boots a new VM on the same disk. kill removes the VM directory.
  • Sizing. The guest gets the sandbox memory limit (at least 256 MiB) and its CPU limit rounded up to whole vCPUs; RUNEWARD_SANDBOX_MEMORY and RUNEWARD_SANDBOX_CPUS apply as on Docker.

Egress

The guest has no network device (libkrun's TSI is disabled). Its only way out is vsock: HTTP_PROXY/HTTPS_PROXY point at the agent on 127.0.0.1:3128, which forwards each connection to a per-sandbox Unix socket on the host where the policy's egress proxy and credential broker decide, as on the container backends. Deny-by-default therefore cannot be bypassed from inside, under strict and cooperative alike.

Warning: Only proxy-aware traffic leaves. Raw TCP, UDP and DNS lookups fail even under an open policy (runeward validate warns), and the browser IDE is refused.

The agent collects the same probe sections natively, so an image without a shell still reports evidence. vm needs a separate guest kernel and a hypervisor marker, and the backend records host:hypervisor=<monitor> only while the monitor it launched is running. A failed probe reports container. Both monitors reported verdict:vm on the KVM test host (Firecracker 1.15.1; libkrun 1.19.6 with libkrunfw 5.6.2).

Settings refused or changed

Setting On microvm
host.seccomp, host.apparmor Refused. The monitor runs under its own seccomp filters; use [process] for in-guest seccomp.
[ide] enabled Refused: no sandbox network address.
[filesystem] landlock = "required" Works only when the guest kernel has Landlock. libkrunfw and the Firecracker CI 6.1 kernel do not; runeward validate warns for libkrun.
[[endpoint]] binaries Refused: the broker runs outside the VM (security.md).
host.user, host.command, [process], broker, [[file]], copy_from, snapshots As on Docker.

Setting up a host

  1. Build the guest agent: cargo build --release --target x86_64-unknown-linux-musl -p runeward-vmagent (aarch64-unknown-linux-musl on arm64), then set RUNEWARD_MICROVM_AGENT or put it next to runeward.
  2. e2fsprogs 1.43 or later (mkfs.ext4 and debugfs, or RUNEWARD_MICROVM_MKFS).
  3. Access to /dev/kvm for the Rune Box user (the kvm group).
  4. Firecracker: a release binary on PATH or RUNEWARD_FIRECRACKER_BIN, and an uncompressed guest kernel with virtio MMIO block and vsock, ext4, overlayfs, devtmpfs and initramfs support as RUNEWARD_MICROVM_KERNEL (the Firecracker CI kernels qualify).
  5. libkrun: 1.19 or later built with block-device support (make BLK=1; the helper refuses other builds), libkrunfw next to it, the runeward-krun helper (cargo build --release -p runeward-krun) on PATH or RUNEWARD_KRUN_HELPER, and RUNEWARD_LIBKRUN if libkrun.so.1 is not on the loader path.

RUNEWARD_MICROVM_DIR (default ~/.runeward/microvm) must stay short: Unix socket paths are limited to about 100 bytes. Opening the backend fails with a message naming what is missing.

On macOS, libkrun runs on Apple silicon through Hypervisor.framework (Firecracker is Linux-only). It needs libkrun built with --features blk and libkrunfw side by side, the runeward-krun helper signed with the com.apple.security.hypervisor entitlement, an aarch64-unknown-linux-musl agent, e2fsprogs, and RUNEWARD_MICROVM_DIR on a case-sensitive volume. See the source isolation doc for the exact build steps.

Verify on a KVM host (RUNEWARD_TEST_MICROVM=libkrun with RUNEWARD_KRUN_HELPER and RUNEWARD_LIBKRUN for libkrun; RUNEWARD_TEST_MICROVM_SUPERVISED=1 adds a supervised read-only sandbox):

RUNEWARD_TEST_MICROVM=firecracker \
RUNEWARD_MICROVM_DIR=/var/lib/rw-microvm \
RUNEWARD_MICROVM_AGENT=/opt/runeward/runeward-vmagent \
RUNEWARD_MICROVM_KERNEL=/opt/runeward/vmlinux-6.1.155 \
cargo test -p runeward-backend --test microvm_e2e -- --nocapture

Limitations

  • Images are pulled anonymously; private registries and local-only images are not supported yet.
  • zstd layers are refused, and images whose layers write through an absolute symlink to a directory fail to unpack.
  • After a control-plane restart running VMs stay reachable, but their egress path is gone until the sandbox is woken again: egress fails closed.
  • Firecracker runs as the Rune Box user without its jailer; the VM boundary and Firecracker's seccomp filters are the isolation.

See Isolation and runtimes for the other runtimes and Security model for what a microVM does and doesn't protect.

Written from docs/isolation.md, docs/security-model.md at commit 1ee29ff4ab36. Rune Box is open source under Apache-2.0.