Run Untrusted Code Without Handing It Your Machine
Sandlock is a lightweight Linux process sandbox. Kernel-enforced policy over filesystem, network, syscalls, and resources, applied in about 5 milliseconds. No root, no image, no container runtime, no hypervisor.
# Read-only system dirs, one writable dir, 512 MB cap,
# and exactly one host reachable on exactly one port.
$ sandlock run -r /usr -r /lib -r /etc -w /tmp \
-m 512M -P 20 -t 300 \
--net-allow api.openai.com:443 \
-- python3 agent.py
Open source, Apache-2.0, written in Rust
Strict Confinement Without the Weight
Containers and microVMs package and boot a system. To run one command you do not trust, they make you pay for a system anyway.
Containers
An image, a daemon, and root or user namespaces, for a boundary that is a namespace rather than a policy.
MicroVMs
A separate kernel is a strong boundary, but it needs KVM, a guest image, and gives no view of what runs inside.
Sandlock
A policy applied to a process: the kernel enforces the rules, a small supervisor handles the rest.
One Policy, Six Enforcement Surfaces
One policy object, whether written as CLI flags, a TOML profile, or a struct in Python, Rust, or Go.
Filesystem
Landlock read and write grants, evaluated by the kernel on every access, immune to TOCTOU races.
Network
Default-deny egress. Allow a host, IP, or CIDR on specific ports over TCP, UDP, or ICMP.
HTTP ACL
Allow POST api.openai.com/v1/chat/completions and nothing else, with zero-config HTTPS interception.
Credential injection
The key is attached in the proxy after the ACL check. The sandboxed process never holds it.
Copy-on-write
Writes are staged, then committed or discarded. --dry-run shows what a command would change.
Resources
Memory, processes, open files, CPU, disk, and GPU device selection, without cgroups.
Kernel First, Supervisor Second
Confinement is installed in the child before it executes anything. What the kernel can enforce, the kernel enforces.
Landlock
Kernel-evaluated access control for paths, TCP ports, and IPC, irreversible for the life of the process tree.
seccomp-bpf
A default blocklist removes syscall families a confined workload has no business using.
seccomp notify
The supervisor sees selected syscalls first: IP checks, memory accounting, COW, /proc virtualization.
A Sandbox You Can Program, Not Just Configure
Handlers run your code inside the supervisor, on any syscall you choose, and decide what the workload observes.
import sandlock
from sandlock.handler import Handler, NotifAction
class Audit(Handler):
def handle(self, ctx):
print(f"open {ctx.read_path()} from pid {ctx.pid}")
return NotifAction.continue_()
sb = sandlock.Sandbox(fs_readable=["/usr", "/lib", "/etc"])
sb.run_with_handlers(
cmd=["python3", "task.py"],
handlers=[("openat", Audit())],
)
Confinement You Can Leave On
Landlock and the seccomp blocklist cost nothing per syscall. Only syscalls the supervisor registers for take a round trip.
| Workload | Bare metal | Sandlock | Docker |
|---|---|---|---|
/bin/echo startup |
2 ms | 7 ms | 307 ms |
| Redis SET, 100K ops | 82K rps | 80K rps | 52K rps |
| Redis GET, 100K ops | 79K rps | 77K rps | 53K rps |
| Redis p99 latency | 0.5 ms | 0.6 ms | 1.5 ms |
| COW fork × 1000 | No equivalent | 530 ms | No equivalent |
Measured on a typical Linux workstation. Redis under Sandlock holds 97.1% of bare-metal throughput; COW fork clones in about 530 µs.
Reach for It From Where You Already Are
One Rust core. Every surface takes the same policy.
sandlock run, ps, inspect, kill, learn.
A Sandbox dataclass, pipelines, COW fork, policy callbacks.
The core itself: typed builder, async execution, custom handlers.
cgo bindings with a plain config struct, safe across goroutines.
Drop-in runtime for containerd, CRI-O, and Kubernetes.
Sandboxed shell, Python, and file tools for any MCP client.
Built for Code You Did Not Write
AI agents and tool use
A workspace, one API endpoint, and nothing else. The key stays out of the agent's reach.
Read moreCI and untrusted builds
Build a pull request with the source tree copy-on-write, the network closed, and no Docker socket to hand out.
Read morePer-request code execution
A fresh sandbox per request. At 5 ms there is no warm pool to keep and nothing carries over.
Read moreStart Confining in Under Five Minutes
Apache-2.0, free at any scale. When you outgrow one machine, run it as a fleet.