multikernel/sandlock

The lightest AI sandbox. A process-based sandbox for Linux, no container, no VM, no privilege, no prompt injection

Rust

573

1,295 commits

updated Oct 18, 2026

See the code

README

Sandlock

Lightweight process sandbox for Linux. Confines untrusted code using Landlock (filesystem + network + IPC), seccomp-bpf (syscall filtering), and seccomp user notification (resource limits, IP enforcement, /proc virtualization). No root, no cgroups, no containers.

sandlock run -w /tmp -r /usr -r /lib -m 512M -- python3 untrusted.py

Why Sandlock?

Containers and VMs are powerful but heavy. Sandlock targets the gap: strict confinement without image builds or root privileges. Built-in COW filesystem protects your working directory automatically.

FeatureSandlockContainerMicroVM (Firecracker)
Root requiredNoYes*Yes (KVM)
Image buildNoYesYes
Startup time~5 ms~200 ms~100 ms
KernelSharedSharedSeparate guest
Filesystem isolationLandlock + seccomp COWOverlayBlock-level
Network isolationLandlock + seccomp notifNetwork namespaceTAP device
HTTP-level ACLMethod + host + path rulesN/AN/A
Syscall filteringseccomp-bpfseccompN/A
Resource limitsseccomp notif + SIGSTOPcgroup v2VM config

* Rootless containers exist but require user namespace support and /etc/subuid configuration.

Architecture

Sandlock is implemented in Rust for performance and safety:

  • sandlock-core: Rust library (Landlock, seccomp, supervisor, COW, pipeline)
  • sandlock-cli: Rust CLI binary (sandlock run ...)
  • sandlock-oci: OCI runtime shim for containerd, CRI-O, and Kubernetes (namespace-less)
  • sandlock-ffi: C ABI shared library (libsandlock_ffi.so)
  • Python SDK: ctypes bindings to the FFI library
  • Go SDK: cgo bindings to the FFI library

See docs/architecture.md for how the pieces fit together and how confinement is applied.

Requirements

  • Linux 6.12+ (Landlock ABI v6), Rust 1.70+ (to build)
  • Python 3.8+ (optional, for Python SDK)
  • No root, no cgroups
FeatureMinimum kernel
seccomp user notification5.6
Landlock filesystem rules5.13
Landlock TCP port rules6.7 (ABI v4)
Landlock IPC scoping6.12 (ABI v6)

Protections can be selectively waived per-policy when needed; see docs/sandbox-reference.md#protection-opt-out.

Install

From source

# Build the Rust binary and shared library
cargo build --release

# Install Python SDK (auto-builds Rust FFI library)
cd python && pip install -e .

CLI only

cargo install --path crates/sandlock-cli

Optional features

All five features (http, checkpoint, image, profiles, cow) are enabled by default. Build with none or select the ones you need:

cargo build --release --no-default-features
cargo build --release --no-default-features --features http,profiles

See Building Sandlock for feature dependencies and Rust library configuration.

Quick Start

CLI

# Basic confinement
sandlock run -r /usr -r /lib -w /tmp -- ls /tmp

# Interactive shell (the sandboxed command inherits the terminal)
sandlock run -r /usr -r /lib -r /lib64 -r /bin -r /etc -w /tmp -- /bin/sh

# Resource limits + timeout
sandlock run -m 512M -P 20 -t 30 -- ./compute.sh

# Outbound allowlist: one host on one port
sandlock run --net-allow api.openai.com:443 -r /usr -r /lib -r /etc -- python3 agent.py

# HTTP-level ACL (method + host + path rules via transparent proxy)
sandlock run \
  --http-allow "GET docs.python.org/*" \
  --http-allow "POST api.openai.com/v1/chat/completions" \
  --http-deny "* */admin/*" \
  -r /usr -r /lib -r /etc -- python3 agent.py

# COW filesystem (writes captured, committed on success)
sandlock run --workdir /opt/project -r /usr -r /lib -- python3 task.py

# Dry-run (show what files would change, then discard)
sandlock run --dry-run --workdir . -w . -r /usr -r /lib -r /bin -r /etc -- make build

# Use a saved profile
sandlock run -p build -- make -j4

