Skip to content

CONCEPT Cited by 3 sources

Server-Side Sandboxing

Server-side sandboxing (also called workload isolation) is the practice of running a given piece of server-side code inside a restricted execution environment whose capabilities are a strict subset of what a general-purpose process on the same host would have — on the premise that vulnerabilities will exist in the sandboxed code, so the goal is to bound the blast radius of a successful exploit rather than try to prevent all exploits.

(Source: sources/2026-04-21-figma-server-side-sandboxing-virtual-machines)

The three canonical primitives

Figma's security team groups practical options into three levels of isolation strength vs overhead:

Primitive Boundary Compatibility Overhead
Virtual machines / micro-VMs Hardware virtualisation (hypervisor) Full OS; runs almost anything unmodified Highest boot + memory cost
Containers Kernel namespaces + cgroups Linux-only; most workloads unmodified Shared kernel attack surface
seccomp Syscall allowlist Workload-specific tuning Lightest; highest friction

(See parts 2 + 3 of the Figma series. sources/2026-04-21-figma-server-side-sandboxing-virtual-machines covers the VM row in detail; sources/2026-04-21-figma-server-side-sandboxing-containers-and-seccomp covers the containers + seccomp rows.)

The two questions sandboxing must answer

For any sandboxing choice, Figma asks:

  1. Can a malicious job escape the sandbox? (integrity of the primitive — see concepts/vm-escape for the VM case, concepts/container-escape for the container case, concepts/kernel-attack-surface for the seccomp-only case)
  2. If it can't escape, what damage can it do with the sandbox's own capabilities? (network egress, IAM permissions, credential lifetime)

Both must be bounded. A sandbox with a perfect boundary but excessive permissions is still a risk — see patterns/minimize-vm-permissions.

Containers and seccomp — Part 3 framings

Part 3 of the Figma series adds the nuances specific to the kernel- isolation rows:

Containers are not automatically secure

"By default, containers are not automatically secure sandboxes because the level of isolation provided depends very much on [three factors]: runtime implementation, OS primitives and interface available to the runtime, and runtime configuration."

Unlike VMs, the operator owns a configuration axis — more control = more foot-guns. The three axes together form the concepts/container-escape attack surface. gVisor is the technology that reduces axis 1 (kernel surface) by interposing a user-space reimplemented kernel.

Seccomp-only sandboxes trade compatibility for surface

The premise behind seccomp-only: "many programs do pure computation, and thus do not need dynamic access to the filesystem or to make network calls at all." For those, a syscall allowlist restricting to write-to-open-fd / exit / memory-allocation / time is both enough and dramatically cheaper than any container or VM.

Two limitations force engineering decisions:

  • seccomp can't dereference pointer args — so openat can't be filtered by path. The workaround is either a coarser allowlist or a program rewrite that reorders dangerous syscalls before the untrusted-input phase so a sharper filter lands mid-program.
  • Allowlists are brittle — every library upgrade / rare codepath / kernel change can add a syscall that trips the filter. Debugging is painful (kernel log names the failing syscall, nothing more).

Composition: patterns/seccomp-bpf-container-composition

systems/nsjail and systems/firejail combine namespaces + cgroups + seccomp in one sandbox; each layer defends a different axis, so a single-primitive compromise is not a total compromise. Figma's production sandbox for RenderServer is nsjail (full GPU path) + seccomp-only-post- refactor (non-GPU path).

Four trade-off axes

Figma's decision framework for picking among primitives:

  • Environment — what the workload needs from the OS (libraries, binaries, syscalls).
  • Security & performance — strength of the isolation boundary vs cold-start latency, per-workload overhead.
  • Development cost & friction — debugging experience, tooling maturity, how much workload modification is required.
  • Maintenance & operational overhead — orchestration complexity, need for specialist SRE expertise, per-VM state tracking.

Anti-pattern: sandboxing as primary defence

Server-side sandboxing is defence in depth, not a replacement for secure code. Figma's framing: "rather than try to prevent security vulnerabilities entirely, we employ server-side sandboxing … to minimize these security risks." The sandbox exists because the inner code is assumed to be exploitable — ImageMagick, document converters, browser engines, third-party libraries fetched over a URL, etc.

Seen in

  • sources/2026-04-21-figma-server-side-sandboxing-an-introduction — canonical intro / framing post. Establishes the two-question frame (can a compromise escape? what can it do with the sandbox's own capabilities?), the three-primitive table, and the four-axis decision questionnaire used to pick among VMs / containers / seccomp. Motivating example is ImageTragick (2016) — an ImageMagick RCE that hit any server running the library on user-supplied images; Figma's posture: "Buggy software is a fact of life … it's nearly impossible to prevent all vulnerabilities," so sandbox to bound the blast radius.
  • sources/2026-04-21-figma-server-side-sandboxing-virtual-machines — canonical VM-row framing, with the VM primitive deep-dived and Figma's AWS Lambda / Firecracker usage for link-preview + canvas image-fetch workloads as the production exemplar.
  • sources/2026-04-21-figma-server-side-sandboxing-containers-and-seccomp — canonical containers + seccomp rows, with Figma's RenderServer as the worked exemplar (nsjail for the GPU path; seccomp-only-after-refactor for the non-GPU path). Introduces the three-axis container-escape attack surface, the seccomp pointer-dereference limitation, and operational surprises like the 1-MB rlimit_fsize default.
Last updated · 200 distilled / 1,178 read