Skip to main content

Secure read-only sandboxing for LLM agents and system diagnostics

Reason this release was yanked:

Python 3.9 no longer supported. Please upgrade to Python 3.10+ and use shannot>=0.3.0

Project description

Shannot Sandbox

Tests License Python Linux

Shannot is an easy-to-deploy sandbox tool for running commands in a secure, read-only environment using Linux's bubblewrap. It's designed for system diagnostics and monitoring, particularly with LLM-based agents where strict read-only enforcement is critical.

Claude shannot do that!

🚀 Try it now

Open in GitHub Codespaces

Want to try Shannot without installing anything? Click the badge above to open a dev environment to start testing sandboxed commands in seconds!

Features

  • Minimal dependencies - Only requires Python 3.9+ and bubblewrap
  • Read-only by default - Prevents any modifications to the host system
  • Network isolation - Commands run without network access by default
  • JSON-based profiles - Easy to configure and share
  • Command allowlisting - Restrict which commands can be executed
  • Drop-in deployment - Transfer to remote systems and run in minutes
  • Type-safe API - Fully typed Python interface

Quick Start

Installation

# Install bubblewrap (if not already installed)
# Fedora/RHEL
sudo dnf install bubblewrap

# Debian/Ubuntu
sudo apt install bubblewrap

# Install shannot
pip install shannot

# Or use the installation script
./install.sh

Usage

# Run a command in the sandbox
shannot run ls /

# Verify the sandbox is working
shannot verify

# Export your profile configuration
shannot export

# Use a custom profile
shannot --profile /path/to/profile.json run cat /etc/os-release

# Get help
shannot --help

Use Cases

Remote System Diagnostics

Allow LLM agents or remote operators to inspect system state without modification risk:

shannot run df -h
shannot run cat /proc/meminfo
shannot run systemctl status

Safe Command Exploration

Test unfamiliar commands without worrying about side effects:

shannot run find / -name "*.conf"
shannot run grep -r "pattern" /var/log

Automated Monitoring

Build monitoring scripts with guaranteed read-only access:

from shannot import SandboxManager, load_profile_from_path
from pathlib import Path

profile = load_profile_from_path("~/.config/shannot/profile.json")
manager = SandboxManager(profile, Path("/usr/bin/bwrap"))

result = manager.run(["df", "-h"])
if result.succeeded():
    print(result.stdout)

Configuration

Shannot uses JSON profiles to define sandbox behavior. Three profiles are included:

Included Profiles

minimal.json (default) - Basic read-only access:

  • Commands: ls, cat, grep, find
  • Binds: /usr, /etc, /lib, /lib64
  • Works out-of-the-box, no setup required

readonly.json - Comprehensive read-only profile:

  • Extended command set
  • Additional binds (includes /sbin, /var/lib/ca-certificates)
  • Suitable for most use cases

diagnostics.json - System monitoring and diagnostics:

  • Full diagnostic commands: df, free, ps, uptime
  • Access to /proc, /sys, /var/log
  • Perfect for LLM-based monitoring

Quick Profile Example

{
  "name": "minimal",
  "allowed_commands": ["ls", "cat", "grep", "find"],
  "binds": [
    {"source": "/usr", "target": "/usr", "read_only": true}
  ],
  "tmpfs_paths": ["/tmp"],
  "environment": {"PATH": "/usr/bin:/bin"},
  "network_isolation": true
}

See docs/profiles.md for complete profile documentation.

How It Works

Shannot wraps Linux's bubblewrap tool to create lightweight, secure sandboxes:

  1. Namespace isolation - Each command runs in isolated namespaces (PID, mount, network, etc.)
  2. Read-only mounts - System directories are mounted read-only
  3. Temporary filesystems - Writable locations use ephemeral tmpfs
  4. Command allowlisting - Only explicitly permitted commands can execute
  5. No persistence - All changes are lost when the command exits

Python API

from shannot import SandboxManager, load_profile_from_path
from pathlib import Path

# Load profile and create manager
profile = load_profile_from_path("~/.config/shannot/profile.json")
manager = SandboxManager(profile, Path("/usr/bin/bwrap"))