The full option tour (GPU, network grammar, HTTPS MITM, credential injection, port virtualization, chroot, nesting) is in docs/cli.md.

Python API

from sandlock import Sandbox, BranchAction

sandbox = Sandbox(
    fs_writable=["/tmp/sandbox"],
    fs_readable=["/usr", "/lib", "/etc"],
    max_memory="256M",
    max_processes=10,
    clean_env=True,
)

# Run a command (with optional timeout in seconds)
result = sandbox.run(["python3", "-c", "print('hello')"], timeout=30)
assert result.success
assert b"hello" in result.stdout

# Dry-run: see what files would change, then discard
sandbox = Sandbox(fs_writable=["."], workdir=".", fs_readable=["/usr", "/lib", "/bin", "/etc"],
                  on_exit=BranchAction.ABORT)
result = sandbox.run(["make", "build"])
for c in result.changes:
    print(f"{c.kind}  {c.path}")  # A=added, M=modified, D=deleted

See python/README.md for the SDK guide, including HTTP ACL, chroot mounts, port virtualization, confine(), and deferred commit.

Rust API

use sandlock_core::{confine, Confinement, Sandbox};
use sandlock_core::sandbox::ByteSize;

let mut sandbox = Sandbox::builder()
    .fs_read("/usr").fs_read("/lib")
    .fs_write("/tmp")
    .max_memory(ByteSize::mib(256))
    .name("hello-box")
    .build()?;
let result = sandbox.run(&["echo", "hello"]).await?;
assert!(result.success());

// HTTP ACL: restrict API access at the HTTP level
let mut agent = Sandbox::builder()
    .fs_read("/usr").fs_read("/lib").fs_read("/etc")
    .http_allow("POST api.openai.com/v1/chat/completions")
    .http_deny("* */admin/*")
    .name("agent-box")
    .build()?;
let result = agent.run(&["python3", "agent.py"]).await?;

// Confine the current process (Landlock filesystem only, irreversible)
let confinement = Confinement::builder()
    .fs_read("/usr").fs_read("/lib")
    .fs_write("/tmp")
    .build();
confine(&confinement)?;

Documentation

DocumentContents
docs/building.mdBuild commands, optional features, and minimal Rust embedding
docs/cli.mdEvery sandlock run option by example, profiles, ps / inspect / kill
docs/sandbox-reference.mdEvery Sandbox field, default, and TOML key; credentials; protection opt-out
docs/network.mdEndpoint grammar, protocol gating, HTTP interception, bind rules, port virtualization
docs/policy-fn.mdDynamic policy callbacks: events, verdicts, context methods, TOCTOU guarantees
docs/pipelines.mdPipelines, the XOA pattern, COW fork and map-reduce
docs/prompt_injection.mdPrompt injection defenses: isolation, permissions, credentials, and text inspection
docs/architecture.mdCrate layout, confinement sequence, supervisor handlers, COW filesystem
docs/learn.mdsandlock learn: generate a profile from an observed run
docs/extension-handlers.mdCustom seccomp-notification handlers (Rust and C ABI)
docs/python-handlers.mdCustom handlers from Python
python/README.mdPython SDK guide
go/README.mdGo SDK guide
crates/sandlock-oci/README.mdOCI runtime shim

Performance

Benchmarked on a typical Linux workstation:

WorkloadBare metalSandlockDockerSandlock overhead
/bin/echo startup2 ms7 ms307 ms5 ms (44x faster than Docker)
Redis SET (100K ops)82K rps80K rps52K rps97.1% of bare metal
Redis GET (100K ops)79K rps77K rps53K rps97.1% of bare metal
Redis p99 latency0.5 ms0.6 ms1.5 ms~2.5x lower than Docker
COW fork ×1000n/a530 msn/a530μs/fork, ~1,900 forks/sec

Testing

# Rust tests
cargo test --release

# Python tests
cd python && pip install -e . && pytest tests/
ai-agents
faas
landlock
linux
promptinjection
rust
sandboxing
seccomp

multikernel/sandlock

The lightest AI sandbox. A process-based sandbox for Linux, no container, no VM, no privilege, no prompt injection

Rust

573

1,295 commits

updated Oct 18, 2026

