ferroday-cage
A pure-Rust library for running a command inside an unprivileged Linux sandbox: its own root filesystem view, its own namespaces, and a clean environment, all established by talking to the kernel directly.
Configure a sandbox with a typed builder, launch a command, and consume its streamed
output and a typed result. The command runs under a minimal init in its own PID
namespace, and a running sandbox is driven through a handle that can wait, set a
deadline, terminate, or kill. A companion command-line tool, fcage, offers the same
sandbox at a shell prompt.
The library issues the sandbox's syscalls itself, so a default build is
self-contained: pure Rust throughout, resting on the kernel alone. unsafe is
confined to the small kernel-facing core — namespaces, id maps, mounts, pivot_root,
exec — and everything above it, and every consumer, is safe Rust.
The sandbox rests on the same kernel primitives as bubblewrap — user and mount
namespaces, pivot_root, seccomp — and presents them as a library with a typed builder
and an in-process handle rather than a command to shell out to. fcage covers the
command-line case.
It is not a container runtime: there are no images, no registry, and no OCI runtime specification. A root filesystem is a directory you supply or provision, and every sandbox is rootless — built with the caller's own credentials, with no daemon involved.
Features
A bare dependency gives the sandbox itself: namespaces, mounts, the root swap, identity maps, the process model, output streaming, and resource limits. Each capability below is opt-in, and every dependency it brings is pure Rust with C backends off, so any combination keeps the build self-contained.
| Feature | What it adds |
|---|---|
hardening |
Landlock filesystem and network rules, seccomp syscall filters, and capability drops applied to the command — plus a restriction fallback for hosts that disable user namespaces, confining a plain process with the same primitives |
tarball |
Provision a rootfs atomically from a tar archive (uncompressed, gzip, xz, or zstd, detected by content) with kernel-enforced containment, and export one back with its ownership and extended attributes intact |
debian |
Bootstrap a Debian suite and architecture straight from the archive — a debootstrap replacement that verifies the release signature, resolves the dependency closure itself, and configures the root in a cage |
netstack |
A native userspace TCP/IP stack giving the isolated network outbound IPv4 and IPv6, terminated in-process and forwarded over ordinary host sockets |
serde |
The sandbox specification round-trips through profile files, including a restricted mode for profiles from an untrusted source |
subid |
uid/gid range maps through the shadow suite's newuidmap/newgidmap, so a userland needing more than one identity works inside |
Usage
use Cage;
Or at a shell prompt, through fcage:
Requires Rust 1.91 or later, and Linux 5.6 or later with unprivileged user namespaces enabled. A host that denies them is reported by name, with the blocking configuration and its remedy. See the guide for details.
Contributing and security
See CONTRIBUTING.md for how to build, test, and propose changes, and SECURITY.md for how to report a containment bypass or another security issue. Released changes are recorded in CHANGELOG.md.
Workspace
crates/ferroday-cage— the library.crates/ferroday-cage-cli— thefcagebinary, a thin consumer of the library's public API.docs/— the guide, an mdBook.
Status
The library is feature-complete for this release, and its public surface is
guarded by a committed API snapshot, cargo-semver-checks, and auto-trait
assertions. The API settles over the 0.x series: while the major version is 0,
a breaking change bumps the minor version. The stability
chapter states
what each interface promises.
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.