Skip to main content

Secure read-only sandboxing for LLM agents and system diagnostics

Project description

Shannot Sandbox

Tests License Python Linux

Shannot lets LLM agents and automated tools safely explore your Linux systems without risk of modification. Built on bubblewrap, it provides hardened sandboxing for system diagnostics, monitoring, and exploration - perfect for giving Claude or other AI assistants safe access to your servers.

Claude shannot do that!

Features

🔒 Run Untrusted Commands Safely

  • Let LLM agents explore your system without risk of modification
  • Network-isolated execution
  • Control exactly which commands are allowed

🤖 Works with your favorite LLMs

  • Plug-and-play standards-compliant MCP integration
  • Convenient auto-install for Claude Code, Codex, LM Studio and Claude Desktop
  • Compatible with any local model that supports tool-calling

🌐 Control Remote Systems

  • Run sandboxed commands on Linux servers from macOS, Windows or Linux via SSH

Deploy in Minutes

  • Lightweight Python client + bubblewrap on target
  • No containers, VMs, or complex setup required

Quick Start

Installation

  • Client (any platform): Python 3.10+
  • Target (Linux only): bubblewrap

Install on Client (any platform)

# Install UV (recommended - works on all platforms)
curl -LsSf https://astral.sh/uv/install.sh | sh  # macOS/Linux
# Or for Windows: irm https://astral.sh/uv/install.ps1 | iex

# macOS/Windows users (for remote Linux targets)
uv tool install "shannot[mcp]"

# Linux users - local sandbox only
uv tool install shannot

# Linux users - with MCP for Claude Code/Codex
uv tool install "shannot[mcp]"

# Linux users - local & remote execution only (no MCP)
uv tool install "shannot[remote]"

Install on Target (Linux only)

If your target is a remote Linux system, bubblewrap is all you need (Python not required):

# Debian/Ubuntu
sudo apt install bubblewrap

# Fedora/RHEL
sudo dnf install bubblewrap

# openSUSE
sudo zypper install bubblewrap

# Arch Linux
sudo pacman -S bubblewrap

If client and target are the same Linux machine, install both shannot and bubblewrap.

See Deployment Guide for remote execution setup via SSH.

Alternative installation methods

pipx (recommended for Ubuntu/Debian):

Ubuntu and Debian mark system Python as "externally managed" (PEP 668), which prevents pip install --user. Use pipx instead:

# Install pipx
sudo apt install pipx
pipx ensurepath

# Install shannot (local execution only)
pipx install shannot

# With MCP support for Claude Code/Codex (includes remote execution)
pipx install "shannot[mcp]"

# Remote execution only (no MCP)
pipx install "shannot[remote]"

Traditional pip:

# Basic installation (local execution only)
pip install --user shannot

# With MCP support for Claude Code/Codex (includes remote execution)
pip install --user "shannot[mcp]"

# Remote execution only (no MCP)
pip install --user "shannot[remote]"

# Note: On Ubuntu/Debian, you may need --break-system-packages
# (not recommended, use pipx or uv instead)

Optional dependencies:

  • [mcp] - MCP server integration for Claude Code/Codex/Claude Desktop (includes remote execution)
  • [remote] - Remote execution via SSH (without MCP)

Usage

# Run a command in the sandbox
shannot ls /

# Check version
shannot --version

# Verify the sandbox is working
shannot verify

# Export your profile configuration
shannot export

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

# Get help
shannot --help

Use Cases

System diagnostics - Let LLM agents inspect system state without modification risk Safe exploration - Test unfamiliar commands without worrying about side effects Automated monitoring - Build scripts with guaranteed read-only access

# Diagnostics
shannot df -h
shannot cat /proc/meminfo
shannot systemctl status

# Exploration
shannot find / -name "*.conf"
shannot grep -r "pattern" /var/log
# Monitoring scripts
from shannot import SandboxManager, load_profile_from_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 control sandbox behavior. Three profiles included:

  • minimal.json (default) - Basic commands (ls, cat, grep, find), works out-of-the-box
  • readonly.json - Extended command set, suitable for most use cases
  • diagnostics.json - System monitoring (df, free, ps, uptime), perfect for LLM agents
{
  "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 profiles for complete 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

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

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

See api for complete documentation.

Development

# Clone and install
git clone https://github.com/corv89/shannot.git
cd shannot
make install-dev

# Run tests (integration tests require Linux + bubblewrap)
make test
make test-unit  # unit tests only

# Lint and type check
make lint
make format
make type-check

# Optional helpers
make test-integration
make test-coverage
make pre-commit-install  # re-install git hooks if needed

Documentation

Full documentation

Quick links:

Contributing

Contributions welcome! See CONTRIBUTING.md or open an issue.

Security Considerations

Shannot provides strong isolation but is not a security boundary:

  • Sandbox escapes possible via kernel exploits
  • Read-only access still exposes system information
  • No built-in CPU/memory limits (use systemd/cgroups)
  • Don't run as root unless necessary

For production, combine with SELinux/AppArmor, seccomp filters (seccomp), and resource limits.

License

Apache 2.0 - See LICENSE

Built on Bubblewrap and libseccomp

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.3.0.tar.gz (78.0 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.3.0-py3-none-any.whl (59.0 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for shannot-0.3.0.tar.gz
Algorithm Hash digest
SHA256 abcf7a335d6f6d8f618baf2472e56636afcd7adf78e7be12ea7de9974faf1947
MD5 3a8321eeb84cdbb9b76479e7b05636c4
BLAKE2b-256 7f40773d397831ad64afda4805b04b81b9d7641e70d6898f947c92d5fa8015f8

See more details on using hashes here.

Provenance

The following attestation bundles were made for shannot-0.3.0.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.3.0-py3-none-any.whl.

File metadata

  • Download URL: shannot-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 59.0 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.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c883501c439b95f7760f1ee5945733a57d9b13a19d521c37b2e802e8edf4e60a
MD5 389bdcc0efc759ee4da6fdc9161af2fe
BLAKE2b-256 a49364ed3036286a8837340a3854cea3f9d3dc03fa7e8ed2b54f6d1b322bff7c

See more details on using hashes here.

Provenance

The following attestation bundles were made for shannot-0.3.0-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