Linux Sandbox (Landlock + seccomp)
On Linux, runok uses a combination of three kernel mechanisms to enforce sandbox policies:
| Mechanism | Controls |
|---|---|
| bubblewrap | Mount namespace isolation (file system layout) |
| Landlock LSM | File system access permissions |
| seccomp-bpf | Network system call filtering |
Two-stage execution
Section titled “Two-stage execution”Linux sandboxing requires a two-stage execution model because the different mechanisms must be applied at different points in the process lifecycle.
Stage 1: Namespace isolation (bubblewrap)
Section titled “Stage 1: Namespace isolation (bubblewrap)”runok launches itself inside bubblewrap (bwrap) using a hidden __sandbox-exec subcommand, which creates an isolated mount namespace:
/is mounted read-only (the entire root file system)- Writable directories are re-mounted with write access
- Protected subpaths are mounted read-only on top (mount ordering ensures deny takes priority)
/procand/devare set up for the sandboxed process/tmpgets a private tmpfs (unless it overlaps with a writable root)- All namespaces are unshared (
--unshare-all), with network selectively shared back if allowed
Stage 2: Process-level restrictions (Landlock + seccomp)
Section titled “Stage 2: Process-level restrictions (Landlock + seccomp)”Inside the bubblewrap namespace, the re-invoked runok process applies:
- Landlock rules for file system access control
- seccomp-bpf filters for network system call blocking
- Then replaces itself with the target command via
execvp
This two-stage model is necessary because bubblewrap sets up the namespace before exec, while Landlock and seccomp must be applied within the namespace. By re-invoking itself via runok __sandbox-exec, runok achieves this without requiring a separate helper binary.
Landlock (file system access)
Section titled “Landlock (file system access)”Landlock is a Linux Security Module (available since Linux 5.13) that provides unprivileged file system access control.
runok uses Landlock to define which paths are readable and writable:
/is granted read-only access/dev/nullis granted read-write access (required by many tools)/dev/zero,/dev/urandom,/dev/randomare granted read-only access/tmpis granted read-write access (unless overlapping with a writable root)- Each configured
writabledirectory is granted read-write access
Compatibility
Section titled “Compatibility”runok uses Landlock ABI V5 with best-effort compatibility. On older kernels with limited Landlock support, unsupported permissions are automatically dropped. The sandbox still provides as much protection as the kernel supports.
seccomp-bpf (network control)
Section titled “seccomp-bpf (network control)”When network.allow is false, runok installs a seccomp-bpf filter that blocks network socket creation:
- The
socket(2)system call is intercepted - If the socket domain is not
AF_UNIX, the call returnsEPERM AF_UNIX(Unix domain sockets) is always allowed for local IPC
This effectively blocks TCP (AF_INET) and IPv6 (AF_INET6) connections while keeping local inter-process communication working.
All other system calls are unaffected — seccomp is only used for network control, not for general system call filtering.
Deny path handling
Section titled “Deny path handling”The deny list in the sandbox configuration is enforced through bubblewrap’s mount ordering:
- Literal paths (e.g.,
.git,/etc/shadow) are mounted read-only via--ro-bind - Glob patterns (e.g.,
.env*,~/.ssh/**) are expanded against the filesystem at startup, and each matched real path is mounted read-only
Related
Section titled “Related”- Sandbox Overview — How sandbox presets are defined and applied.
- Security Model — What the sandbox protects.
- macOS Sandbox (Seatbelt) — macOS implementation.