See the code

README

Sandlock

Lightweight process sandbox for Linux. Confines untrusted code using Landlock (filesystem + network + IPC), seccomp-bpf (syscall filtering), and seccomp user notification (resource limits, IP enforcement, /proc virtualization). No root, no cgroups, no containers.

sandlock run -w /tmp -r /usr -r /lib -m 512M -- python3 untrusted.py

Why Sandlock?

Containers and VMs are powerful but heavy. Sandlock targets the gap: strict confinement without image builds or root privileges. Built-in COW filesystem protects your working directory automatically.

FeatureSandlockContainerMicroVM (Firecracker)
Root requiredNoYes*Yes (KVM)
Image buildNoYesYes
Startup time~5 ms~200 ms~100 ms
KernelSharedSharedSeparate guest
Filesystem isolationLandlock + seccomp COWOverlayBlock-level
Network isolationLandlock + seccomp notifNetwork namespaceTAP device
HTTP-level ACLMethod + host + path rulesN/AN/A
Syscall filteringseccomp-bpfseccompN/A
Resource limitsseccomp notif + SIGSTOPcgroup v2VM config

* Rootless containers exist but require user namespace support and /etc/subuid configuration.

Architecture

Sandlock is implemented in Rust for performance and safety:

  • sandlock-core: Rust library (Landlock, seccomp, supervisor, COW, pipeline)
  • sandlock-cli: Rust CLI binary (sandlock run ...)
  • sandlock-oci: OCI runtime shim for containerd, CRI-O, and Kubernetes (namespace-less)
  • sandlock-ffi: C ABI shared library (libsandlock_ffi.so)
  • Python SDK: ctypes bindings to the FFI library
  • Go SDK: cgo bindings to the FFI library

See docs/architecture.md for how the pieces fit together and how confinement is applied.

Requirements

  • Linux 6.12+ (Landlock ABI v6), Rust 1.70+ (to build)
  • Python 3.8+ (optional, for Python SDK)
  • No root, no cgroups
FeatureMinimum kernel
seccomp user notification5.6
Landlock filesystem rules5.13
Landlock TCP port rules6.7 (ABI v4)
Landlock IPC scoping6.12 (ABI v6)

Protections can be selectively waived per-policy when needed; see docs/sandbox-reference.md#protection-opt-out.

Install

From source

# Build the Rust binary and shared library
cargo build --release

# Install Python SDK (auto-builds Rust FFI library)
cd python && pip install -e .

CLI only

cargo install --path crates/sandlock-cli

Optional features

All five features (http, checkpoint, image, profiles, cow) are enabled by default. Build with none or select the ones you need:

cargo build --release --no-default-features
cargo build --release --no-default-features --features http,profiles

See Building Sandlock for feature dependencies and Rust library configuration.

Quick Start

CLI

# Basic confinement
sandlock run -r /usr -r /lib -w /tmp -- ls /tmp

# Interactive shell (the sandboxed command inherits the terminal)
sandlock run -r /usr -r /lib -r /lib64 -r /bin -r /etc -w /tmp -- /bin/sh

# Resource limits + timeout
sandlock run -m 512M -P 20 -t 30 -- ./compute.sh

# Outbound allowlist: one host on one port
sandlock run --net-allow api.openai.com:443 -r /usr -r /lib -r /etc -- python3 agent.py

# HTTP-level ACL (method + host + path rules via transparent proxy)
sandlock run \
  --http-allow "GET docs.python.org/*" \
  --http-allow "POST api.openai.com/v1/chat/completions" \
  --http-deny "* */admin/*" \
  -r /usr -r /lib -r /etc -- python3 agent.py

# COW filesystem (writes captured, committed on success)
sandlock run --workdir /opt/project -r /usr -r /lib -- python3 task.py

# Dry-run (show what files would change, then discard)
sandlock run --dry-run --workdir . -w . -r /usr -r /lib -r /bin -r /etc -- make build

# Use a saved profile
sandlock run -p build -- make -j4

The full option tour (GPU, network grammar, HTTPS MITM, credential injection, port virtualization, chroot, nesting) is in docs/cli.md.

Python API

from sandlock import Sandbox, BranchAction

