GitXplorerGitXplorer
g

python-sandbox

public
1 stars
2 forks
0 issues

Commits

List of commits on branch master.
Unverified
f469fa267d54d7cb28abbc0fd99df5872db7382d

Implement env var to override env directory

committed 8 days ago
Unverified
f1f140a066ad1d3babb1f7a9b6e1ec063a748db3

Allow for local customization

committed 9 days ago
Unverified
bb2fdc3bd533dbf2750e4f0eef47aac33b69b726

Fix HOME dir expansions in env vars

committed 9 days ago
Unverified
b99d8b1ddc7960e1dfee5df29f71cc6e31fc29c0

Support conda/mamba shims

committed 9 days ago
Unverified
bb08b8524faab85fe377971c06571ad738bd3890

Add support for having conda environments as well

committed 9 days ago
Unverified
cd68931374f15b28e3ac75310e138dc1a6ad4028

Fix a bug when supplying working dir as .

committed 9 days ago

README

The README file for this repository.

Python Sandboxing

Do you trust whatever comes out of pip install? Do you trust nightly builds?

A single hijacked package in your dependencies can leak all your secrets (private keys, tokens, github access, emails, ...).

No? Good! Maybe this is a solution for you, then.

This project aims to provide firejail profiles for python development environments. This means that you will have an isolated shell with only selected parts, some read-only, some not at all visible, of your host filesystem.

Image of a terminal showing access of .ssh folder and no access after activation of the sandbox

This is by no means perfect but at least it is better than being at the mercy of pypi.

Requirements

  • firejail
  • python-virtualenv
  • bash or zsh
  • Linux based OS (WSL2 might work)

Installation

Very basic

This will give you the ability to create python sandboxes from a template and nothing more. No integration into your shell. This is how to do it:

$ sudo apt install firejail python-virtualenv
$ git clone git@github.com:githubnemo/python-sandbox.git
<add $PWD/python-sandbox to your PATH in .bashrc / .zshrc / ...>

This setup assumes that your python envs will live in ~/envs/<sandbox-name>.

Advanced shell integration

There are examples for ZSH and bash on how to integrate these sandboxes better into your environment. These features are showcased in the Neat Things section. I'm not confident enough in these features yet to build a script that you can simply source, sorry.

Allowing your tools inside the sandbox

The default template will never cover all your custom setup. To allow for additional tools outside of the basic template, you can add your own access configuration with a local override that works for every template.

You can place arbitrary rules in ~/.config/firejail/python-env-template.local and they are included in the environment profile.

For example, if you have a specific tool, say fzf, in a directory outside of the sandbox and your .bashrc depends on that path, you could add it there.

Example python-env-template.local file:

whitelist ${HOME}/Code/fzf
read-only ${HOME}/Code/fzf

With the above content your sandbox is now able to access ~/Code/fzf. See man firejail-profile for all possible directives.

Workflow

New python project? New sandbox.

$ mkdir ~/code/mynewproject
$ create-python-sandbox mynewproject ~/code/mynewproject

# After profile creation we can jump into the sandbox
$ firejail --profile=python-env-mynewproject --tab bash

# We can now create a virtualenv there (or use poetry, conda, ...)
$ python -m venv ~/envs/mynewproject
$ . ~/envs/mynewproject/bin/activate
$ pip install [...]

It is best to make access to the sandbox as easy as possible. At best, never leave it (launch a tmux session inside the sandbox, work in there). Second best: create an alias to quickly jump into the sandbox. See section "Common entrypoint":

$ sbox mynewproject

Neat things

Common entrypoint

I have a function definition for invoking sandboxed shells

sbox() {
    # replace "bash" with any shell you like
    firejail --profile=python-env-$1 --tab bash
}

so I can quickly jump into the sandbox using sbox myenv.

Visual hint of being inside a sandbox

To gauge if I'm in a sandbox or not the sandbox environment provides an environment variable (JAILED_ENV=<env name>) so it is easy to react on that in the shell prompt.

Example from my .bashrc:

jail=""
if [ -n "$JAILED_ENV" ]; then
    jail="(J:${JAILED_ENV})"
fi

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}${jail}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}${jail}\u@\h:\w\$ '
fi

Entering the sandbox upon entering a directory

To enter the sandbox as soon as you're working on a project, you can configure your shell to watch for .python-sandbox files with the sandbox's name in it.

Showcase of activating the sandbox on directory change

There's an example for ZSH in examples/zsh.md, the gist is:

# Little helper to go upward the directory tree in search for a file.
# Makes sure to use the least amount of external tools for performance.
_upfind() {
    if [[ "$2" -eq 0 ]]; then
        return 1
    fi
    [[ -e "$1" ]] && echo "$1" || _upfind "../$1" "$(($2 - 1))"
}

enable_sbox_if_needed() {
    if [ -n "$JAILED_ENV" ]; then
        return
    fi

    # Look into current and upward directories for sandbox file to
    # enable sandbox upon finding it.
    sandbox_file=$(_upfind ".python-sandbox" 5)

	if [[ "$?" -eq 0 ]]; then
        export PWD_BEFORE_JAIL="$PWD"
        sbox "$(head -n1 "$sandbox_file")"
    fi
}

add-zsh-hook chpwd enable_sbox_if_needed
enable_sbox_if_needed

Caveats

My bashrc is different in the sandbox :(

Depending on your firejail version, the sandbox bashrc is sourced from /etc/skel/.bashrc. Newer versions of firejail support the keep-shell-rc configuration option. Enable it in the template to avoid this problem.

Tab completion is not working?!

Note the --tab option of firejail. Firejail disables tab completion for bash since there were vulnerabilities in the implementation before and you have to supply --tab to enable that feature explicitly.

To do

  • [ ] limit access to SSH agent from inside the sandbox
  • [ ] limit access to specific read-only tokens (e.g. hf hub)
  • [ ] make paths to tools like fzf, pyenv, conda, etc. configurable