TL;DR: Use a per-session microVM or gVisor sandbox, hardened (non-root, read-only base, no runtime socket, no host mounts). Put nothing valuable inside: no credentials, only the task's files copied in read-only with an ephemeral scratch area. Deny network by default; allow only an internal package mirror through an egress proxy that rejects private and metadata addresses. Enforce CPU, memory, disk, process and wall-clock limits. For GPUs, give each session a dedicated device or a partition with documented isolation, and clear memory between uses. Destroy the sandbox after the session, broker any needed service calls outside it with scoped tokens, and treat all outputs as untrusted.
How to approach it
State the threat: the code may be written under the influence of injected content, so assume it is hostile. Separate the design into isolation boundary, environment (files, credentials, network, resources), lifecycle, outputs and observability. Expect the interviewer to change constraints; show how each change is absorbed.
A strong answer
- 1
1 · Per-session microVM or gVisor
Hardened
- Non-root, read-only base, no runtime socket, no host mounts
- 2
2 · No secrets inside
Task files only
- Inputs copied read-only, ephemeral scratch
- 3
3 · Network denied by default
Internal package mirror only
- No metadata endpoint, no internet
- 4
4 · Resource limits
CPU, memory, time, GPU
- Dedicated GPU or MIG slice; no shared memory
- 5
5 · Destroyed after
Nothing persists
- Outputs reviewed before leaving
Threat model. Hostile code tries to escape to the host, read secrets, reach internal services or the metadata endpoint, exfiltrate the user's files, persist for later sessions, attack other tenants via shared hardware, or exhaust resources.
Design.
| Concern | Decision |
|---|---|
| Boundary | Firecracker or Kata microVM per session (or gVisor where startup latency matters more); hardened config |
| Files | Copy in only task inputs; mount read-only; ephemeral scratch disk with a size cap; nothing from the host |
| Credentials | None. If code must call a service, a broker outside the sandbox makes the call as the user with a scoped, short-lived token |
| Network | No egress by default; optional allowlisted package mirror via proxy that blocks private ranges and metadata |
| Resources | vCPU, memory, disk, PID and wall-clock limits; kill on breach |
| GPU | Dedicated GPU per session, or hardware partitioning with documented isolation; driver patched; memory cleared on release |
| Lifecycle | Fresh sandbox per session, destroyed afterwards; pre-warmed pool of never-used sandboxes for latency |
| Outputs | Size- and type-limited; rendered safely; never executed on the host; scanned if passed onward |
| Observability | Log code, network attempts, resource usage and exit reasons per session |
Constraint changes.
- "It needs the internet to call public APIs." Route through an egress proxy with domain allowlists per feature, strip credentials, log destinations, and cap request rates; open internet becomes an exfiltration channel otherwise.
- "It needs the user's database." No credentials inside; a query broker outside authenticates as the user, enforces read-only access and row limits.
- "It needs to persist state across sessions." Store state outside the sandbox in a per-user location, treated as untrusted when loaded back in.
- "Latency must be under a second." Pre-warmed fresh microVMs or gVisor; never reuse a previous session's sandbox.
GPU specifics. GPU drivers are large kernel components, and GPU memory isolation has had weaknesses (LeftoverLocals, CVE-2023-4969). For untrusted code, avoid sharing a GPU between tenants or sessions without hardware partitioning that the vendor documents as isolating, clear memory between uses, and keep drivers patched.
Leaky sandbox
Shared-kernel container
creds mounted
Code calls metadata, internet
exfiltrates
Account compromise
Outcome, unsafe: Data leaves
Host at risk
Sealed sandbox
MicroVM or gVisor per session
no secrets
Egress denied, limits set
destroyed after
Nothing to take
Outcome, safe: No way out
Resources bounded
What interviewers probe next
- "Why not containers with seccomp?" Shared host kernel; for hostile code the kernel attack surface is too large, and GPU drivers enlarge it further.
- "How do you stop data exfiltration through allowed package downloads?" Mirror-only egress with no arbitrary query strings to external hosts, size limits on requests, and logging.
- "How do you know the sandbox works?" Red-team it: escape attempts, metadata access, private-range scans, fork bombs; run these as regression tests.
What if?
What if · interview follow-ups
Hold your answer as the constraints change
A data-analysis agent writes and runs Python on files users upload, and the first prototype runs code directly on the API server.
Start here
Why is running code on the API server dangerous?
Who effectively wrote the code?
The code is influenced by user files and possibly injected instructions, so it is untrusted. On the API server it can read secrets, reach internal services and the metadata endpoint, and affect other users.
Carry it forwardAgent-written code is untrusted code.
Weak answerTrusting code because the agent generated it.
Constraint changes
What sandbox would you use?
Which isolation fits untrusted code?
A per-session microVM or gVisor sandbox, hardened: non-root, read-only base image, no container runtime socket and no host mounts. Plain shared-kernel containers are too thin for code shaped by untrusted input.
Carry it forwardPer-session microVM or gVisor sandbox.
Weak answerOne long-lived sandbox shared by users.
Constraint changes
What goes inside the sandbox?
What could the code steal if it tried?
Nothing valuable: no credentials, only the task's files copied in read-only, and an ephemeral scratch area. If code needs a service, the sandbox calls a narrow broker that checks the user's authority, not a credential inside.
Carry it forwardKeep the sandbox empty of secrets.
Weak answerMounting the user's whole drive.
Constraint changes
What network access should it have?
Where could the code send data?
Deny by default. Allow only an internal package mirror through an egress proxy that rejects private and metadata addresses. That blocks exfiltration of the uploaded data and SSRF.
Carry it forwardDefault-deny network with a narrow mirror.
Weak answerAllowing internet access for pip install.
Constraint changes
What about resources, GPUs and cleanup?
What persists after the session?
Enforce CPU, memory, disk, process and wall-clock limits. For GPUs, give each session a dedicated device or a partition with documented isolation, and clear memory between uses. Destroy the sandbox after the session and log what ran.
Carry it forwardLimit resources, isolate GPUs, destroy after use.
Weak answerReusing sandboxes between users.
Now defend it
What execution design would you implement?
Per-session microVM or gVisor sandboxes, non-root with read-only base and no runtime socket or host mounts; no credentials inside, task files copied read-only; default-deny network with an internal mirror via an egress proxy; CPU, memory, disk, process and time limits; dedicated or properly partitioned GPUs with memory clearing; destruction after use; and logs of executed code.
How it's scored
Weak: "Run it in Docker."
Hire: Strong boundary, no credentials, network denied by default, resource limits.
Strong Hire: Full environment design with brokered access, GPU isolation, lifecycle and outputs, and adapts cleanly to each constraint change.
Common mistakes
- Mounting the runtime socket or user home directory.
- Open internet "for pip".
- Reusing sandboxes across users.
- Executing sandbox outputs on the host.