sandbox = Sandbox(
    fs_writable=["/tmp/sandbox"],
    fs_readable=["/usr", "/lib", "/etc"],
    max_memory="256M",
    max_processes=10,
    clean_env=True,
)

# Run a command (with optional timeout in seconds)
result = sandbox.run(["python3", "-c", "print('hello')"], timeout=30)
assert result.success
assert b"hello" in result.stdout

# Dry-run: see what files would change, then discard
sandbox = Sandbox(fs_writable=["."], workdir=".", fs_readable=["/usr", "/lib", "/bin", "/etc"],
                  on_exit=BranchAction.ABORT)
result = sandbox.run(["make", "build"])
for c in result.changes:
    print(f"{c.kind}  {c.path}")  # A=added, M=modified, D=deleted

See python/README.md for the SDK guide, including HTTP ACL, chroot mounts, port virtualization, confine(), and deferred commit.

Rust API

use sandlock_core::{confine, Confinement, Sandbox};
use sandlock_core::sandbox::ByteSize;

let mut sandbox = Sandbox::builder()
    .fs_read("/usr").fs_read("/lib")
    .fs_write("/tmp")
    .max_memory(ByteSize::mib(256))
    .name("hello-box")
    .build()?;
let result = sandbox.run(&["echo", "hello"]).await?;
assert!(result.success());

// HTTP ACL: restrict API access at the HTTP level
let mut agent = Sandbox::builder()
    .fs_read("/usr").fs_read("/lib").fs_read("/etc")
    .http_allow("POST api.openai.com/v1/chat/completions")
    .http_deny("* */admin/*")
    .name("agent-box")
    .build()?;
let result = agent.run(&["python3", "agent.py"]).await?;

// Confine the current process (Landlock filesystem only, irreversible)
let confinement = Confinement::builder()
    .fs_read("/usr").fs_read("/lib")
    .fs_write("/tmp")
    .build();
confine(&confinement)?;

Documentation

DocumentContents
docs/building.mdBuild commands, optional features, and minimal Rust embedding
docs/cli.mdEvery sandlock run option by example, profiles, ps / inspect / kill
docs/sandbox-reference.mdEvery Sandbox field, default, and TOML key; credentials; protection opt-out
docs/network.mdEndpoint grammar, protocol gating, HTTP interception, bind rules, port virtualization
docs/policy-fn.mdDynamic policy callbacks: events, verdicts, context methods, TOCTOU guarantees
docs/pipelines.mdPipelines, the XOA pattern, COW fork and map-reduce
docs/prompt_injection.mdPrompt injection defenses: isolation, permissions, credentials, and text inspection
docs/architecture.mdCrate layout, confinement sequence, supervisor handlers, COW filesystem
docs/learn.mdsandlock learn: generate a profile from an observed run
docs/extension-handlers.mdCustom seccomp-notification handlers (Rust and C ABI)
docs/python-handlers.mdCustom handlers from Python
python/README.mdPython SDK guide
go/README.mdGo SDK guide
crates/sandlock-oci/README.mdOCI runtime shim

Performance

Benchmarked on a typical Linux workstation:

WorkloadBare metalSandlockDockerSandlock overhead
/bin/echo startup2 ms7 ms307 ms5 ms (44x faster than Docker)
Redis SET (100K ops)82K rps80K rps52K rps97.1% of bare metal
Redis GET (100K ops)79K rps77K rps53K rps97.1% of bare metal
Redis p99 latency0.5 ms0.6 ms1.5 ms~2.5x lower than Docker
COW fork ×1000n/a530 msn/a530μs/fork, ~1,900 forks/sec

Testing

# Rust tests
cargo test --release

# Python tests
cd python && pip install -e . && pytest tests/
ai-agents
faas
landlock
linux
promptinjection
rust
sandboxing
seccomp

Project health

Latest release

0.9.0 · Oct 13, 2026

Releases this year

25

Significant stargazers

(top 24 of 36)

Domen Kožar

1,095 followers · starred Sep 2026

Duncan Ogilvie

3,981 followers · starred Sep 2026

Pekka Enberg

2,031 followers · starred Jun 2026

PatrickJS

3,596 followers · starred Jul 2026