Bubblewrap

2026-03-15

I found out about Bubblewrap recently. It allows the user to run a program in a sandbox, and restrict its access to paths and resources on the host.

For instance, we can run a Bash shell which has no network interface:

$ bwrap --unshare-all --new-session --ro-bind / / /bin/bash
$ ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
$ curl icanhazip.com
curl: (6) Could not resolve host: icanhazip.com

Or, maybe you want to run a command which does not have access to your personal files inside /home:

$ bwrap --ro-bind /usr /usr \
      --symlink usr/lib64 /lib64 \
      --symlink usr/bin /bin \
      --symlink usr/sbin /sbin \
      --chdir / \
      --unshare-all \
/bin/bash
bash-5.2$ ls /home
ls: cannot access '/home': No such file or directory

Note: The reason that we mount the various directories in /usr and under it separately, but don’t mount / directly, is to ensure that we can mount something else at /home! In fact, it is possible to use bwrap to start as a new user with its own home directory that is inside the ~/sandbox of the host’s filesystem. I was wondering why all the online examples used this!

So far, I have had one use-case for such sandboxing: I use a Perl script to convert GnuCash files into Ledger data files, because I use Ledger for analyzing my personal finances. I want this script to never edit the input GnuCash file. I know that the program does not do it; however, having an additional guarantee is not a bad idea, so I use Docker to run the script and use a read-only volume mount to ensure that the input file can not be edited. This has not been easy to use though. So, I will probably shift it to use Bubblewrap soon.