On a fresh Linux desktop install, any application you launch runs as your user. That sounds obvious until you think about it: your browser, a random video player, a downloaded build tool, and your SSH client all share the same filesystem permissions. There is nothing — at the operating system level — preventing a malicious or compromised application from reading ~/.ssh/id_ed25519 and exfiltrating it.
This is a model inherited from Unix's multi-user origins, where the relevant security boundary was between human users, not between a single user's applications. On modern desktops it's increasingly wrong. The kernel actually has the primitives to fix it — namespaces, seccomp filters, cgroups, capabilities — but they're not used by default. The three tools below are different opinionated wrappers around those primitives.
Bubblewrap: The Low-Level Primitive
Bubblewrap (bwrap) is a small setuid-free wrapper around Linux namespace and seccomp APIs, originally written by Alexander Larsson at Red Hat to be the sandboxing backend for Flatpak. It's deliberately minimal: it doesn't ship policies, it doesn't manage profiles, it doesn't know what application you're running. You give it a long list of flags describing what filesystem paths to bind, what to make read-only, what namespaces to unshare, and what to deny — and it constructs a sandbox accordingly.
A typical bubblewrap invocation looks something like:
--ro-bind /usr /usr— make the system read-only available--bind ~/Downloads ~/Downloads— give writeable access to one directory--unshare-net— no network access--die-with-parent— kill the sandboxed process if bubblewrap itself dies
The advantage of this low-level interface is that it does exactly what you tell it to. The disadvantage is that you have to tell it everything. Running a real GUI application through bubblewrap requires roughly a hundred lines of flags to handle X11/Wayland sockets, DBus, PulseAudio, fonts, themes, and so on. Most people don't write those by hand.
In practice, bubblewrap is the engine that other tools drive. Flatpak uses it directly. The steam-runtime uses it. Distrobox and toolbox use it. Treat it as the foundation primitive, not the user-facing tool.
Flatpak: Packaging + Sandbox + Distribution
Flatpak is the most ambitious of the three. It's not just a sandbox — it's a complete application packaging, distribution, and runtime system, with sandboxing as one component. Flatpak applications are built against a "runtime" (a versioned base of libraries — GNOME, KDE, Freedesktop), distributed through Flathub or other repositories, and executed inside a bubblewrap sandbox configured by the application's manifest.
The sandbox is permission-based. An application declares what it needs — filesystem access, network, DBus interfaces, audio, hardware devices — in its manifest, and the user can review and override those permissions at install or runtime via Flatseal or flatpak override.
Many Flatpak applications request filesystem=home or filesystem=host in their manifest — which substantially defeats the sandbox. The sandbox is only as strong as the permissions actually granted. Flatseal is the practical tool for auditing and tightening these on a per-app basis.
Flatpak's portal system is the genuinely innovative piece. Instead of granting blanket access, an app can request a specific file via the document portal (showing the user a file picker, then making just that file available inside the sandbox), capture a screenshot via the screenshot portal (with user confirmation), or send a notification via the notification portal. This is closer to the iOS/Android permission model than anything else on Linux.
Flatpak is the default packaging format on Fedora Silverblue, on Steam Deck's desktop mode, and increasingly on consumer-focused Linux distributions. It's also opinionated about how it does things — if you want a sandbox without the packaging system, this is the wrong tool.
Firejail: Sandboxes for Native Packages
Firejail takes the opposite approach. Where Flatpak says "package the app and the sandbox together," Firejail says "let me sandbox the apps you've already installed from your distro's package manager." It ships a large library of preconfigured profiles for common applications — Firefox, Chrome, LibreOffice, VLC, Telegram Desktop, hundreds more — that you can apply via firejail firefox or by symlinking /usr/local/bin/firefox to firejail.
The convenience is real. You install software the normal way, and Firejail wraps it with sensible restrictions: no access to ~/.ssh, no access to other applications' configs, restricted network, seccomp filters limiting dangerous syscalls. For users who don't want to rebuild their software stack around Flatpak, this is the closest thing to "drop-in" sandboxing.
The trade-off is the setuid root binary. Firejail historically used setuid root to enter privileged kernel namespaces — and that root binary has had several security vulnerabilities of its own, some quite serious. Recent versions support unprivileged operation on kernels that allow user namespaces, but on many distributions the setuid mode remains the default.
This is a genuine threat-model question. If your goal is to limit damage from a compromised application, Firejail mostly delivers. If your goal includes "no privilege escalation paths in security tooling itself," the setuid root mode is a concern.
How They Stack Up
| Tool | Best for | Watch out for |
|---|---|---|
| Bubblewrap | Programmers building sandboxed runtimes; scripted isolation of specific commands | You have to design the policy yourself |
| Flatpak | End users on Silverblue, Steam Deck, or who want the iOS-style permission model | App-declared permissions often too broad; audit with Flatseal |
| Firejail | Sandboxing apps installed from distro repositories without changing how you install software | Setuid root surface; rely on unprivileged mode when possible |
What None of These Solve
All three tools share the same fundamental limit: they're isolating processes within a single Linux user account, against threats that lack kernel exploits. They are not VM-grade isolation. A kernel local-privilege-escalation vulnerability bypasses all of them — and the kernel has a steady stream of those.
For threats that warrant stronger isolation, the next step up is virtualization-based — Tails for amnesic isolation, Qubes OS for compartmentalized VMs, or even just running risky software in a dedicated VM. The sandboxing tools above are a meaningful improvement on the default "everything runs as you" model, but they are not a substitute for a strong virtualization boundary when the threat model demands it.
Practical Recommendations
A few concrete suggestions for users sorting through this for the first time:
- If you use Flatpak applications, install Flatseal and review the permissions of anything you actually trust with sensitive data. Pay particular attention to filesystem access and "talk to any name on the session bus" — both are common over-grants.
- If you install software from your distro's package manager and want lightweight isolation, Firejail is the lowest-friction path. Symlink the binaries you care about; review the profile shipped for each app.
- If you're writing scripts or build tooling that needs to run untrusted code, bubblewrap directly is probably the right tool. Don't reinvent the wheel.
- If your threat model includes targeted attacks, consider Qubes OS or compartmentalized VMs instead. Sandboxing within one Linux user is the wrong layer for that fight.
The shift toward sandboxed-by-default Linux applications is real but incomplete. Each of these tools represents a different philosophy about how to get there, and none of them is the obvious right answer for everyone. Understanding what they actually isolate — and what they don't — is the first step toward using whichever one fits your situation.