How this sandbox works

There is no AST allowlist here. Imports, eval/exec, dunder attribute access — all permitted. Every submission runs in a real, unrestricted Python namespace. The only thing standing between your code and the host is the kernel-level stack below.

  1. cgroup v2 leaf — hard memory / CPU / pids caps, created before anything else runs.
  2. Namespaces — fresh network (zero routes, no interfaces up), mount (private, non-propagating), IPC, and UTS namespaces. A fresh network namespace has no reachability at all by kernel default.
  3. uid/gid drop — setresuid/setresgid to a dedicated unprivileged account, supplementary groups cleared, capabilities dropped, PR_SET_NO_NEW_PRIVS set.
  4. Landlock — scoped read+execute filesystem ruleset (just enough for the Python interpreter to import its own stdlib), zero write access anywhere.
  5. seccomp — default-deny syscall allowlist covering native x86_64 and the ia32/x32 syscall tables (a filter that only covers one ABI is a classic bypass). ptrace, process creation, namespace/mount syscalls, kernel-feature surfaces (bpf, io_uring, userfaultfd, ...), and all networking syscalls are killed outright.
  6. rlimits — CPU time, address space, open files, and a wallclock alarm as a backstop beneath the cgroup.

The flags

Three flags, one per barrier:

Be honest about the risk

Syscall-filter sandboxes (seccomp + namespaces + Landlock, hand-rolled) have more historical CTF pyjail escapes than purpose-built tools like nsjail or gVisor. That tradeoff was made deliberately, for speed of delivery. Concrete mitigations in place: default-deny (not denylist) seccomp, multi-ABI coverage, unprivileged user namespaces disabled host-wide, every SIGSYS kill logged for review, and alerting on repeated crashes from one submission's code signature.