Skip to content

Instantly share code, notes, and snippets.

@mdp
Created May 15, 2026 12:33
Show Gist options
  • Select an option

  • Save mdp/82d2af2538b225e6d7eda027418db0a8 to your computer and use it in GitHub Desktop.

Select an option

Save mdp/82d2af2538b225e6d7eda027418db0a8 to your computer and use it in GitHub Desktop.
BoxLite: Technical Summary for Engineers

BoxLite: Technical Summary for Engineers

What It Is (Elevator Pitch)

BoxLite is an embeddable micro-VM runtime that runs standard OCI containers (Docker images) inside lightweight hardware-virtualized sandboxes ("Boxes"). It follows the SQLite philosophy: you link it as a library into your application—no daemon, no root, no background service required.

It is positioned as a "compute substrate for AI agents," but the primitive is general-purpose: give me an isolated, stateful environment where I can run untrusted code with real kernel isolation, and I want it to feel as easy as docker run.

The Core Value Proposition

Capability What BoxLite Does
Isolation Each Box gets its own kernel via KVM (Linux) or Hypervisor.framework (macOS)—not just Linux namespaces.
Stateful Boxes are persistent workspaces. Install packages, write files, stop the VM, come back later—state is still there. This is fundamentally different from ephemeral serverless sandboxes.
Embed-friendly Link the Rust crate, or use Python/Node/Go/C SDKs. The runtime lives in your process.
OCI-native Pull and run standard images (python:slim, node:alpine, etc.) from any registry.
Local-first Runs on your laptop. No cloud account. Scale out to a remote server later via the REST API if you want.

Architecture at a Glance

Your App (Rust/Python/Node/Go/C)
│
├─ BoxliteRuntime ── RwLock ── BoxManager + ImageManager
│     │
│     ▼
├─ LiteBox (lazy-init handle)
│     │
│     ▼
├─ ShimController ── spawns subprocess
│     │
│     ▼
├─ Jailer Boundary (OS sandbox)
│  ├─ Linux: seccomp + namespaces + cgroups v2 + Landlock + bubblewrap
│  └─ macOS: sandbox-exec (Seatbelt) + rlimits
│     │
│     ▼
├─ Shim Process (boxlite-shim)
│  ├─ loads libkrun
│  ├─ starts gvproxy / libslirp (user-mode networking)
│  └─ enters VM (krun_start_enter — never returns)
│     │
│     ▼
├─ Guest VM
│  ├─ virtio-fs (host shares)
│  ├─ virtio-blk (QCOW2 disks)
│  ├─ vsock (host-guest comms)
│  └─ Guest Agent (gRPC server)
│        │
│        ▼
└─ OCI Container Runtime (libcontainer inside the guest)
     └─ Your actual container process

Tech Stack & Key Dependencies

Layer Technology Rationale
Core language Rust 1.88+ (Edition 2024) Safety, async/await, embeddable
Async runtime Tokio All I/O is async; streaming stdout/stderr uses futures::Stream
VMM / Hypervisor libkrun Lightweight VMM built on KVM (Linux) and Hypervisor.framework (macOS). Uses virtio-fs, virtio-blk, vsock. BoxLite maintains a fork (libkrunfw) with prebuilt firmware blobs.
Guest agent Rust + Tokio + Tonic (gRPC) Receives commands from host over vsock
OCI runtime (guest) libcontainer (youki) Runs containers inside the guest VM
Image pulling oci-client + oci-spec Pulls manifests and layers; blob-level deduplication
Networking gvproxy (default) or libslirp User-mode NAT/DHCP/DNS; supports port forwarding
Storage QCOW2 (qcow2-rs), overlayfs, reflink Copy-on-write disks and layer sharing
Host-guest transport gRPC over vsock → Unix socket bridge Defined in boxlite-shared/proto/
Security (Linux) seccomp BPF, bubblewrap, cgroups v2, Landlock LSM, namespaces, AppArmor Defense-in-depth
Security (macOS) sandbox-exec (Seatbelt), rlimits macOS-native sandboxing
Logging tracing + tracing-appender Daily rotating logs in ~/.boxlite/logs/
Metrics AtomicU64 counters Lock-free runtime-wide and per-Box metrics

