Skip to main content

A Python sandboxing tool for enforcing filesystem and network restrictions on arbitrary processes at the OS level

Project description

py-sandboxrt — Python Sandbox Runtime

PyPI version CI Python Versions License

A Python port of the Anthropic Sandbox Runtime, providing lightweight OS-level sandboxing for arbitrary processes without requiring a container.

py-sandboxrt uses native OS sandboxing primitives (sandbox-exec on macOS, bubblewrap on Linux) and proxy-based network filtering. It can be used to sandbox the behaviour of agents, local MCP servers, bash commands, and arbitrary processes.

Installation

Install from PyPI using pip:

pip install py-sandboxrt

Or using uv:

uv add py-sandboxrt

Development Installation

Clone the repository and install in development mode:

git clone https://github.com/saolalab/py-sandboxrt.git
cd py-sandboxrt
pip install -e ".[dev]"

Or with uv:

uv sync --dev

Quick Start

CLI

# Run a command in the sandbox
srt echo "hello world"

# With debug logging
srt --debug curl https://example.com

# Custom settings file
srt --settings /path/to/srt-settings.json npm install

# Command string mode
srt -c "curl https://example.com && echo done"

Library

import asyncio
from srt import SandboxManager, SandboxRuntimeConfig
from srt.config import NetworkConfig, FilesystemConfig

config = SandboxRuntimeConfig(
    network=NetworkConfig(
        allowed_domains=["example.com", "api.github.com"],
        denied_domains=[],
    ),
    filesystem=FilesystemConfig(
        deny_read=["~/.ssh"],
        allow_write=[".", "/tmp"],
        deny_write=[".env"],
    ),
)


async def main():
    mgr = SandboxManager()
    await mgr.initialize(config)

    sandboxed_cmd = await mgr.wrap_with_sandbox("curl https://example.com")

    import subprocess
    proc = subprocess.Popen(sandboxed_cmd, shell=True)
    proc.wait()

    mgr.cleanup_after_command()
    await mgr.reset()


asyncio.run(main())

Configuration

Settings File

By default, py-srt reads ~/.srt-settings.json. Override with --settings:

srt --settings /path/to/config.json <command>

The config file uses the same JSON format as the TypeScript version (camelCase keys are automatically converted):

{
  "network": {
    "allowedDomains": [
      "github.com",
      "*.github.com",
      "npmjs.org",
      "*.npmjs.org"
    ],
    "deniedDomains": ["malicious.com"]
  },
  "filesystem": {
    "denyRead": ["~/.ssh"],
    "allowWrite": [".", "src/", "test/", "/tmp"],
    "denyWrite": [".env", "config/production.json"]
  }
}

Network Configuration (allow-only pattern)

All network access is denied by default.

Key Description
allowedDomains Domains permitted to connect to (supports *.example.com wildcards)
deniedDomains Domains explicitly blocked (checked first, overrides allow)
allowUnixSockets macOS only: specific Unix socket paths to allow
allowAllUnixSockets Allow all Unix sockets on both platforms
allowLocalBinding Allow binding to local ports (default: false)

Filesystem Configuration

Key Pattern Description
denyRead deny-only Paths to block reading (default: allow all reads)
allowWrite allow-only Paths to allow writing (default: deny all writes)
denyWrite deny-within-allow Paths to block writing even within allowed paths

Mandatory Deny Paths (Auto-Protected)

Certain sensitive files are always blocked from writes, even within allowed paths:

  • Shell configs: .bashrc, .bash_profile, .zshrc, .zprofile, .profile
  • Git configs: .gitconfig, .gitmodules
  • Other: .ripgreprc, .mcp.json
  • Directories: .vscode/, .idea/, .claude/commands/, .claude/agents/, .git/hooks/

How It Works

Dual Isolation Model

  • macOS: Uses sandbox-exec with dynamically generated Seatbelt profiles
  • Linux: Uses bubblewrap for containerized filesystem and network namespace isolation

Network Filtering

HTTP and SOCKS5 proxy servers run on the host, filtering all traffic against domain allowlists:

  1. HTTP/HTTPS — intercepted by an HTTP proxy that validates CONNECT tunnels and forwards requests
  2. Other TCP — handled by a SOCKS5 proxy for SSH, database connections, etc.
  3. Linux bridgesocat relays between Unix sockets (inside sandbox) and TCP ports (host proxies)

Filesystem Restrictions

  • Read (deny-only): All reads allowed by default; deny specific paths
  • Write (allow-only): All writes denied by default; explicitly allow paths
  • macOS uses Seatbelt regex/glob matching; Linux uses bubblewrap bind mounts

Architecture

src/srt/
├── __init__.py           # Public API exports
├── cli.py                # CLI entrypoint (srt command)
├── config.py             # Pydantic configuration models
├── sandbox_manager.py    # Main orchestrator
├── http_proxy.py         # HTTP/HTTPS proxy with domain filtering
├── socks_proxy.py        # SOCKS5 proxy with domain filtering
├── macos_sandbox.py      # macOS sandbox-exec Seatbelt profiles
├── linux_sandbox.py      # Linux bubblewrap sandboxing
├── sandbox_utils.py      # Shared utilities (paths, globs, env vars)
├── violation_store.py    # In-memory violation tracking
├── platform_utils.py     # Platform detection
└── debug.py              # Debug logging

Platform Support

Platform Mechanism Dependencies
macOS sandbox-exec + Seatbelt profiles ripgrep
Linux bubblewrap + network namespaces bubblewrap, socat, ripgrep
Windows Not supported

Installing Dependencies

macOS:

brew install ripgrep

Linux (Debian/Ubuntu):

sudo apt-get install bubblewrap socat ripgrep

Debug Logging

Set the SRT_DEBUG environment variable to enable verbose logging to stderr:

SRT_DEBUG=1 srt curl https://example.com
# or
srt --debug curl https://example.com

License

Apache-2.0 — see LICENSE for details.

Credits

Python port of anthropic-experimental/sandbox-runtime.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

py_sandboxrt-0.2.0.tar.gz (92.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

py_sandboxrt-0.2.0-py3-none-any.whl (39.0 kB view details)

Uploaded Python 3

File details

Details for the file py_sandboxrt-0.2.0.tar.gz.

File metadata

  • Download URL: py_sandboxrt-0.2.0.tar.gz
  • Upload date:
  • Size: 92.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for py_sandboxrt-0.2.0.tar.gz
Algorithm Hash digest
SHA256 064cc9fc7b6e17e16c5bed97c9b99ed525207f279cc53ee25c17615ef15f4eee
MD5 17ff01324d06ce34083f4b9be4292f47
BLAKE2b-256 03edc27cfa21742eeb1eb508dacb02063c66c304e8aab05c6230ed5aa2f16cef

See more details on using hashes here.

Provenance

The following attestation bundles were made for py_sandboxrt-0.2.0.tar.gz:

Publisher: publish.yml on saolalab/py-sandboxrt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file py_sandboxrt-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: py_sandboxrt-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 39.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for py_sandboxrt-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 363d8b3432e19d727da3a0c1ede8211622d8a11e86c123a6d2362ea2f4fcc7f1
MD5 bdcd74a32402f2ed1f8733a80b55970f
BLAKE2b-256 d48fa11014fcbd63f7528fce4416c92ffc69704fb340ae1bf3057ede7344f8b6

See more details on using hashes here.

Provenance

The following attestation bundles were made for py_sandboxrt-0.2.0-py3-none-any.whl:

Publisher: publish.yml on saolalab/py-sandboxrt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page