Skip to content
Registry

sandbox-libkrun

v0.2.2

libkrun sandbox adapter - serves the iii sandbox router's sandbox::* calls as sandbox-libkrun::* in libkrun microVMs, and boots Compose's worker VMs.

license: Elastic-2.0libkrunmicrovmsandboxvm

Install

bash
iii trigger compose::add worker=sandbox-libkrun

Run in your project with the iii engine running. Exact versions are immutable and digest-pinned.

iii-config.yaml
- auto_install: true
  default_cpus: 1
  default_idle_timeout_secs: 300
  default_memory_mb: 512
  image_allowlist:
    - python
    - node
  max_concurrent_sandboxes: 32

sandbox-libkrun

The libkrun sandbox adapter: it runs sandboxes and worker VMs as libkrun microVMs on the engine's host. The engine's sandbox::* router forwards each sandbox call to it as sandbox-libkrun::<operation>, and Compose boots package:// and path:// VM workers through its sandbox-libkrun::worker::* functions. You rarely call it directly: callers use sandbox::*, and Compose installs this adapter when a project needs it.

Install

Compose adds it on its own when a project needs sandboxes or VM workers. To add it by hand on iii 0.26 or later, use the iii-sandbox alias, which pins the adapter to the sandbox contract major the engine supports:

iii trigger compose::add worker=iii-sandbox

Older Compose has no such alias, so pin the range yourself (0.2.x implements sandbox contract 1):

iii trigger compose::add worker=sandbox-libkrun@^0.2

Calling sandbox::* through the router needs iii 0.26 or later; the sandbox-libkrun::* ids work on iii 0.24 and later.

Quickstart

Run code in a fresh VM through the router, which forwards to this adapter:

iii trigger sandbox::run --timeout-ms 300000 \
  --json '{"image":"python","code":"print(6*7)","lang":"python"}'

The reply carries stdout (42), stderr and exit_code; the VM stops when the call returns. The first call pulls the image, so it is slower. sandbox-libkrun::run takes the same payload directly.

What it serves

Functions Purpose
create, exec, stop, list, catalog::list, run Sandbox lifecycle and one-call runs
fs::ls, fs::stat, fs::mkdir, fs::rm, fs::chmod, fs::mv, fs::grep, fs::sed, fs::write, fs::read Files inside a live sandbox
adapter::info Adapter name, version and the sandbox contract version it implements
worker::prepare, worker::start, worker::status, worker::logs, worker::stop, worker::destroy Compose's worker VMs (see below)

Every id is prefixed with sandbox-libkrun::.

Configuration

The adapter reads its configuration entry once at startup with configuration::get (III_CONFIG_NAME, else sandbox-libkrun). A change applies when the adapter restarts. A config that does not parse, or a failed read, stops the adapter with exit code 2 instead of falling back to defaults.

auto_install: true              # pull a missing image on first create
image_allowlist: [python, node] # bootable images; empty denies every create
default_idle_timeout_secs: 300  # idle sandboxes are reaped after this
max_concurrent_sandboxes: 32
max_concurrent_exec_per_sandbox: 4  # 0 means 1, not unlimited
max_exec_timeout_ms: 300000     # ceiling on any exec's timeout_ms
default_cpus: 1
default_memory_mb: 512
per_image_caps:                 # optional per-image ceilings
  python: { max_cpus: 4, max_memory_mb: 2048 }
custom_images:                  # extra images: name -> OCI ref
  my-app: ghcr.io/acme/my-app:1.2.3   # must also be in image_allowlist

A custom_images key may not reuse a preset name (python, node), and the old wrapped shape (sandbox: {...}) is rejected.

VM tuning stays in four environment variables the adapter passes to each worker VM (sandboxes ignore them):

Variable Effect
III_VM_HYPERTHREADING=1 Enable SMT (hyperthreading) in the guest
III_VM_NESTED_VIRT=1 Enable nested virtualization
III_VM_VIRTIOFS_SHM_SIZE_MIB=<n> virtiofs shared-memory window; 0 skips it
III_VM_NOFILE_LIMIT=<n> Guest open-file limit; 0 leaves it to the guest init

Host prerequisites

  • macOS, Apple Silicon only. The released binary is ad-hoc signed with the com.apple.security.hypervisor and com.apple.security.cs.disable-library-validation entitlements. An unsigned dev build signs itself in place on first run.
  • Linux, glibc. The Compose user needs read/write access to /dev/kvm.
  • Any other host gets a clear UnsupportedPlatform error from Compose when a project needs the adapter.

Worker VMs

Compose runs VM workers through sandbox-libkrun::worker::*. Because those requests name host directories (host_path) and carry the guest's environment, two guards apply:

  • Token. Compose generates a per-project token and passes it to the adapter as III_SANDBOX_WORKER_TOKEN. Every worker::* request carries it in auth; a mismatch gets S505.
  • Host roots. host_path is accepted only under the project's Compose directory and the Compose package cache. Anything else gets S501 naming the two roots.

Compose also sets III_DISABLE_TRACE_PAYLOADS=1 on the adapter, so the token and guest env never land in the engine's trace store.

Known limits

The guards assume bus clients are trusted. A client that registers the adapter's function ids or its worker name first, while the adapter is down, receives the auth token and the guest env that Compose sends. The router has the same limit for sandbox::* forwards.

Errors

Errors carry an S-code with a docs_url. The full list is at iii.dev/docs/creating-workers/sandboxes.

Search the registry

Find workers, kits and executables, or jump to a page.