Skip to main content

bubble-sandbox

A Python-specific driver for configuring bubblewrap sandboxes using a specified Python virtual environment, controlling which packages are available.

Each execution runs in a disposable sandbox with the following constraints:

  • no network access
  • PID isolation
  • read-only filesystem (unless host directories are mounted read-write)

This package provides driver commands:

  • bubble-sandbox runs bwrap command with arguments which populate the sandbox filesystem using a specified Python virtual environment before running a Python script in the sandbox. The command can optionally copy host-sytem files into the /sandbox/workspace directory (the working directory in which the script runs).

Quick Start

Build and run:

uv sync
uv run bubble-sandbox exec-script \
  --environment=bare' \
  --script='script=print("hello world")' | jq
{
  "stdout": "hello world\n",
  "stderr": "",
  "return_code": 0
}

CLI commands

bubble-sandbox list-environments

List available execution environments and their dependencies.

uv run bubble-sandbox list-environments

──────────────────────────── Available environments ────────────────────────────

- bare
- pandas-only

bubble-sandbox exec-script

Execute a Python script in a sandboxed environment.

Inline script:

uv run bubble-sandbox exec-script \
  --environment="bare" \
  --script="import sys; print(sys.version_info)"

──────────── Running script: 'import sys; print(sys.version_info)' ─────────────

sys.version_info(major=3, minor=13, micro=12, releaselevel='final', serial=0)

Script stored in a file (same script as above):

uv run bubble-sandbox exec-script \
  --environment="bare" \
  --script-file=/tmp/foo.py

───────────────────────── Running script: @/tmp/foo.py ─────────────────────────

sys.version_info(major=3, minor=13, micro=12, releaselevel='final', serial=0)

bubble-sandbox exec-command

Execute a shell command in a sandboxed environment.

uv run bubble-sandbox exec-command \
  --environment="bare" \
  --workdir "/tmp/test" \
  "pwd && ls -l"

───────────────────── Running shell command: pwd && ls -l ──────────────────────

/sandbox/work
total 8
-rw-rw-r-- 1 1000 1000  4 Apr  7 16:38 baz.txt
-rw-rw-r-- 1 1000 1000 58 Apr  7 16:38 script.py

bubble-sandbox exec-command

Execute a command line (no shell wrapper) in a sandboxed environment.

$ uv run bubble-sandbox execute -w /tmp/bar/ -e bare -- ls -laF

─────────────────────────── Running command: ls -laF ───────────────────────────

total 12
drwxrwxr-x 2 1000 1000 4096 Apr  7 16:38 ./
drwx------ 4 1000 1000   80 Apr  7 18:11 ../
-rw-rw-r-- 1 1000 1000    4 Apr  7 16:38 baz.txt
-rw-rw-r-- 1 1000 1000   58 Apr  7 16:38 script.py

Note: the -- above prevents the CLI from interpreting the -laf as one of its own arguments.

Configuration

All settings are configured via environment variables with the BUBBLE_SANDBOX_ prefix:

Variable Default Description
BUBBLE_SANDBOX_ENVIRONMENTS_DIR environments Path to environments directory
BUBBLE_SANDBOX_WORKSPACE_DIR workspace_data Root directory for session workspaces and volumes
BUBBLE_SANDBOX_MAX_UPLOAD_SIZE_BYTES 10485760 Max total upload size (10 MB)
BUBBLE_SANDBOX_ALLOWED_EXTENSIONS [".txt",".csv",".md",".json",".yaml",".yml",".tsv",".xml"] Allowed file extensions (JSON list)
BUBBLE_SANDBOX_EXECUTION_TIMEOUT_SECONDS 30 Max script execution time
BUBBLE_SANDBOX_SESSION_IDLE_TIMEOUT_SECONDS 3600 Session idle timeout (seconds)
BUBBLE_SANDBOX_MAX_SESSIONS 50 Maximum concurrent sessions
BUBBLE_SANDBOX_ALLOW_PERSISTENT_SESSIONS true Allow clear_data=false on delete
BUBBLE_SANDBOX_LOG_LEVEL INFO Log level (JSON to stdout)

Adding Environments

Each subdirectory in environments/ is a self-contained Python environment with its own virtual environment and dependencies.

1. Create the environment directory

mkdir environments/my-env

2. Add a pyproject.toml

[project]
name = "my-env"
version = "0.1.0"
requires-python = ">=3.13"
dependencies = [
    "requests>=2.32",
    "beautifulsoup4>=4.12",
]

3. Sync the environment

cd environments/my-env
uv sync

This creates a .venv/ directory with the declared dependencies installed.

Note: Avoid using a Python here which derives from another virtual environment: instead, use the "base" environment. E.g.:

uv sync --python="/opt/Python-3.13.12"

4. Use it

uv run bubble-sandbox exec-script \
  --environment="my-dnv" \
  --script='import requests; print(requests.get("http://example.com").status_code)'

Note: network access is disabled in the sandbox by default, so scripts that make HTTP requests will fail. The environment provides the libraries, not network access.

Bundled environments

Name Dependencies Use case
bare (none) Standard library only
pandas-exec pandas 3.0.1+ Data analysis with pandas

Sandbox Isolation

Each script execution is wrapped in a bubblewrap sandbox that provides:

  • Filesystem isolation: read-only bind mounts for system libraries and the selected venv; a writable tmpfs for /tmp; uploaded files available in the working directory
  • User namespace (--unshare-user): runs as an unprivileged user
  • PID namespace (--unshare-pid): cannot see or signal other processes
  • Network isolation (--unshare-net): no network access (loopback only)
  • Session isolation (--new-session): no TTY control
  • Auto-cleanup (--die-with-parent): sandbox is killed if the server process dies

The sandbox working directory and all uploaded files are deleted after execution completes.

Development

# Install dependencies
uv sync

# Sync environment venvs (for local testing) (see note above).
cd environments/bare && uv sync && cd ../..
cd environments/pandas-exec && uv sync && cd ../..

# Run tests (100% coverage required)
uv run pytest

# Lint and format
uv run ruff check
uv run ruff format --check

Metadata

Release files for bubble-sandbox 0.13

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bubble-sandbox 0.13
File Size Uploaded
bubble_sandbox-0.13.tar.gz 12.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for bubble-sandbox 0.13
File Interpreter ABI Platform
bubble_sandbox-0.13-py3-none-any.whl Python 3 none any Details

Total release size: 26.7 kB

Release files / bubble_sandbox-0.13.tar.gz

Download URL bubble_sandbox-0.13.tar.gz
Size 12.3 kB
Tags Source
SHA-256 checksum
How to use checksums
45e6fbb6f23286c3ef8cdf95dc7c34f53169835d1ea7e58742f5ea84f2b3e27d
BLAKE2b-256 checksum
How to use checksums
81175fc524e2a1dc159b9a7e95ab47e7a7923122cae1c2330b334fa5e20d1fa0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release files / bubble_sandbox-0.13-py3-none-any.whl

Download URL bubble_sandbox-0.13-py3-none-any.whl
Size 14.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
673394b86a8baa8186a6ca69700818ba9d6ffd44ef5748d34191268cd8e08ba5
BLAKE2b-256 checksum
How to use checksums
b45f498a965ebd05d49e2230db3b405c3a383aad3686085ec30d9918cbcf8778
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release history Release notifications | RSS feed

This release

0.13 This release

2 release files

0.12.0

2 release files

0.11.0

2 release files

0.10.0

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page