Skip to main content

[ GUIDE / HARDENING ]

Before you scale hard: what to harden

sandboxd v1 is tuned for "works anywhere with just Docker, in one command." To keep it that simple, a few things were left basic on purpose. None of them affect the core loop (create → build → preview → sleep → wake → persist) — they're the knobs to tighten once you have real users and real money on the line. Plain version:

Kept simple on purposeFine forDo this when you're scaling / serious
Container isolation (hardened Docker), not full VMsyour own users running their own coderunning untrusted strangers' code → put each tenant on its own VM, or use gVisor / Kata / Firecracker
API auth is OFF by defaultlocal developmentturn it on (SANDBOXD_API_AUTH_DISABLED=false + tokens) and never expose the API port unauthenticated
Preview links are public (anyone with the URL)demos, sharinggate sensitive previews (the private-sandbox forward-auth hook)
Open, unlogged network egressmost appsadd firewall / egress rules + logging
Plain-directory workspaces, no disk quotaa single serveradd filesystem/volume quotas; plan multi-host sharding
One server, one Docker socket (the control plane is root-equivalent on the host)starting outtreat the host as a trust boundary, keep it patched, isolate it, and don't co-locate unrelated secrets

The short version for a fast-scaling company: the three that matter most are (1) stronger isolation (VM-per-tenant) if you ever run untrusted code, (2) turn on API auth and lock down the host, and (3) plan for more than one machine. Everything else above is a config change, not a rewrite. Start lean, revisit these as you grow — and PRs are very welcome (CONTRIBUTING.md).

The isolation model

Each sandbox runs under hardened runc: --cap-drop=ALL, --security-opt=no-new-privileges, --read-only rootfs with tmpfs for /tmp, a hard --memory ceiling, --pids-limit, and file-descriptor ulimits.

The threat model is authenticated, accountable users running their own code — not anonymous hostile multi-tenancy. Kernel-CVE container escape is mitigated by patching, not by a VM boundary; if you need stronger isolation, run sandboxd on a dedicated VM per trust domain.

Design choices you can tighten later

Areav1 choiceTrade-off / how to harden
Workspace storageplain directory per sandboxno hard per-workspace disk quota (host fs is shared); add quotas at the fs/volume layer if needed
Memoryhard --memory ceiling per sandboxthe softer cgroup memory.high throttle is opt-in (SANDBOXD_SET_MEMORY_HIGH, needs host cgroup access)
Egressdefault-allow, no loggingadd host firewall rules / a proxy if you need egress control
Package installspublic npm/PyPI registriesrun your own caching proxy and point the image at it for speed/airgap
TLS / domainHTTP on *.localhost out of the boxswitch to a real wildcard domain + cert resolver (see Production / TLS)
Snapshots/templatesAPI present, experimental on directory storageuse plain workspace copies, or contribute a directory-tar snapshot backend