sandbubble - a python sandbox for untrusted code
sandbubble runs python written by an LLM or an agent inside a lightweight sandbox. The code cannot reach your home directory or ssh keys. It does this without docker or a virtual machine.
It is one file, sandbox.py, which you put in your project. There is no build step, daemon, or container to manage. It starts quickly. The sandbox is a python virtualenv, so you can use a venv that already has your private dependencies.
It sets up a fresh bubblewrap
container with a tmpfs root, read-only system directories (/usr, /lib, /bin, /sbin), and separate /proc, /dev, and /tmp filesystems. The container can use the venv linked to the python executable. Network access is on by default; --disable-network turns it off. One writable host directory is mounted at /mnt for moving data in and out. AppArmor, through aa-exec, constrains both bubblewrap and the code it runs.
Setup is a one-off. Run sandbox.py as a script. It works out the AppArmor profile needed by the virtualenv, writes the profile, and prints the cp and apparmor_parser commands needed to install it. The profile is plain text, so you can inspect it before loading it as root. Run the script again after installing the profile and it runs self-checks for the isolation. sandbox_extra_tests.py adds an extended --extra-tests suite. You then use sandbox.py as a module with get_default_sandbox_config(), SandboxConfig, and either run_sandboxed() or run_sandboxed_async(). It needs Linux with AppArmor enabled, bubblewrap, the aa-exec userspace tools, and a virtualenv.
sandbubble is an isolation layer, not a hardened sandbox. It is suitable for an internal application, but a determined attacker may escape it. The kernel remains trusted, so sandbubble does not protect against kernel 0-days or a new container escape. It has no default limits for cpu, memory, disk, or output. Add cgroups and rlimits if you need them. It is not formally verified, and changing the mounts or AppArmor profile changes what an escape would have to get through. Network access is on by default, so code can send data out. That is a convenience setting, not a security measure.
The scope is narrow. sandbubble is for running your own internal LLM or agent code behind a boundary you can inspect. Do not use it for hostile public input or multi-tenant workloads. Those need stronger isolation. The code is at github.com/nzjrs/sandbubble .