How Sandlock Works
Sandlock is a lightweight process sandbox for Linux that enforces confinement without requiring root privileges, containers, or virtual machines. It achieves this through a combination of kernel-level mechanisms: Landlock for filesystem, network, and inter-process communication (IPC) restrictions; seccomp-bpf for syscall filtering; and seccomp user notifications for resource limits and IP enforcement. Unlike traditional sandboxing methods, Sandlock operates at the process level, sharing the host kernel while isolating untrusted code in a confined environment.
The core of Sandlock’s design is its policy-driven approach. Policies define what resources a process can access, such as read-only or writable directories, allowed network endpoints, and system call restrictions. These policies are enforced by the Linux kernel, ensuring that even if an attacker exploits a vulnerability, they remain constrained by the predefined rules. Sandlock applies these policies before the confined process executes any code, leveraging kernel-enforced access control to prevent unauthorized operations.
A key innovation in Sandlock is its Copy-on-Write (COW) filesystem. This mechanism automatically protects the working directory by capturing writes and committing changes only upon successful execution. If the process fails or is terminated, the changes are discarded, leaving the host system untouched.
Sandlock’s architecture is modular, consisting of several components implemented in Rust for performance and safety.
- sandlock-core: A Rust library that handles Landlock integration, seccomp filtering, supervision, COW filesystem management, and pipeline execution.
- sandlock-cli: A command-line interface for running confined processes with customizable policies.
- sandlock-oci: An OCI runtime shim that allows Sandlock to integrate with container orchestration systems like containerd, CRI-O, and Kubernetes without requiring namespaces.
These components work together to provide a cohesive sandboxing solution that can be deployed across different environments and use cases.
Sandlock’s confinement is applied in a sequence that ensures security before execution. The supervisor component intercepts critical syscalls, such as those related to network access, memory usage, and filesystem operations. This allows for dynamic policy enforcement, where custom handlers can be invoked to decide whether to allow or deny specific operations.
This flexibility is particularly valuable in environments where certain operations must be permitted despite the default deny policy.
Use Cases
Sandlock is designed to address the limitations of traditional sandboxing methods, such as containers and virtual machines, which are often overkill for running untrusted code. Its lightweight nature makes it ideal for scenarios where performance and resource efficiency are critical.
- Agent and Tool Security: Sandlock can confine AI agents, automation tools, or scripts that interact with sensitive systems or APIs. By restricting access to specific resources, it mitigates the risk of accidental or malicious data leaks. For example, an AI agent querying an API like OpenAI’s can be confined to allow only specific HTTP endpoints, such as POST api.openai.com/v1/chat/completions, while blocking all other network traffic.
- The COW filesystem ensures that any changes made during the build process are discarded unless explicitly committed, maintaining a clean state between runs.
- Interactive Development: Developers can safely test untrusted code or third-party scripts without risking system contamination. The interactive shell feature allows users to run confined commands in a terminal, providing a familiar environment while maintaining isolation.
- Resource-Constrained Environments: Sandlock’s minimal overhead makes it suitable for edge devices or systems with limited resources. Unlike containers or VMs, it does not require additional layers like images or hypervisors, reducing startup time and memory usage.
- Dynamic Policy Enforcement: Organizations can deploy Sandlock to enforce granular policies for internal tools or services. For instance, a policy can restrict a confined process to specific directories, network endpoints, and system calls, ensuring compliance with security guidelines while allowing legitimate operations.
Sandlock’s integration with OCI runtimes also enables its use in Kubernetes or other container orchestration platforms. This allows teams to adopt Sandlock as a drop-in replacement for traditional container runtimes, benefiting from its lightweight performance while maintaining compatibility with existing workflows.
Key Features and Capabilities
- Kernel-Enforced Confinement: Policies are enforced by the Linux kernel, ensuring that even if a confined process is compromised, it cannot bypass the restrictions. This includes filesystem access, network communications, and system call execution.
- No Root or Privilege Escalation: Sandlock operates without requiring root privileges or user namespaces, making it accessible to standard users while maintaining strong isolation guarantees.
- Copy-on-Write (COW) Filesystem: Writes to the working directory are staged and only committed upon successful execution. This feature prevents accidental or malicious modifications to the host system and supports dry-run modes to preview changes before applying them.
- HTTP-Level Access Control: Sandlock can enforce fine-grained HTTP ACLs, allowing or denying specific methods, hosts, and paths.
- Resource Limits Without cgroups: Sandlock imposes memory, process, open file, CPU, and GPU limits using seccomp notifications and signals, eliminating the need for cgroups or root privileges. This simplifies deployment in environments where cgroups are unavailable or undesirable.
- Network Isolation: Network access is restricted to explicitly allowed hosts, ports, and protocols (TCP, UDP, ICMP). This includes support for IP, CIDR ranges, and domain names.
- Syscall Filtering with seccomp-bpf: Sandlock uses seccomp to block unauthorized system calls, such as those related to privilege escalation or sensitive operations. Custom handlers can further refine this filtering by intercepting specific syscalls and deciding whether to allow, deny, or fabricate responses.
- Dynamic Policy Callbacks: Administrators can define custom handlers to enforce additional rules or audit events. These handlers run within the supervisor and can inspect syscall arguments, modify responses, or log activities, providing a layer of dynamic control beyond static policies.
- Performance Optimizations: Sandlock is designed for low overhead. Benchmarks on a typical Linux workstation show that confined processes achieve 97.1% of bare-metal throughput for operations like Redis SET and GET. Startup time is approximately 5 milliseconds, compared to 200–300 milliseconds for containers, making it suitable for high-frequency or latency-sensitive workloads.
- The Rust implementation ensures portability and performance across different environments.
- Integration with Existing Tools: Sandlock provides OCI-compatible runtimes, allowing it to replace traditional container runtimes in Kubernetes or other orchestration platforms. It also offers SDKs for Python and Go, enabling seamless integration with existing applications.
- Audit and Transparency: Sandlock’s design ensures that all confined operations are subject to kernel-enforced policies, making it difficult for attackers to evade monitoring. The supervisor logs critical events, and dry-run modes allow administrators to preview changes before execution.
Sandlock’s feature set is continually evolving, with recent releases introducing improvements such as better COW filesystem handling, enhanced network policy enforcement, and support for custom syscall interception. These updates reflect its focus on addressing real-world security challenges while maintaining compatibility and performance.
Technical Requirements and Implementation
To deploy Sandlock, users must meet specific system requirements, primarily centered around the Linux kernel version and supporting libraries. The minimum requirements include:
- Linux Kernel 6.12+: Sandlock relies on Landlock ABI version 6 for IPC scoping and other features.
- Rust 1.70+: Required for building the core components and SDKs.
- Python 3.8+ (Optional): Needed for the Python SDK and bindings.
Sandlock does not require cgroups or root privileges, making it accessible on standard Linux distributions. The absence of these dependencies simplifies deployment in environments where containers or VMs are impractical.
The installation process involves building the Rust components and optionally installing the Python SDK. The CLI tool, sandlock run, provides a straightforward interface for confining processes with custom policies, while the SDKs enable programmatic integration in Python, Go, or Rust.
The project also includes extensive documentation for CLI options, policy configuration, and advanced features like HTTP ACLs and custom handlers.
Redis operations under Sandlock maintain 97.1% of bare-metal throughput, demonstrating its suitability for high-performance workloads. The COW filesystem achieves a fork rate of 1,900 operations per second, further emphasizing its low overhead.
Recent releases have focused on refining core functionality, such as improving COW filesystem handling, fixing network policy issues, and enhancing support for architectures like RISC-V.
