SYSTEM Cited by 1 source
Figma RenderServer¶
RenderServer is a server version of the Figma editor — a C++ application that performs Figma-file rendering in backend services rather than a browser. Used internally for features like thumbnailing, image export, and SVG export. Leverages GPU acceleration for rendering on the full-featured path; a non-GPU variant exists for paths that trade features for tighter sandboxing. (Source: sources/2026-04-21-figma-server-side-sandboxing-containers-and-seccomp)
Why it needs sandboxing¶
RenderServer processes user-supplied Figma files — potentially adversarial input delivered by anyone who can upload a design. "RenderServer has a complex set of features, leverages Graphics Processing Units (GPU) acceleration to perform rendering, and is used in multiple backend services." Complex C++ codebase + third-party image / font / rendering libraries (many memory-unsafe) + adversarial input = a canonical workload-isolation target.
The two sandboxing postures¶
Figma runs RenderServer under two different sandboxes, chosen per use case:
1. Full GPU path — nsjail¶
For rendering that requires GPU acceleration:
- New user / pid / mount / network namespaces per request.
- No network access.
- Specific mount points only: input file, libraries, output folder.
- seccomp-bpf with a strict syscall allowlist.
Chosen over Docker as a drop-in — no service rearchitecture, no orchestration tax. See systems/nsjail#Use case Figma RenderServer.
2. Non-GPU path — seccomp-only, post-refactor¶
For RenderServer use cases that don't need GPU acceleration,
Figma stripped the sandbox down to seccomp-only — cheaper,
faster, simpler to operate. The problem blocking this move
was seccomp's
pointer-dereference limitation:
seccomp cannot filter openat by path (paths are pointer
arguments), so either all openat calls are allowed or none
are. RenderServer needed dynamic file access during image
processing, so blocking openat would break it.
The refactor:
reorder all file opens
to occur before any image processing on potentially
dangerous user input, then apply a restrictive seccomp filter
via libseccomp that denies openat for the rest of the
process lifetime.
Trade-offs disclosed:
- ✅ Easier to test and debug than nsjail.
- ✅ Runs significantly faster than the nsjail version.
- ❌ Locks RenderServer into a single-threaded model.
- ❌ Cannot dynamically load fonts or images later in runtime — all must be opened pre-lockdown.
"This new version of RenderServer is far easier to test and debug, and it runs significantly faster than the previous iteration using nsjail. But, it also introduces constraints on engineers who wish to add new features or improvements to RenderServer."
Worked example: SVG export¶
"Suppose we want to use RenderServer to help users export their Figma file as an SVG. In this scenario, the risky step that must be sandboxed is the processing of the Figma file, which might contain malicious input planted by an attacker who wants to hack Figma. A combination of RenderServer and various third-party libraries written in memory-unsafe languages, mostly in C++, handle processing. RenderServer will first finish generating the preview image before writing it to an output file."
The risk: a compromised RenderServer process during image
processing could use openat to read arbitrary files on the
system. The naive mitigation (block openat via seccomp)
breaks RenderServer's own output-write step. The refactor
resolves this by opening the output file first, then
installing the seccomp filter, then processing the user
input.
Rollout surprises¶
- Default
rlimit_fsize = 1 MBin nsjail silently truncated outputs for large-image inputs. Debuggable because "many errors were correlated with input files that contained large images and resulted in output files that were exactly 1 MB in size. Very suspicious!" One- line config fix. - Seccomp allowlist needed several rounds of expansion as production hit rare codepaths not exercised in testing. "Kernel logs will indicate when a process is killed by seccomp and which syscall caused the problem, without providing much more context" — each iteration was a mini-investigation.
Seen in¶
- sources/2026-04-21-figma-server-side-sandboxing-containers-and-seccomp — canonical system + source. Figma's worked example of how the sandboxing-posture choice ripples into the application's own architecture (single-threaded, no-dynamic-font-load constraints).