py-landlock
Python bindings for the Linux Landlock security module.
Landlock is a Linux kernel feature that enables unprivileged processes to restrict their own access to the filesystem, network, and IPC resources. This library provides both a high-level API for common use cases and low-level access to the underlying syscalls.
Requirements
- Python 3.10 or later
- Linux kernel 5.13 or later with Landlock enabled
- Supported architectures: x86_64, aarch64
Installation
pip install py-landlock
Or with uv:
uv add py-landlock
Examples
Quick Start
from py_landlock import Landlock
Landlock() \
.allow_read("/usr", "/etc") \
.allow_execute("/usr/bin") \
.apply()
# Any attempt to write or access other paths now raises PermissionError
Check Availability
from py_landlock import get_abi_version, LandlockNotAvailableError
try:
version = get_abi_version()
print(f"Landlock ABI v{version}")
except LandlockNotAvailableError as e:
print(f"Not available: {e}")
Sandbox with Network Restrictions
from py_landlock import Landlock
Landlock() \
.allow_read("/usr", "/etc") \
.allow_read_write("/tmp/myapp") \
.allow_network(443, bind=False, connect=True) \
.apply()
For more examples, see the examples/ directory.
Usage
High-Level API
The Landlock class provides a fluent builder interface for constructing and applying security policies.
Filesystem Access Control
| Method | Description |
|---|---|
allow_read(*paths) |
Allow reading files and listing directories |
allow_write(*paths) |
Allow writing, creating, and removing files |
allow_execute(*paths) |
Allow executing files |
allow_read_write(*paths) |
Combination of read and write access |
add_path_rule(*paths, access) |
Add a rule with specific AccessFs flags |
Network Access Control
Network restrictions require kernel ABI version 4 or later.
| Method | Description |
|---|---|
allow_network(*ports, bind, connect) |
Allow TCP bind and/or connect on specified ports |
allow_all_network() |
Disable network restrictions entirely |
Scope Restrictions
Scope restrictions limit IPC and signal delivery to processes within the same Landlock domain. Requires kernel ABI version 6 or later.
| Method | Description |
|---|---|
allow_scope(scope) |
Exempt specific scope restrictions |
allow_all_scope() |
Disable all scope restrictions |
Strict vs Best-Effort Mode
By default, the library operates in strict mode and raises CompatibilityError if a requested feature is not supported by the running kernel. Use Landlock(strict=False) for best-effort mode which silently ignores unsupported features.
ABI Compatibility
Landlock uses ABI versioning to maintain backward compatibility as new features are added. The kernel's ABI version determines which access rights are available:
| ABI Version | Kernel Version | Features Added |
|---|---|---|
| 1 | 5.13 | Basic filesystem access control |
| 2 | 5.19 | File referring (REFER) |
| 3 | 6.2 | File truncation (TRUNCATE) |
| 4 | 6.7 | TCP network restrictions |
| 5 | 6.10 | Device IOCTL (IOCTL_DEV) |
| 6 | 6.12 | Scope restrictions (abstract UNIX, signals) |
| 7 | 6.14 | Audit logging control |
Low-Level API
For advanced use cases, the library exposes the underlying syscall wrappers:
from py_landlock import (
create_ruleset,
add_rule,
restrict_self,
RulesetAttr,
PathBeneathAttr,
AccessFs,
)
attr = RulesetAttr()
attr.handled_access_fs = AccessFs.READ_FILE | AccessFs.WRITE_FILE
ruleset_fd = create_ruleset(attr)
path_attr = PathBeneathAttr.from_path("/tmp", AccessFs.READ_FILE | AccessFs.WRITE_FILE)
add_rule(ruleset_fd, path_attr)
restrict_self(ruleset_fd)
Error Handling
| Exception | Description |
|---|---|
LandlockError |
Base exception for all Landlock errors |
LandlockNotAvailableError |
Landlock not available (wrong platform, architecture, or kernel) |
LandlockDisabledError |
Landlock supported but disabled at boot |
RulesetError |
Failed to create, configure, or apply a ruleset |
PathError |
Specified path does not exist |
CompatibilityError |
Requested feature requires a higher ABI version |
NetworkDisabledError |
TCP/IP not available in kernel |
Threading
Landlock rules apply to the calling thread and are inherited by all threads and processes it creates afterward. Key behaviors:
- Rules cannot be removed once applied
- Each thread can add additional restrictions to itself
- Child threads and processes inherit all restrictions from their parent
- A thread cannot relax restrictions inherited from its parent
Limitations
Landlock has several limitations documented in the kernel documentation:
-
Filesystem topology: Sandboxed threads cannot modify filesystem topology via
mount(2)orpivot_root(2). However,chroot(2)is permitted. -
Special filesystems: Files from non-user-visible filesystems (such as pipes and sockets) accessible through
/proc/<pid>/fd/*cannot be explicitly restricted. Special kernel filesystems like nsfs also cannot be directly restricted. -
Ruleset stacking limit: A maximum of 16 stacked rulesets can be applied. Once this limit is reached,
restrict_self()returnsE2BIG. This can be problematic for programs that launch other sandboxed programs. -
IOCTL restrictions: The
IOCTL_DEVaccess right only applies to device files opened after the ruleset is applied. Pre-existing file descriptors (stdin, stdout, stderr) are unaffected. -
Network restrictions: Only TCP bind and connect operations can be restricted. UDP, ICMP, and other protocols are not covered.
Resources
- Landlock website
- Linux kernel documentation
- rust-landlock - Rust bindings
- go-landlock - Go bindings
License
Metadata
Release files for py-landlock 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| py_landlock-0.1.1.tar.gz | 16.2 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| py_landlock-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 32.8 kB
Release files / py_landlock-0.1.1.tar.gz
| Download URL | py_landlock-0.1.1.tar.gz |
|---|---|
| Size | 16.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
917e83917ea8932c1f106b62e82874542094738143600b77dbccd88deabc5656
|
|
BLAKE2b-256 checksum How to use checksums |
83aa6dc19aa2393cf4d2288fe3647ade6308d66c2deb233e40e592ddce7c6330
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.9.24 {"installer":{"name":"uv","version":"0.9.24","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / py_landlock-0.1.1-py3-none-any.whl
| Download URL | py_landlock-0.1.1-py3-none-any.whl |
|---|---|
| Size | 16.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a4dd8dad2032edeb6974031d10be8758acf6c9747ab18616921a03779d97e404
|
|
BLAKE2b-256 checksum How to use checksums |
25f553515e4b743ee4d07e37aedfb4bc30c2185b48bd96df44a9fbbef3f3c610
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.9.24 {"installer":{"name":"uv","version":"0.9.24","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for py-landlock 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.