Key Design Decisions

1. Lazy Initialization

runtime.create() returns a handle immediately. The heavy work—pulling the image, assembling the rootfs, spawning the VM, waiting for the guest agent—happens on first exec(). This makes batch setup fast.

2. Single RwLock for Runtime State

All mutable runtime state (Box registry, image cache) is protected by one RwLock. The team deliberately chose this over fine-grained locking to eliminate deadlock risk and make concurrency reasoning simpler. Metrics are lock-free (AtomicU64).

3. Subprocess Isolation for the VMM

libkrun's krun_start_enter takes over the calling thread/process and never returns. To prevent the host app from hanging, BoxLite spawns a dedicated shim subprocess that actually enters the VM. The shim is then sandboxed by the jailer. This also means if the shim crashes, the host survives.

4. Embedded Binaries

The runtime bundles the boxlite-shim and boxlite-guest binaries (and on Linux, firmware/shared libraries) directly into the library via include_bytes!. When you install the Python wheel or Node package, the native binaries are extracted at first use. No separate installation step.

5. Pluggable Backends

The codebase uses a trait-based backend pattern everywhere:

  • RuntimeBackend — local VMs vs. REST API client
  • BoxBackend / SnapshotBackend — local box lifecycle vs. remote
  • Vmm — currently only libkrun, but Firecracker is defined as a variant
  • NetworkBackendgvproxy vs. libslirp

Project Layout

/home/mdp/tmp/boxlite/
├── src/
│   ├── boxlite/          # Core runtime (~40K+ loc across modules)
│   │   ├── runtime/      # BoxliteRuntime, options, filesystem layout
│   │   ├── litebox/      # LiteBox handle, exec, state machine
│   │   ├── vmm/          # VMM abstraction + libkrun integration
│   │   ├── jailer/       # Security isolation (seccomp, bubblewrap, etc.)
│   │   ├── portal/       # gRPC host-guest communication
│   │   ├── images/       # OCI image pull, cache, layer extraction
│   │   ├── rootfs/       # Rootfs assembly (overlayfs, DNS injection)
│   │   ├── volumes/      # virtio-fs and QCOW2 volume management
│   │   ├── net/          # Network backends (gvproxy, libslirp)
│   │   └── metrics/      # Lock-free metrics
│   ├── cli/              # `boxlite` CLI + built-in REST server (axum)
│   ├── guest/            # Guest agent (runs inside VM)
│   ├── shim/             # Shim process that enters libkrun
│   ├── shared/           # Protobuf, error types, constants
│   ├── test-utils/       # Shared test helpers
│   └── deps/             # Vendored sys crates (libkrun-sys, libgvproxy-sys, bubblewrap-sys, e2fsprogs-sys)
├── sdks/
│   ├── python/           # PyO3 + maturin bindings
│   ├── node/             # napi-rs bindings
│   ├── c/                # cbindgen FFI
│   └── go/               # CGO + prebuilt native library
└── make/                 # Makefile includes (build, test, dist, quality)

Critical Code Paths

Creating a Box

  1. BoxliteRuntime::new() → initializes FilesystemLayout (~/.boxlite), acquires filesystem lock, starts ImageManager.
  2. runtime.create(options) → mints a BoxID, creates LiteBox with lazy BoxBackend.
  3. First exec() triggers BoxBuilder::initialize() → pipeline:
    • Pull OCI image (if missing) → ImageStore / ImageStorage
    • Extract layers (deduplicated by digest)
    • Assemble rootfs (overlayfs or copied snapshot)
    • Spawn shim via ShimController
    • Jailer applies seccomp/bwrap/cgroups
    • Shim starts libkrun → guest boots
    • Guest agent connects back via vsock
    • Host sends Guest.Init then Container.Init over gRPC

Executing a Command

  1. litebox.exec(BoxCommand) → gRPC Execution.Exec to guest agent
  2. Guest agent uses libcontainer to spawn the container process
  3. stdout/stderr stream back as gRPC streams → converted to futures::Stream in host API

