Home
Why Sandlock
How It Works Use Cases Comparison Security Model
Docs
Documentation Home Getting Started CLI Reference Python SDK Sandbox Reference FAQ
Products
Overview Sandbox HTTP API Sandbox Scheduler
GitHub Schedule a Demo
Security model

What Sandlock Guarantees, and What It Does Not

A sandbox is only useful if you know its edges: the trust boundaries, what each layer guarantees, and what is out of scope.

By Cong Wang · Updated

Trust boundaries

Three Tiers of Trust

Trust placed in userspace is kept as small as the policy allows.

Fully trusted

The host kernel

Evaluates Landlock and seccomp. Sandlock shares it with the workload; if the kernel is compromised, so is every guarantee here.

Partially trusted

The supervisor

Runs in the parent, outside the sandbox, deciding the syscalls the kernel hands it. Built-in handlers run first, so a custom one can extend confinement but never relax it.

Untrusted

The workload

Assumed hostile. NO_NEW_PRIVS, Landlock, and seccomp are installed and inherited descriptors closed before exec, so it never runs unconfined.

Scope

In Scope and Out of Scope

Sandlock defends against

  • Filesystem escape. Only granted Landlock paths open; denials override grants.
  • Unapproved network egress. Default deny: Landlock refuses TCP connects; seccomp refuses UDP, ICMP, and raw sockets.
  • Exfiltration on an approved host. HTTP rules match method, host, and path.
  • Credential theft. The secret stays in the supervisor and is attached after the ACL check.
  • Escalation via setuid. NO_NEW_PRIVS makes a setuid binary confer nothing.
  • Reaching sibling processes. Landlock v6 scopes deny abstract sockets and signals outside the sandbox.
  • Host resource exhaustion. Memory, processes, open files, CPU share, and COW disk are capped.
  • Unintended writes. Copy-on-write discards a failed run's writes.

Sandlock does not defend against

  • Kernel vulnerabilities. An escalation bug in a permitted syscall defeats the sandbox. That is the price of no hypervisor.
  • Hardware side channels. Spectre-class and cache timing attacks. CPU pinning is not a mitigation.
  • A policy that grants too much. Sandlock enforces the policy you wrote, not the one you meant.
  • A hostile launcher. Whoever controls the process that starts Sandlock controls the policy.
  • The workload starving itself. Limits protect the host, not the workload's progress.
  • Open-file limits as a boundary. A privileged sandbox can raise RLIMIT_NOFILE again. It is a budget.
  • Covert channels. Sandboxes on one host share timing, disk, and memory bandwidth.
  • Packet crafting. Raw ICMP sockets are never exposed, deliberately.
Design detail

Time-of-Check to Time-of-Use

seccomp_unotify(2) documents the hazard: after a continue verdict, the kernel re-reads any argument passed by pointer, so a path string a supervisor inspected can be overwritten before the kernel acts. Filtering on path strings in userspace is unsound, however carefully written. Sandlock addresses it two ways.

Path strings never reach policy callbacks

Events carry the syscall, PID, network destination, and argv, never a path. Path decisions belong in Landlock rules, which the kernel resolves at access time. Runtime decisions use deny_path() and allow_path(), which add Landlock restrictions rather than filtering strings.

argv is exposed, and made safe first

Before exposing argv for an execve, the supervisor freezes every task in its process index, including peers that could alias the memory. If the freeze cannot be established, for instance under a YAMA ptrace policy, the syscall is denied with EPERM. The invariant is never silently relaxed.

Defaults

Strict by Default, Explicit to Weaken

Sandlock starts from deny. A permissive default fails silently: you learn about the gap from an incident rather than an error.

Surface With no policy To open it up
Filesystem Nothing readable or writable, not even /usr. Name every path.
Network No TCP connect; no UDP, ICMP, or raw socket creation. --net-allow '*' explicitly; ICMP needs its own icmp:// rule.
Syscalls The default blocklist, always. Named groups only, such as System V IPC. A typo fails loudly.
Kernel protections All enforced; Sandlock refuses to start if one is missing. Per protection: allow_degraded or disable.

A sandbox's protection posture is part of its checkpoint, so a restore keeps the protections it was built with. sandlock check reports the host's Landlock ABI.

Secrets

Credential Handling

A workload can use a secret without holding it. The supervisor loads it from an environment variable, file, or descriptor and attaches it in the proxy strictly after the ACL check, so a rejected request never carries it.

  • The child never carries the value. An env: source is stripped from its environment; an fd: source never touches disk.
  • Cleartext HTTP warns. Attaching a credential over plain HTTP emits a one-per-run warning.
  • The CA key stays in memory. --http-inject-ca writes only the public certificate into the bundles you name.

There is no secret-manager client, deliberately. Vault, a cloud store, or a CSI driver materializes the value into a file: or fd: source, off ps and out of shell history.

Research

Where This Threat Model Is Written Down

The guarantees above, and the attacks out of scope, are stated formally in the paper.

Paper

Sandlock: Confining AI Agent Code with Unprivileged Linux Primitives

Cong Wang and Yusheng Zheng. arXiv:2605.26298, May 2026.

“It also supports dynamic network decisions, HTTP-level access control, TOCTOU-safe inspection of execve arguments, and reversible filesystem effects. On our workstation, Sandlock adds roughly 5 ms of startup overhead and runs Redis at bare-metal throughput (within measurement noise).”
Disclosure

Reporting a Vulnerability

Found a way out of a Sandlock policy? We want to hear it first.

Email contact@multikernel.io with a reproducer where possible. Please do not open a public issue until we have responded.