Sandbox
sandbox runs any application in a disposable FreeBSD jail backed by a ZFS clone. When you close the app, the jail and its clone are destroyed. Nothing persists to the host filesystem.
sandbox <application>Examples:
sandbox firefoxsandbox telegram-desktopsandbox mpv ~/Downloads/video.mp4sandbox sh # disposable shellThe application runs with a fresh clone of the base environment. File writes inside the jail disappear when the process exits.
What Happens Under the Hood
Section titled “What Happens Under the Hood”| Step | Operation |
|---|---|
| 1 | ZFS clone of zroot/sandbox/base → zroot/sandbox/run-XXXX |
| 2 | FreeBSD jail created, root mounted from the clone |
| 3 | Host Wayland socket ($WAYLAND_DISPLAY) bind-mounted into the jail |
| 4 | Application launched inside the jail with Wayland display set |
| 5 | On exit: jail stopped, ZFS clone destroyed |
The Wayland socket mount gives the jailed application access to your display without exposing the full host filesystem.
ZFS clones are copy-on-write. Creating a sandbox clone costs almost nothing in time or space — only diverging blocks are written.
Technical Details
Section titled “Technical Details”ZFS Clone
Section titled “ZFS Clone”# sandbox creates something like:CLONE="zroot/sandbox/run-$(uuidgen | cut -c1-8)"zfs clone zroot/sandbox/base@snap "$CLONE"# ... run jail ...zfs destroy -r "$CLONE"Jail Configuration
Section titled “Jail Configuration”# Generated jail.conf fragmentsandbox-XXXX { path = /sandbox/run-XXXX; host.hostname = sandbox-XXXX; allow.sysvipc = 0; allow.raw_sockets = 0; enforce_statfs = 2; persist = 0;
mount.fdescfs; mount.procfs;
exec.start = "/bin/sh /etc/rc"; exec.stop = "/bin/sh /etc/rc.shutdown";}Wayland Access
Section titled “Wayland Access”The host Wayland socket is mounted read-write into the jail. The WAYLAND_DISPLAY and XDG_RUNTIME_DIR environment variables are set so the application connects to the host compositor.
# Mount the Wayland socketmount -t nullfs /run/user/$(id -u)/wayland-1 \ /sandbox/run-XXXX/run/user/1000/wayland-1Use Cases
Section titled “Use Cases”| Scenario | Command |
|---|---|
| Open a downloaded PDF without trusting it | sandbox evince ~/Downloads/untrusted.pdf |
| Test an app install without polluting host | sandbox sh then install inside |
| Run a one-off CLI tool | sandbox some-tool —args |
| Browse with a clean profile | sandbox firefox |
| Run legacy or untrusted software | sandbox old-app |
Persistent Sandboxes
Section titled “Persistent Sandboxes”If you need a sandbox that persists across sessions, use a named jail instead:
# Create a persistent named sandboxsandbox-create myapp
# Run in the persistent sandboxsandbox-exec myapp firefox
# List persistent sandboxessandbox-list
# Destroy when donesandbox-destroy myappThe Wayland socket mount gives the sandboxed app access to your display. A malicious application can still capture screen contents or inject keystrokes via Wayland protocols. Sandboxing here is about filesystem isolation, not full security containment.
Base Environment Setup
Section titled “Base Environment Setup”The sandbox base environment is at zroot/sandbox/base. It contains a minimal FreeBSD userland plus the packages needed to run GUI applications:
# Rebuild the base environmentsandbox-init
# Add packages to the basesandbox-base-install pkg-nameSee sandbox --help for the full option list.