ADR-003: gVisor as Linux isolation layer¶
Status: accepted and implemented (Phase 4, Linux).
Context¶
We need an isolation layer that contains an exploited renderer on Linux. Candidates: plain process seccomp (weak), namespaces+cgroups (kernel attack surface still full), Docker/Podman (a dependency we explicitly must avoid), a dedicated VM (heavy, but strongest), gVisor (user-space kernel interposing syscalls).
Decision¶
Use gVisor (runsc), driven directly from the Rust Sandbox Manager (no Docker/Podman).
runsc runs the worker as an OCI container under a user-space kernel that intercepts and
validates syscalls, with an empty network namespace, read-only rootfs, dropped capabilities, an
unprivileged user, and cgroup limits for memory/CPU/PIDs. The host-side manager performs the
lifecycle: locate binary → check version → build OCI bundle → create → run → IPC → kill/delete →
cleanup.
Alternatives considered¶
- Namespaces + seccomp-only sandbox (e.g.,
bubblewrap): much thinner, but every syscall still reaches the host kernel; a kernel bug is directly exploitable. Rejected for the renderer boundary. - Firecracker/Cloud Hypervisor microVM: strongest isolation, but VM bring-up and vCPU/memory cost are higher; keep as the Phase 6 outer boundary for Windows/macOS hosts.
- Docker/Podman as a launcher: rejected (explicit requirement; adds a privileged daemon — worse
trust model than calling
runscourselves).
Security implications¶
gVisor becomes the primary isolation boundary. Defense in depth still applies: unprivileged user, no capabilities, no network, read-only rootfs, resource limits — so an escape from gVisor does not automatically grant the attacker anything beyond host-kernel access to a locked-down process. gVisor escapes are treated as Critical (see threat model A10).
Consequences¶
Linux-only for the real sandbox in Phase 4; the architecture requires an outer VM layer for Windows/macOS (Phase 6). The OCI bundle and rootfs are generated by our own scripts (no container runtime dependency).