Repository navigation
The sandbox runtime release: credentials kept out of the VM, idle VMs that
suspend themselves, copy-on-write forks, and the full lifecycle tested on real
KVM.
Added
- Host egress broker (opt-in,
LANTERN_EGRESS_MODE=broker, Firecracker;
ADR 0026, #299) — broker-mode VMs get no network device; egress and the
harness control channel run over vsock to a per-VM broker on the host, which
enforces the allowlist and injects credentials fromlantern.secret/...refs
(egress[].inject, exact hostnames only) so the secret never enters the VM.
HTTPS is terminated only for injected hosts, with a per-VM CA scoped to them.
Validated live on KVM (infra/firecracker/broker-e2e.sh). - Idle auto-suspend + transparent auto-resume (#296) —
idleTimeoutSecson
schedule /lantern run --idle-timeout; idle VMs are snapshotted and stopped
through the crash-safe pause path (quota slot freed) and resumed on the next
exec or file request (REST, CLI or SDK). - Shared-memory copy-on-write forks (#295) — forks hard-link one read-only
snapshot memory file (MAP_PRIVATE); fork cap configurable
(LANTERN_MAX_FORK_COUNT, default 100, ceiling 1000). - Sandbox file API (#294) — list/read/write files under
/workspacevia
REST, TS/Python/Go SDKs andlantern vm ls|cat|put. - Agentic onboarding (#297) — conversational
/onboardingflow (LLM-designed
agent spec, real provider check, streamed first run, sandbox try-out,
resumable) and interactivelantern onboard;lantern doctorchecks the
sandbox runtime. - Real-KVM lifecycle e2e (#298) — snapshot → restore → fork ×3 (jailed, with
an inode check proving shared memory) in Lima and GitHub's KVM runners, with
per-step timings indocs/benchmarks/runtime-latency.md. - New brand, README, landing site, docs site and diagrams — 28 diagrams in
one visual system, animated landing hero and lifecycle walkthrough. - GA hardening stack (#276–#292): pause/resume/fork, per-call runtime-manager
authz and service token, re-identification on restore, per-fork identity,
manager-owned harness config, tenant-wide budget cap, tool-spend metering,
body-hashed LLM idempotency keys.
Fixed
- Harness reaper raced tokio's pidfd wait (
ECHILDfromshell_execafter
restore); stale sockets broke same-vm_id restore; first exec after restore
waited out a dead address (37 s → ~4 s); unjailed restores shared one rootfs. - Manager secret relay sent the node's env tenant/vm_id instead of the VM's
(empty scope on multi-tenant nodes) — now the VM's, empty fails closed. - Onboarding: generate-spec returned the raw completion envelope; CLI sent
api_keyinstead ofapiKey; saved keys were never tested.
Security
- wasmtime moved to the 36.x LTS line (20 guest-can-panic-host advisories,
#293); wasmtime's unusedcachefeature dropped to remove zstd
(RUSTSEC-2026-0395/0396/0400); h2/quinn-proto/rustls/webpki/zod bumps.
Earlier unreleased work
- Interactive TTY exec —
lantern vm exec <vm> -it -- <cmd>allocates a real
PTY in the guest (harnessopenpty+ controlling terminal + winsize) and
streams it bidirectionally; the CLI enters raw mode (no-op on non-terminal
stdin). Docker backend setsTty: true. Non-tty exec is byte-identical.
ExecRequestgainstty/term_rows/term_cols/term. - Firecracker guest exec — the in-guest harness now serves its first RPC
(RuntimeHarness.Exec); the manager records each VM's guest address from the
heartbeat peer and forwardslantern vm execinto firecracker-class VMs over
that channel (services/harness/src/exec.rs,runtime-managerservice.rs). - Firecracker jailer wrapping — opt-in via
FIRECRACKER_JAILER_PATH
(chroot + drop to non-rootFIRECRACKER_JAILER_UID/GID, default 123:100;
FIRECRACKER_CHROOT_BASEdefault/srv/jailer). Argv construction unit-tested;
jailed exec is Linux-runtime-only; jailed snapshot-restore fails closed. - K8s isolation validation harness (
infra/k8s/,make k8s-validate) — kind- Calico cluster asserting default-deny egress, seccomp/cap-drop, and admission
rejection of privileged pods. Ran green (18/18).
- Calico cluster asserting default-deny egress, seccomp/cap-drop, and admission
- End-to-end runtime suite (
e2e/runtime/,make test-e2e) — drives the live
control-plane REST surface through the full VM lifecycle; skips when the stack
is down. - Lima Firecracker dev path (
infra/lima/) — run real microVMs on Apple
Silicon (M3+/macOS 15+) via nested virt; verified ~1.6 s boot on an M4 Max. ExecandStatsgRPC handlers for the Docker backend inruntime-manager
(services/runtime-manager/src/service.rs). Both were previously
UNIMPLEMENTEDstubs; the Docker path is now backed.- Make targets
run-runtime-manager,run-scheduler,run-api-runtimefor
running the full W12 runtime stack locally without Docker Compose. - Docker Compose
runtimeprofile somake devcan optionally include the
runtime-manager and scheduler containers. - Runtime handler tests in the control-plane covering the
/v1/runtime/*
endpoint surface. examples/headless-agents/demo images baked withlantern-harnessas PID 1
so demos work without a separately-deployed harness image.services/runtime-manager/README.mdandpackages/sdk-python/README.md(new).
runtime-manager
- Kata backend (
src/backends/kata.rs):RUNTIME_BACKEND=kataactivates a
thin Docker-delegating backend that setsHostConfig.runtimeto
KATA_RUNTIME_NAME(defaultkata-runtime). Exec and Stats work through the
inner Docker client unchanged. - Wasm backend (
src/backends/wasm.rs):RUNTIME_BACKEND=wasmruns
WebAssembly modules in-process via Wasmtime (WASIp1). Memory limits via
StoreLimitsBuilder; CPU limits via epoch interruption with configurable
limits.timeout. - Exec + Stats for docker and kata: both gRPC methods are now backed for the
Docker and Kata backends. - SnapshotStore (
src/snapshot_store.rs): filesystem-backed snapshot
persistence underSNAPSHOT_DIR(default/var/lib/lantern/snapshots) with
ADR 0007 Tier-2 retention (keep last 3 per(agent_version_id, vm_id), delete
after 7 days). SHA-256 computed over sorted artifact bytes. - RelaySecretResolver (
src/secret_resolver.rs): production secret resolver
callingPOST /v1/runtime/secrets/resolveon the control-plane (ADR 0008).
Activated when bothLANTERN_CONTROL_PLANE_URLandLANTERN_RUNTIME_SECRET_TOKEN
are set. Fail-closed: unset env →EnvSecretResolver(dev/CI default). RuntimeManager.SnapshotRPC added topackages/proto/lantern/v1/runtime.proto
and hand-stub Go bindings ingen/go/.
harness
- Egress per-rule rate limiting (
src/egress.rs): token bucket throttles
byte throughput per CONNECT tunnel whenEgressRule.rate_bpsis non-zero.
Burst = 1 second of traffic;rate_bps == 0is unlimited. - Plain-HTTP method filtering (
src/egress.rs):EgressRule.http_methods
is now checked on plain-HTTP (non-CONNECT) requests. CONNECT tunnels are not
filtered (opaque TLS — no MITM). - Cgroup v2 stats (
src/heartbeat.rs):sample_usage_loopreads
memory.currentandcpu.stat usage_usecfrom the cgroup v2 unified hierarchy
first; falls back to/proc/self/statusVmRSS on macOS / cgroup v1 / no mount.
runtime-scheduler
- Postgres write-through persistence (
internal/store/): whenDATABASE_URL
is set, every cluster-state mutation is written to Postgres (sched_nodes,
sched_vms,sched_snapshotstables) and state is restored from DB on restart.
DB write failures degrade to in-memory-only rather than failing placement. - Snapshot forwarding to manager:
SnapshotRPC now calls the winning node's
manager and persists the returned metadata insched_snapshots.
control-plane
POST /v1/runtime/secrets/resolve(internal/handlers/runtime_secrets.go):
service-to-service endpoint for the runtime-manager'sRelaySecretResolver.
Authenticates viaX-Lantern-Runtime-Token/LANTERN_RUNTIME_SECRET_TOKEN;
returns 403 when the token is unset (fail-closed). See ADR 0008.docs/adr/0008-runtime-secret-relay.md: new ADR documenting the relay
endpoint design and security properties.
CI
sdlc-qa.yml: Go tests now run against apgvector/pgvector:pg16Postgres
service withDATABASE_URLset, so scheduler and control-plane DB-dependent
tests run in CI.make test-db: new Make target that starts dev Postgres if needed and runs
all Go tests withDATABASE_URLwired.
runtime-manager (this batch)
- K8s exec (
src/backends/k8s.rs):exec_commanduses the kubewsfeature
(Api::exec/AttachedProcess) to attach to theagent-runnercontainer and
collect stdout, stderr, and exit code. PreviouslyUNIMPLEMENTED. - K8s stats (
src/backends/k8s.rs):stats_samplequeries
GET /apis/metrics.k8s.io/v1beta1/namespaces/{ns}/pods/{name}. Surfaces a clear
"metrics-server not installed" error when the API group is absent rather than an
opaque transport failure. - Firecracker stats via heartbeat cache (
service.rs): the manager now consumes
RuntimeHarness::Heartbeatbidirectional streams from in-VM harnesses and caches
ResourceUsagepervm_id. TheStatsgRPC method serves the cached value for
Firecracker VMs; entries older than 30 s yieldStatus::UNAVAILABLEwith an
explicit staleness message. - SnapshotStore S3/MinIO tier (
src/snapshot_store.rs):putuploads all
artifacts +meta.jsonto S3 after writing locally;getfalls back to S3 when
the local copy is missing. Activated byS3_ENDPOINT+S3_BUCKET+
AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY. S3 upload failures are non-fatal
(warn-logged; local copy is always written first). Verified live against dev MinIO.
control-plane (this batch)
- Secret relay per-VM binding (
internal/handlers/runtime_secrets.go): the
POST /v1/runtime/secrets/resolveendpoint now verifies thatvm_idexists in
runtime_vms, belongs to the claimedtenant_id, and is in a non-terminal state
before resolving any credentials. Binding failures return404 {"error":"not found"}
— identical for unknown VM, wrong tenant, and terminal state (no oracle). Binding
failures count against the per-IP auth rate limiter to throttle probing. go vetclean: pre-existingt.Context()failures replaced with
context.Background();go vet ./...now exits clean across the control-plane.
CI (this batch)
microvm-integration.yml: addedcargo test --allsteps for
services/runtime-managerandservices/harnesson the KVM runner, running before
the heavier image-build step so test regressions fail fast.
Dev environment
infra/lima/: Lima VM template (firecracker-dev.yaml) + guide for running
real Firecracker microVMs on Apple Silicon Macs (M3+/macOS 15+) via nested
virtualization — provisions the pinned Firecracker release and validates
/dev/kvm. Verified: Ubuntu 22.04 microVM boots to login in ~1.6 s on an M4 Max.
Fixed (live-boot validation on KVM)
- Running
infra/firecracker/integration-test.shon a real KVM host surfaced and
fixed six runtime-manager bugs that blocked an actual microVM boot: missing
rustls CryptoProvider (mTLS panic), invalid firecracker--log-levelflag,
unbuiltcerts.imgdrive, missing vsock runtime dir, swallowed anyhow error
chain, and a corrupting bare snapshot-restore mem-path derivation. A real
microVM now boots end-to-end; the in-guest harness VendSecret agent remains
the one open piece. Also fixed the build-image.sh CI kernel URL (upstream
renamed the artifact keys) and the integration test's certs (Go's TLS needs
EKU extensions openssl omits).