# Run commands
result = manager.run(["ls", "/"])
print(f"Output: {result.stdout}")
print(f"Duration: {result.duration:.2f}s")

See docs/api.md for complete API documentation including profile creation, error handling, and advanced usage.

Requirements

  • Operating System: Linux (kernel 3.8+)
  • Python: 3.9 or newer
  • System Package: bubblewrap (bwrap)

Deployment

SSH Install

For quick deployment to remote systems:

# Transfer and install in one command
ssh user@remote "bash -s" < install.sh

See docs/deployment.md for advanced deployment scenarios.

Development

Quick Start with Codespaces

The fastest way to start developing:

  1. Click the "Open in GitHub Codespaces" badge above
  2. Wait for the container to build (includes bubblewrap and all dependencies)
  3. Start coding immediately - everything is pre-configured!

Local Development Setup

# Clone the repository
git clone https://github.com/corv89/shannot.git
cd shannot

# Install bubblewrap (required for testing)
sudo apt install bubblewrap  # Debian/Ubuntu
sudo dnf install bubblewrap  # Fedora/RHEL

# Install in development mode with dev dependencies
pip install -e ".[dev]"

# Run tests
pytest tests/ -v

# Run linter and formatter
ruff check .
ruff format .

# Run type checker
basedpyright

Running Tests

# Run all tests
pytest tests/ -v

# Run with coverage
pytest tests/ --cov=shannot --cov-report=html

# Run only unit tests (skip integration tests)
pytest tests/ -v -m "not integration"

# Run only integration tests (requires Linux + bubblewrap)
pytest tests/ -v -m "integration"

Note: Integration tests require Linux and bubblewrap. They will be automatically skipped on other platforms.

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

Documentation

Contributing

Contributions are welcome!

  • Report bugs via GitHub Issues
  • Submit pull requests
  • Request features
  • Share use cases

Security Considerations

While Shannot provides strong isolation, it's not a security boundary:

  • Kernel vulnerabilities - Sandbox escapes are possible via kernel exploits
  • Information leakage - Read-only access still exposes system information
  • Resource limits - No built-in CPU/memory limits (use systemd or cgroups)
  • Root usage - Don't run shannot as root unless absolutely necessary

For production security, combine with:

  • SELinux/AppArmor policies
  • seccomp filters (supported via profiles)
  • User namespaces
  • Resource limits via cgroups

License

Apache License 2.0 - See LICENSE file for details.

Credits

Shannot builds upon:

  • Bubblewrap - The low-level Linux sandboxing tool
  • libseccomp - The BPF-based syscall filtering library

Support

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

shannot-0.1.1.tar.gz (26.9 kB view details)

Uploaded Source

Built Distribution

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

shannot-0.1.1-py3-none-any.whl (20.8 kB view details)

Uploaded Python 3

File details

Details for the file shannot-0.1.1.tar.gz.

File metadata

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

File hashes

Hashes for shannot-0.1.1.tar.gz
Algorithm Hash digest
SHA256 15b606db1644cd8c87807bbf41b12074f15a68211fb1e9771f13fda09b1c5c37
MD5 bc613daa060d8c350adf0655268cecc7
BLAKE2b-256 104af7b78b86f7404465d36d1315ff2697205459b21e54b89a8dc2b7a2f9c234

See more details on using hashes here.

Provenance

The following attestation bundles were made for shannot-0.1.1.tar.gz:

Publisher: release.yml on corv89/shannot

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

File details

Details for the file shannot-0.1.1-py3-none-any.whl.

File metadata

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

File hashes

Hashes for shannot-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 582f19338a961065105fa97c34e96719e2065628a7cd7028f90a8ed6719601de
MD5 083da4a7181d2a26804a78770b803e00
BLAKE2b-256 4849f7e0f532d85e030e4ab3068c87c28c5f77921f9e826fa1570cf88837fd4b

See more details on using hashes here.

Provenance

The following attestation bundles were made for shannot-0.1.1-py3-none-any.whl:

Publisher: release.yml on corv89/shannot

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