Bubblewrap’s official description contains a short sentence that packs several important Linux security ideas into just a few words:
Low-level unprivileged sandboxing tool used by Flatpak and similar projects.
In plain language:
A low-level tool for building sandboxes without requiring general administrator privileges, used by Flatpak and similar projects.
To understand that sentence properly, we need to separate four ideas: low-level, unprivileged, sandboxing, and the relationship with Flatpak.
First: what is a sandbox?
A sandbox is a restricted environment in which a process runs with limits on what it can see or do.
For example, an application might run with access shaped like this:
/usr -> read-only
/tmp -> isolated
/home -> hidden
network -> disabled
processes -> only processes inside the sandbox
The application still runs on the same Linux kernel, but its view of the system is much smaller.
That is an important distinction from a full virtual machine. A VM normally runs another operating system with its own kernel. A namespace-based sandbox reuses the host kernel and builds boundaries around a process.
What does “low-level” mean?
Bubblewrap is not trying to be a complete platform like Docker, Kubernetes, or Flatpak.
It works much closer to the primitives provided by the Linux kernel.
Those primitives include:
- mount namespaces;
- user namespaces;
- PID namespaces;
- network namespaces;
- IPC namespaces;
- UTS namespaces;
- bind mounts;
- seccomp filters.
Bubblewrap combines those pieces to construct the environment in which a process will run.
A useful mental model looks like this:
Application
│
▼
Bubblewrap
│
├── filesystem namespace
├── process namespace
├── network namespace
├── allowed mounts
└── additional restrictions
│
▼
Linux kernel
That is why it is called a low-level tool: it provides mechanisms, not a full application-distribution experience.
What does “unprivileged” mean?
This is one of the most interesting parts.
Historically, many operations related to containers, mounts, and namespaces required elevated privileges. Giving ordinary users unrestricted access to powerful system-administration tools would be dangerous because it could become a path to a root shell on the host.
Linux introduced user namespaces, which allow a normal user to create a space where they can have a privileged-looking identity inside that namespace without becoming real root outside it.
Bubblewrap takes advantage of that capability.
Conceptually:
HOST
normal user: UID 1000
│
▼
user namespace
│
└── may appear as root inside the namespace
but does NOT become root on the host
That is the idea behind unprivileged sandboxing: the user launching Bubblewrap does not need to receive broad administrative control over the machine in order to construct the sandbox.
Bubblewrap also uses mechanisms such as PR_SET_NO_NEW_PRIVS so the sandboxed process cannot later gain privileges through setuid executables.
How Bubblewrap constructs the filesystem
One of Bubblewrap’s most interesting design choices is that it begins by creating a new, empty mount namespace.
Its initial root is backed by a tmpfs that is invisible from the host.
From there, the caller explicitly adds the parts of the host that the sandboxed process should be allowed to see.
A simplified example inspired by the project’s documentation looks like this:
bwrap \
--ro-bind /usr /usr \
--proc /proc \
--dev /dev \
--unshare-pid \
--new-session \
bash
The idea is not to copy all of /usr. --ro-bind makes that part of the host filesystem visible inside the sandbox in read-only mode.
We can picture it like this:
HOST SANDBOX
/usr --------------------> /usr [read-only]
/home/user [not visible]
/tmp different /tmp
host processes [hidden]
The important point is that the sandbox is assembled in a style similar to deny by default: expose what is needed rather than automatically exposing the entire host.
So, is Bubblewrap like Docker?
Not exactly.
Docker provides many layers around isolation:
Docker
├── images
├── layers
├── registries
├── networking
├── volumes
├── container lifecycle
├── daemon / runtime
└── isolation
Bubblewrap focuses mainly on the last part:
Bubblewrap
└── construct the isolated process environment
That is why it can be embedded as a component inside larger systems.
It does not attempt to solve image distribution, orchestration, registries, or fleet management.
The relationship with Flatpak
Now we reach the second half of the original sentence: used by Flatpak.
Flatpak wants to run desktop applications with limited access to the host system.
By default, its sandboxing model restricts things such as:
- host files;
- devices;
- external processes;
- certain syscalls;
- system services;
- D-Bus;
- and, unless allowed, network access.
But Flatpak needs a mechanism that turns those policy decisions into real process isolation.
Bubblewrap is one of the fundamental pieces it uses to build that environment.
A useful model is:
Flatpak
│
defines permissions/policy
│
▼
Bubblewrap
│
builds namespaces + mounts
│
▼
Linux kernel
This is probably the most useful way to understand their relationship:
Flatpak decides what should be allowed. Bubblewrap helps turn that decision into an isolated runtime environment.
Bubblewrap is NOT a complete security policy
This is perhaps the most important detail of all.
Bubblewrap’s maintainers explicitly describe it as a tool for constructing sandbox environments, not as a complete ready-made sandbox with one fixed security policy.
The amount of isolation depends on the arguments used to launch it.
For example, one caller could create a very restrictive environment:
minimal filesystem
no network
no external processes
read-only directories
restrictive seccomp
Another could create a much more permissive environment:
full home directory
shared network
many devices
numerous host mounts
Both could have been created with Bubblewrap.
The tool provides the mechanisms. The program invoking it —Flatpak, another framework, or an ad-hoc script— is responsible for designing the security model.
Namespaces: the technology behind the illusion
Namespaces are one of the foundations of modern containers on Linux.
They allow two processes sharing the same kernel to have different views of the system.
For example:
PID namespace
A process inside the sandbox can be prevented from seeing processes running on the host.
HOST
PID 1 systemd
PID 800 sshd
PID 1200 browser
PID 3000 sandbox
SANDBOX
PID 1 application
PID 2 worker
Network namespace
The sandbox can receive its own network stack and be left with only a loopback interface instead of direct access to the host network.
Mount namespace
This controls which parts of the filesystem appear inside the sandbox.
User namespace
This allows users and groups to be mapped differently inside the isolated environment.
Bubblewrap acts as a relatively small layer that assembles these capabilities.
Why this matters for agents and modern developer tools
The concept extends far beyond Flatpak.
We increasingly run software that generates or executes actions dynamically:
- AI agents;
- autonomous developer tools;
- CI runners;
- third-party code processors;
- plugins;
- systems that execute automatically generated commands.
In all of these environments the same question appears repeatedly:
How do we let a process do useful work without handing it the entire machine?
Bubblewrap represents a powerful philosophy for answering that question:
Do not ask only:
"Do I trust this program?"
Also ask:
"Which capabilities does it actually need?"
Then build an environment where only those capabilities are available.
A simple analogy
Think of Bubblewrap as the contractor that builds a secure room.
Flatpak is the architect handing over the plans:
Flatpak:
- one door
- no windows
- access to this cabinet
- no access to the rest of the house
Bubblewrap takes those instructions and constructs the room using Linux kernel primitives.
The application lives inside it.
That is also why the name Bubblewrap is so fitting: it wraps a process in a protective layer.
Reading the original sentence again
When we return to:
Low-level unprivileged sandboxing tool used by Flatpak and similar projects
we can now interpret each part precisely:
Low-level
→ works directly with Linux kernel mechanisms.
Unprivileged
→ can be used by ordinary users through user namespaces.
Sandboxing tool
→ constructs restricted environments for processes.
Used by Flatpak
→ Flatpak uses it as a mechanism for materializing its isolation policy.
And one final idea is worth remembering:
Bubblewrap does not decide the security policy. It provides the mechanisms another system can use to build one.
Sources
- Bubblewrap official repository: https://github.com/containers/bubblewrap
- Flatpak — Sandbox Permissions: https://docs.flatpak.org/en/latest/sandbox-permissions.html