Build & Distribution Model

BoxLite is Makefile-driven. The project explicitly discourages running cargo directly because the Makefile handles:

  • Cross-compilation
  • Downloading prebuilt libkrunfw firmware blobs
  • Building guest + shim binaries
  • Embedding binaries into the Rust library
  • Running the full test matrix

Key make targets:

  • make setup — initial dev environment
  • make runtime / make cli:release — build artifacts
  • make test — unit + integration tests
  • make dev:python — build Python wheel locally

Distribution:

  • Rust crate on crates.io
  • Python wheels via PyPI (prebuilt for macOS ARM64, Linux x86_64/ARM64)
  • Node.js via npm (prebuilt N-API binaries)
  • Go via go get + setup script (downloads prebuilt native lib)
  • CLI via cargo install, GitHub Releases, or install script (curl | sh)

Security Posture

BoxLite implements defense-in-depth with multiple concentric layers:

  1. Hardware virtualization — KVM/HVF isolates the guest kernel from the host.
  2. OS sandboxing (Jailer) — The shim process itself is sandboxed:
    • Linux: seccomp BPF syscall filtering, bubblewrap namespaces/chroot, Landlock LSM for filesystem restrictions, cgroups v2 for resource limits, privilege dropping.
    • macOS: sandbox-exec (Seatbelt) with a custom SBPL profile.
  3. Guest isolation — Each Box has its own kernel and cannot see host processes or filesystems except through explicitly mounted virtio-fs shares.
  4. No root required — The runtime runs as the invoking user; the jailer drops privileges further.

See src/boxlite/src/jailer/THREAT_MODEL.md for the full threat model.


Where It Fits in the Landscape

Technology Isolation Stateful Embed as Lib OCI Notes
Docker / containerd Namespaces/cgroups Yes No (daemon) Yes Process-level isolation; shared kernel
Firecracker Micro-VM Yes No (daemon/server) No Requires MicroVM-init; daemon model
gVisor Sentry (user kernel) Yes Partial Yes No hardware virtualization
BoxLite Micro-VM (KVM/HVF) Yes Yes Yes Library-first, stateful, OCI-native
Wasmtime / WASI Capability-based No Yes No Different abstraction; no general Linux compatibility

BoxLite occupies a relatively unique niche: hardware-isolated + stateful + library-embeddable + OCI-compatible. It is closest to "Firecracker + containerd + embedded SQLite," but packaged as a single library with a simple async API.


Getting Oriented (Where to Read Code)

If you want to understand... Start here
The public API surface src/boxlite/src/lib.rs
Runtime lifecycle & options src/boxlite/src/runtime/core.rs, src/boxlite/src/runtime/options.rs
How a Box starts up src/boxlite/src/litebox/init/, src/boxlite/src/litebox/box_impl.rs
Security / sandboxing src/boxlite/src/jailer/mod.rs, src/boxlite/src/jailer/THREAT_MODEL.md
VMM integration src/boxlite/src/vmm/krun/, src/deps/libkrun-sys/
Host-guest protocol src/shared/proto/boxlite/v1/service.proto
Guest agent internals src/guest/src/main.rs, src/guest/src/service/
Image pull & caching src/boxlite/src/images/manager.rs, src/boxlite/src/images/store.rs
CLI & REST server src/cli/src/cli.rs, src/cli/src/commands/serve.rs
Python SDK sdks/python/src/lib.rs (PyO3)

Summary

BoxLite is a well-architected Rust project that bridges the gap between heavy-weight VM orchestration (Firecracker, QEMU) and lightweight container convenience (Docker). It is built with modern Rust patterns (async Tokio, trait-based backends, lock-free metrics) and prioritizes embeddability and local development. The security model is serious (seccomp, Landlock, cgroups, hardware virtualization), and the multi-language SDK strategy makes it accessible to a broad audience. For engineers evaluating it, the key mental model is: "SQLite, but for running Docker containers inside micro-VMs."

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment