Motivation for this is already documented in e.g. python security post. Here the aim is to be able run isolated Python processes on a fully ad-hoc basis without need to be thinking about long-lived containers. This approach is based more on filesystem hierarchy and integrates better with traditional unix tools.

Aims

  1. Python processes can only read and write data within a project filesystem tree
  2. Python can see the internet only during installation of packages, but during this time it can not see the rest of project
  3. During running the project Python can not communicate with internet, and can not change any information which it sees during stage (2)
  4. Can use Jupyter and friends as normal

Implementation

The project directory has to exist before start:

export PROJ=$HOME/j/t3
mkdir -p $PROJ

I am using pyenv to install arbitrary python versions, so give access to it. In first step of creating the virtual env there is no need for network:

firejail --whitelist=$HOME/.pyenv/ --read-only=$HOME/.pyenv/ --whitelist=$PROJ  --net=none python3  -m venv  $PROJ/.venv

To install packages enable network, but disable access to rest of project, only allow the .venv:

firejail --whitelist=$HOME/.pyenv/ --read-only=$HOME/.pyenv/ --whitelist=$PROJ/.venv  $PROJ/.venv/bin/pip3 install --upgrade pybind11 setuptools jupyter

To run Jupyter disable networking but launch Jupyter listening on a Unix socket. Mount the “.venv” read-only so that any subsequent package installs with network can not leak info:

firejail --whitelist=$HOME/.pyenv/ --read-only=$HOME/.pyenv/  --whitelist=$PROJ --read-only=$PROJ/.venv   --net=none $PROJ/.venv/bin/jupyter notebook --sock $PROJ/jupyter.sock --no-browser