LGPL-2.1-or-later🖥️ Self-hostable

Bubblewrap

Bubblewrap

Overview

Bubblewrap (bwrap) is the low-level sandboxing tool that lets an unprivileged user run a program inside a locked-down view of the filesystem. It creates a brand-new mount namespace whose root is an empty tmpfs invisible from the host, and then hands you a small set of options — --bind, --ro-bind, --tmpfs, --dir, --symlink, --proc, --dev — with which you assemble exactly the parts of the system the sandboxed process is allowed to see. Anything you do not bind simply does not exist inside: no /home, no /etc/shadow, no host PIDs, no network unless you keep it.

It is deliberately not a complete sandbox with a fixed policy. Bubblewrap is the mechanism; whatever constructs the command line — Flatpak, rpm-ostree unprivileged, libgnome-desktop, sandwine or your own shell script — is the thing that defines the security model. That split is why the code is small and auditable: a single C program of a few thousand lines, built with meson, developed by Alexander Larsson and now maintained by Simon McVittie and contributors in the containers/bubblewrap repository at github.com/containers/bubblewrap (C, LGPL, actively maintained — 0.13.1 landed on 14 October 2026). It is the sandbox engine underneath millions of Flatpak installs, and it is packaged in every major distribution as bubblewrap.

Key Features

  • Unprivileged by design — it relies on Linux user namespaces rather than setuid, so any ordinary user can create a sandbox with no help from the administrator. The historical setuid fallback for kernels without unprivileged user namespaces has been removed; upstream now requires working user namespaces.
  • Construct-your-own root filesystem — --ro-bind /usr /usr shares a read-only copy of the host tree, --bind shares it writably, --tmpfs /tmp gives a private temporary directory, --dir and --symlink synthesise the layout a dynamically linked binary expects. Injections are mounted nodev by default.
  • Namespace isolation you can dial in — the mount namespace is always created; PID, IPC, UTS, cgroup, network and user namespaces are opt-in, or all at once with --unshare-all (plus --share-net when the sandbox still needs the network). A sandboxed --unshare-all run sees only lo and a handful of processes, not the host’s 250+.
  • No privilege escalation inside — bubblewrap sets PR_SET_NO_NEW_PRIVS, which disables setuid binaries (the traditional escape from a chroot) and makes seccomp filters usable by an unprivileged process.
  • A real PID 1 — with --unshare-pid bubblewrap runs a trivial init inside the sandbox to reap orphaned children, sidestepping the classic “PID 1 zombie reaping” problem; --as-pid-1 hands that role to your own command.
  • Seccomp and session hardening — --seccomp FD loads a BPF filter to restrict which syscalls the sandbox may make, while --new-session protects against terminal-injection (TIOCSTI, CVE-2017-5226) and --die-with-parent guarantees the sandbox dies with its parent.
  • Honest about its limits — the README states plainly that protection depends entirely on the arguments passed and documents the sharp edges: bound D-Bus sockets can be abused without xdg-dbus-proxy filtering, and seccomp restrictions can conflict with browsers that apply their own filters.

Why Use It

The usual alternatives require trust in a setuid root binary, and that is a large amount of privilege to hand to a sandbox front-end. Bubblewrap takes the opposite approach: a small program, no setuid, kernel user namespaces doing the isolation, and privilege escalation inside the sandbox switched off with NO_NEW_PRIVS. The result is a component that is tractable to audit and easy to reason about. It is also composable rather than opinionated — because the caller chooses the mounts, the same binary serves wildly different jobs, from “strong security boundary around an untrusted app” to “run this build with a different filesystem layout”, without either case inheriting policy it did not ask for. And the ecosystem argument is the strongest one at scale: Flatpak, rpm-ostree and desktop portals already build on it, so sandbox behaviour is consistent and battle-tested rather than bespoke.

Use Cases

  • Wrapping untrusted software — run a downloaded binary or a friend’s build with a read-only system and no access to your home directory.
  • Flatpak and desktop app sandboxing — bubblewrap is the mechanism Flatpak uses to implement each application’s declared filesystem and device permissions.
  • Build and test isolation — compile against pinned toolchains with a private /tmp, no network and a filesystem that cannot be scribbled on outside a chosen work directory.
  • Running old or exotic toolchains — bind a chroot-style rootfs or a container image’s filesystem and execute inside it as an ordinary user, with no daemon and no root.
  • Hardening scripting and automation — a live-upgrade or CI script can wrap a risky step in bwrap --unshare-all --die-with-parent so a failure cannot reach outside the sandbox.
  • Security research and testing — reproduce what a process can and cannot see under a given policy before shipping it as a real application manifest.

Platforms

Linux only — it depends on mount, PID, IPC, UTS, network and user namespaces plus seccomp, all kernel features. A modern kernel with unprivileged user namespaces enabled is required (the setuid fallback is gone). It has no daemon, no GUI and no runtime dependencies beyond libc and libcap; it builds from source with meson (meson setup _builddir && meson compile -C _builddir) and is packaged for Debian and Ubuntu (bubblewrap, 0.12.0 in Debian 13), Fedora/RHEL, Arch, Alpine and openSUSE. On distributions that restrict unprivileged user namespaces through AppArmor or a sysctl, the sandbox will need that restriction relaxed — which is exactly why Flatpak’s own 0.12+ builds may request the bwrap capability profile.

Licence and Website

Free and open source. Bubblewrap is released under the GNU Lesser General Public License, version 2.1 or later — the repository’s COPYING file carries the LGPL 2.1 text and the source files declare SPDX-License-Identifier: LGPL-2.0-or-later; Debian’s packaging records the licence as LGPL-2.1+. Source, releases and the issue tracker are at github.com/containers/bubblewrap; the Linux man page (man bwrap) ships with the package and documents every option.

Alternatives

Explore More Categories

Sign In

Register

Reset Password

Please enter your username or email address, you will receive a link to create a new password via email.