void-box logoVoid-Box
OCI Containers

OCI Container Image Support

VoidBox supports OCI container images in three ways: as a pre-built guest image containing the kernel and initramfs, as a base image providing the full guest root filesystem, and as OCI skills that mount additional container images as read-only tool providers.

Images are pulled from Docker Hub, GHCR, or any OCI-compliant registry and cached locally at ~/.voidbox/oci/.

Guest Image (sandbox.guest_image)

Pre-built kernel + initramfs distributed as a FROM scratch OCI image containing two files: vmlinuz and rootfs.cpio.gz. Auto-pulled from GHCR on first run — no local toolchain needed.

Resolution Order

VoidBox resolves the kernel/initramfs using a 5-step chain:

Resolution chain
1. sandbox.kernel / sandbox.initramfs   (explicit paths in spec)
2. VOID_BOX_KERNEL / VOID_BOX_INITRAMFS (env vars)
3. sandbox.guest_image                  (explicit OCI ref)
4. ghcr.io/the-void-ia/voidbox-guest:v{version}  (default auto-pull)
5. None → mock fallback (mode: auto)

Cache layout: ~/.voidbox/oci/guest/<sha256>/vmlinuz + rootfs.cpio.gz + <sha256>.done marker.

Base Image (sandbox.image)

A full container image (e.g. python:3.12-slim) used as the guest root filesystem. The guest-agent switches root with overlayfs + pivot_root (or secure switch-root fallback when kernel returns EINVAL for initramfs root).

Linux/KVM

Host builds a cached ext4 disk artifact from the extracted OCI rootfs and attaches it as virtio-blk (guest sees /dev/vda).

macOS/VZ

Rootfs remains directory-mounted via virtiofs path. No block device needed.

Security properties are preserved across both paths: OCI root switch is driven only by kernel cmdline flags set by the trusted host, command allowlist + authenticated vsock control channel still gate execution, and the writable layer is tmpfs-backed while the base OCI lowerdir remains read-only.

Cache layout: ~/.voidbox/oci/rootfs/<sha256>/ (full layer extraction with whiteout handling).

OCI Skills

Mount additional container images as read-only tool providers at arbitrary guest paths. Each skill image is pulled, extracted, and mounted independently — no sandbox.image required. This lets you compose language runtimes (Python, Go, Java, etc.) without baking them into the initramfs.

examples/specs/oci/skills.yaml
api_version: v1
kind: agent
name: multi-tool-agent

sandbox:
  mode: auto
  memory_mb: 2048
  vcpus: 2
  network: true

llm:
  provider: ollama
  model: "qwen2.5-coder:7b"

agent:
  prompt: >
    You have Python, Go, and Java available as mounted skills.
    Set up PATH to include the skill binaries:
      export PATH=/skills/python/usr/local/bin:/skills/go/usr/local/go/bin:/skills/java/bin:$PATH

    Write a "Hello from <language>" one-liner in each language and run all three.
    Report which versions are installed.
  skills:
    - "agent:claude-code"
    - image: "python:3.12-slim"
      mount: "/skills/python"
    - image: "golang:1.23-alpine"
      mount: "/skills/go"
    - image: "eclipse-temurin:21-jdk-alpine"
      mount: "/skills/java"
  timeout_secs: 300

Cache Layout

~/.voidbox/oci/
  blobs/     # Content-addressed blob cache
  rootfs/    # Extracted OCI rootfs layers (per sha256)
  guest/     # Guest image cache (kernel + initramfs)

OCI Client Internals

The voidbox-oci/ crate provides the OCI distribution client:

ModulePurpose
registry.rsOCI Distribution HTTP client (anonymous + bearer auth, HTTP for localhost)
manifest.rsManifest / image index parsing, platform selection
cache.rsContent-addressed blob cache + rootfs/guest done markers
unpack.rsLayer extraction (full rootfs with whiteouts, or selective guest file extraction)
lib.rsOciClient: pull(), resolve_rootfs(), resolve_guest_files()

Example Specs

All OCI examples are in examples/specs/oci/:

SpecDescription
agent.yamlSingle agent with sandbox.image: python:3.12-slim
workflow.yamlWorkflow with sandbox.image: alpine:3.20 (no LLM)
pipeline.yamlMulti-language pipeline: Python base + Go and Java OCI skills
skills.yamlOCI skills only (Python, Go, Java) mounted into default initramfs
guest-image-workflow.yamlWorkflow using sandbox.guest_image for auto-pulled kernel + initramfs

Running

Linux (KVM)

code-run
VOID_BOX_KERNEL=/boot/vmlinuz-$(uname -r) \
VOID_BOX_INITRAMFS=target/void-box-rootfs.cpio.gz \
cargo run --bin voidbox -- run \
  --file examples/specs/oci/skills.yaml

macOS (Virtualization.framework)

code-run
VOID_BOX_KERNEL=target/vmlinux-arm64 \
VOID_BOX_INITRAMFS=target/void-box-rootfs.cpio.gz \
cargo run --bin voidbox -- run \
  --file examples/specs/oci/skills.yaml