Skip to content

Sandbox runtimes

A sandbox’s RuntimeClass decides what stands between agent-directed code and the host kernel. This page answers what else it decides: which of the sandbox’s protections still hold under gVisor, under Kata, and under Kata on Firecracker. For how to set a RuntimeClass, see Run agents under gVisor or Kata. For the protections themselves, see Sandbox security.

gVisor puts a user-space kernel between the workload and the host’s. Kata runs the pod in a lightweight VM with its own guest kernel, on a hypervisor such as QEMU, Cloud Hypervisor or Firecracker.

A runtime can change which of the sandbox’s other protections hold. Each was measured: Omnia’s sandbox pod shape (the restricted security context, a /workspace subPath of an NFS volume, a Secret volume, a bounded scratch volume and the NetworkPolicy) was run under each runtime.

ProtectionruncgVisorKata (QEMU, Cloud Hypervisor)Kata on Firecracker
Ingress only from the owning agent✓✓✓✓
Egress denied except declared peers✓✓✓✓
/workspace shows only the claim’s directory✓✓✓✓
Writes to /workspace reach the volume✓✓✓✗
Scratch sizeLimit enforced✓✓✓✗
Secret files readable, no ServiceAccount token✓✓✓✓
Seccomp filter on the workload✓gVisor’s ownnone inside the VMnone inside the VM
Kernel the workload seeshostgVisorguest VMguest VM

Three results shape what you can rely on.

  • Kata applies no seccomp filter inside its VM. The guest kernel is the boundary instead, and an exploit has to escape the VM to reach the host.
  • Firecracker has no shared filesystem. The guest gets a copy of the workspace volume: it reads correctly, but its writes stay inside the VM, and a scratch volume’s sizeLimit goes unenforced. Firecracker suits only a class with neither a workspace nor scratch, and none of the shipped classes qualifies.
  • The kubelet follows a subPath symlink before any runtime sees the mount. A link from a claim’s directory to a sibling’s is followed on every runtime, gVisor and Kata included. Before it builds the pod, the operator refuses a mount whose directory, or any directory above it in the volume, is a symlink. That check is the guard whichever runtime you choose.

The NetworkPolicy holds under every runtime because it is enforced on the node, outside the pod.

Every Omnia release re-checks the table. Before a build is published, a conformance suite runs sandboxes through the operator on runc, gVisor, Kata with QEMU, Kata with Cloud Hypervisor, and Kata on Firecracker, and asserts each protection above. A runtime upgrade that drops one fails the release instead of reaching you.

Each class reports what its runtime gives it. The operator resolves the RuntimeClass to a runtime family (runc, gvisor, kata, kata-firecracker or unknown) and writes it, with the protections that hold there, to the class’s status. A class whose RuntimeClass does not exist, or a Firecracker class with a workspace or scratch volume, reports Ready=False, and its claims fail rather than start. A RuntimeClass Omnia does not recognise is reported as unknown and allowed: none of the protections above is verified on it. See Class status.

The cost is speed. Every runtime measured started the sandbox pod within a few seconds, but gVisor intercepts every system call, so syscall-heavy and small-file work, such as builds, runs slower than on runc.