LanternDOCS

Isolation Classes

Every headless agent declares an isolation class in its agent.yaml. The class is the security boundary the workload runs behind. On Kubernetes it maps to a runtimeClassName — isolation is a tier on the pod, not a separate backend (ADR 0009).

The decision tree

Pick the least-privileged class the workload can tolerate. Walk it top to bottom and stop at the first match:

Is the code first-party and signed?                 ── yes ─▶  TRUSTED   (runc)
   │ no
Does it load packages from the internet,
or drive a browser, or run user/LLM-generated code? ── yes ─▶  UNTRUSTED (gVisor + egress-deny)
   │ no
Is the *input* adversarial / hostile?               ── yes ─▶  HOSTILE   (Kata microVM)
   │ no
                                                    ────────▶  STANDARD  (gVisor, default)

The classes

ClassRuntimeClassUse when
trustedruncSigned first-party code only. Runs on shared nodes. No untrusted package loading, no LLM-generated code path.
standardgvisorDefault. Your own code on shared, gVisor-isolated nodes. Used when the class is left unset.
untrustedgvisor + egress-denyLoads internet packages (PyPI/npm), drives a browser, or runs LLM-generated code. Adds an egress allowlist and seccomp deny-default.
hostilekata-qemu (or kata-fc)Adversarial workloads. Full-kernel microVM via Kubernetes on a dedicated node pool with no co-tenancy.
wasmcrun+wasmWebAssembly workloads (or in-process Wasmtime on trusted hosts).
devcontainergvisorLong-lived workspace: a persistent pod + PVC that survives across calls.

Defaults & forced classes

  • An unset class resolves to standard.
  • Marketplace bundles and LLM-generated bundles are forced to untrusted — they cannot opt down.
  • trusted requires the signing key; a bundle without it cannot claim trusted.

The fail-closed gate

This is the load-bearing invariant. Untrusted and hostile code never runs in a bare pod:

  • A node may satisfy untrusted only if it advertises the gvisor RuntimeClass.
  • A node may satisfy hostile only if it advertises kata-qemu / kata-fc.
  • A node that lacks the required hardened RuntimeClass fails closed — the run is refused. It is never downgraded to runc.

The requirement is enforced in two places: the manager (which builds the pod spec) and the scheduler's node-capability filter (which only places onto nodes advertising the needed RuntimeClass).

Important: If your cluster has not provisioned the gvisor / kata RuntimeClasses, untrusted and hostile workloads are refused — correct, but operationally visible. The data-plane installer provisions them and a preflight check surfaces the gap before traffic.
Note: gvisor intercepts syscalls in user space — a minority of workloads hit an unimplemented syscall. Declare hostile (full kernel via Kata) for those, or get a runc-on-trusted exception via the admin override.

In a spec

Demo 02 (web-scraper) declares untrustedbecause it pulls third-party packages, and pairs it with an egress allowlist:

spec:
  isolation: untrusted
  network: allowlist_domain
  egress_rules:
    - pattern: "*.wikipedia.org"
      http_methods: ["GET"]
      rate_bps: 1048576      # 1 MiB/s

Egress enforcement and secret vending for untrusted workloads are covered in Identity & secrets.