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
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
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:
- Namespace isolation - Each command runs in isolated namespaces (PID, mount, network, etc.)
- Read-only mounts - System directories are mounted read-only
- Temporary filesystems - Writable locations use ephemeral tmpfs
- Command allowlisting - Only explicitly permitted commands can execute
- 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:
- Click the "Open in GitHub Codespaces" badge above
- Wait for the container to build (includes bubblewrap and all dependencies)
- 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
- installation.md - Installation for various Linux distributions
- usage.md - CLI usage and common use cases
- profiles.md - Complete profile configuration reference
- api.md - Python API documentation
- deployment.md - Deployment with Ansible, systemd, SSH
- seccomp.md - Optional: Adding seccomp BPF filters
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
- Documentation: docs/
- Issues: GitHub Issues
- Discussions: GitHub Discussions
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
15b606db1644cd8c87807bbf41b12074f15a68211fb1e9771f13fda09b1c5c37
|
|
| MD5 |
bc613daa060d8c350adf0655268cecc7
|
|
| BLAKE2b-256 |
104af7b78b86f7404465d36d1315ff2697205459b21e54b89a8dc2b7a2f9c234
|
Provenance
The following attestation bundles were made for shannot-0.1.1.tar.gz:
Publisher:
release.yml on corv89/shannot
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
shannot-0.1.1.tar.gz -
Subject digest:
15b606db1644cd8c87807bbf41b12074f15a68211fb1e9771f13fda09b1c5c37 - Sigstore transparency entry: 623095348
- Sigstore integration time:
-
Permalink:
corv89/shannot@a790453f0325f3d3d5fce00b0803ea88abfcf628 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/corv89
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@a790453f0325f3d3d5fce00b0803ea88abfcf628 -
Trigger Event:
release
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
582f19338a961065105fa97c34e96719e2065628a7cd7028f90a8ed6719601de
|
|
| MD5 |
083da4a7181d2a26804a78770b803e00
|
|
| BLAKE2b-256 |
4849f7e0f532d85e030e4ab3068c87c28c5f77921f9e826fa1570cf88837fd4b
|
Provenance
The following attestation bundles were made for shannot-0.1.1-py3-none-any.whl:
Publisher:
release.yml on corv89/shannot
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
shannot-0.1.1-py3-none-any.whl -
Subject digest:
582f19338a961065105fa97c34e96719e2065628a7cd7028f90a8ed6719601de - Sigstore transparency entry: 623095351
- Sigstore integration time:
-
Permalink:
corv89/shannot@a790453f0325f3d3d5fce00b0803ea88abfcf628 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/corv89
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@a790453f0325f3d3d5fce00b0803ea88abfcf628 -
Trigger Event:
release
-
Statement type: