Skip to main content

Python bindings for nono capability-based sandboxing

Project description

nono-py

Python bindings for nono, a capability-based sandboxing library.

nono provides OS-enforced sandboxing using Landlock (Linux) and Seatbelt (macOS). Once a sandbox is applied, unauthorized operations are structurally impossible.

Installation

pip install nono-py

From source

Requires Rust toolchain and maturin:

pip install maturin
maturin develop

Usage

from nono_py import CapabilitySet, AccessMode, apply, is_supported

# Check platform support
if not is_supported():
    print("Sandboxing not supported on this platform")
    exit(1)

# Build capability set
caps = CapabilitySet()
caps.allow_path("/tmp", AccessMode.READ_WRITE)
caps.allow_path("/home/user/project", AccessMode.READ)
caps.allow_file("/etc/hosts", AccessMode.READ)
caps.block_network()

# Apply sandbox (irreversible!)
apply(caps)

# Now the process can only access granted paths
# Network access is blocked
# This applies to all child processes too

API Reference

Sandboxing

CapabilitySet + apply()

Sandbox the current process (irreversible):

caps = CapabilitySet()
caps.allow_path("/tmp", AccessMode.READ_WRITE)
caps.block_network()
apply(caps)  # Process is now sandboxed

sandboxed_exec

Run a command in a sandboxed child process. The parent stays unsandboxed and can call this repeatedly with different capabilities:

caps = CapabilitySet()
caps.allow_path("/workspace", AccessMode.READ_WRITE)
caps.block_network()
result = sandboxed_exec(caps, ["python", "agent.py"], cwd="/workspace", timeout_secs=30.0)
print(result.stdout, result.exit_code)

Network Proxy

Domain-filtered network access for sandboxed children. The proxy intercepts outbound HTTP requests and enforces a host allowlist. For API calls, it performs credential injection: the sandboxed process sends a dummy token, and the proxy transparently swaps in the real API key (loaded from the OS keyring) before forwarding upstream. The sandboxed process never sees the real secret.

from nono_py import ProxyConfig, RouteConfig, start_proxy

config = ProxyConfig(
    allowed_hosts=["api.openai.com", "*.anthropic.com"],
    routes=[
        RouteConfig(prefix="/openai", upstream="https://api.openai.com", credential_key="openai-key"),
    ],
)
proxy = start_proxy(config)

# Inject proxy env vars into sandboxed child
env = list(proxy.env_vars().items()) + list(proxy.credential_env_vars().items())
result = sandboxed_exec(caps, ["python", "agent.py"], env=env)

# Audit trail
events = proxy.drain_audit_events()
proxy.shutdown()

Filesystem Snapshots

Content-addressable snapshots with Merkle-committed state and rollback:

from nono_py import SnapshotManager, ExclusionConfig

mgr = SnapshotManager(
    session_dir="~/.nono/rollbacks/session-001",
    tracked_paths=["/workspace"],
    exclusion=ExclusionConfig(exclude_patterns=["node_modules", "__pycache__"]),
)
mgr.create_baseline()

# ... agent runs and modifies files ...

manifest, changes = mgr.create_incremental()
for change in changes:
    print(f"{change.change_type}: {change.path}")

# Roll back
mgr.restore_to(snapshot_number=0)

Other Classes

  • QueryContext - Check permissions without applying the sandbox
  • SandboxState - Serialize/restore capability sets as JSON
  • SupportInfo - Platform support details
  • Policy - Load and resolve policy.json documents
  • SessionMetadata - Session audit trail with Merkle roots and network events

Functions

  • apply(caps) - Apply sandbox (irreversible)
  • sandboxed_exec(caps, command, ...) - Run command in sandboxed child
  • start_proxy(config) - Start network filtering proxy
  • is_supported() / support_info() - Platform support
  • load_policy(json) / load_embedded_policy() - Policy loading

Platform Support

Platform Backend Requirements
Linux Landlock Kernel 5.13+ with Landlock enabled
macOS Seatbelt macOS 10.5+
Windows - Not supported

Development

# Install dev dependencies
pip install maturin pytest mypy

# Build and install for development
make dev

# Run tests
make test

# Run linters
make lint

# Format code
make fmt

License

Apache-2.0

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

nono_py-0.8.0.tar.gz (155.1 kB view details)

Uploaded Source

Built Distributions

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

nono_py-0.8.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.6 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

nono_py-0.8.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.4 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ ARM64

nono_py-0.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.6 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

nono_py-0.8.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.4 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARM64

nono_py-0.8.0-cp312-cp312-macosx_11_0_arm64.whl (3.0 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

nono_py-0.8.0-cp312-cp312-macosx_10_12_x86_64.whl (3.3 MB view details)

Uploaded CPython 3.12macOS 10.12+ x86-64

nono_py-0.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.6 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

nono_py-0.8.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.4 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ ARM64

nono_py-0.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.6 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

nono_py-0.8.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.4 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ ARM64

nono_py-0.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.6 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ x86-64

nono_py-0.8.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.4 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ ARM64

File details

Details for the file nono_py-0.8.0.tar.gz.

File metadata

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

File hashes

Hashes for nono_py-0.8.0.tar.gz
Algorithm Hash digest
SHA256 c02294b83b541023b704c36fddafb47f6746cdbf686429d6f1e259bc2b09758c
MD5 300b481cd00e207e1d41170e8e99d624
BLAKE2b-256 0ebf4d3b645e3d6a01f8ab70bd8fb707572423be74949dac4ceaad695ffc5a7a

See more details on using hashes here.

Provenance

The following attestation bundles were made for nono_py-0.8.0.tar.gz:

Publisher: publish.yml on always-further/nono-py

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

File details

Details for the file nono_py-0.8.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for nono_py-0.8.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 8254f78a9e93193b765185cff6c378923f053a67cf08c3ba56be69c37fe1d952
MD5 a8f8654b771a6f1a010d164afe313d32
BLAKE2b-256 c019b9bc4f99c1752cfec364761395ec0d89930eaff902f01ea1a5b78d1d24a9

See more details on using hashes here.

Provenance

The following attestation bundles were made for nono_py-0.8.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish.yml on always-further/nono-py

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

File details

Details for the file nono_py-0.8.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for nono_py-0.8.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 6c39864a151e5ff88f03d5b8462976b119ba77509b5569ac8c3f7f51e04369ec
MD5 e99ee3608198c6312d3d4f168197d52c
BLAKE2b-256 3027c66b69bcdbc788d4cace88191f7203e203e4d297f10b981b6d24052f9fa1

See more details on using hashes here.

Provenance

The following attestation bundles were made for nono_py-0.8.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: publish.yml on always-further/nono-py

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

File details

Details for the file nono_py-0.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for nono_py-0.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 9cbe029f6801efbad63272c7aa7adc2cbcd4d28efa1bc0e752f4a9600e150dba
MD5 87fe0ece45deae9012c89c447acf7b7c
BLAKE2b-256 4e39757c200b7e8c62a3817e7668ee5341ae9cc389866c5344b60f3844da617a

See more details on using hashes here.

Provenance

The following attestation bundles were made for nono_py-0.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish.yml on always-further/nono-py

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

File details

Details for the file nono_py-0.8.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for nono_py-0.8.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 5ef8182f18241ce68f2c5c1edbc16e8ff8c573d7bf6bd53d6989dc86551da3f3
MD5 9814d978f4bd22d0817005cfbe6c9eb0
BLAKE2b-256 b5026a8eac089ec2b17a4b32c8a789e0768c15cec5a1d5a4f6f9feb0c019b802

See more details on using hashes here.

Provenance

The following attestation bundles were made for nono_py-0.8.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: publish.yml on always-further/nono-py

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

File details

Details for the file nono_py-0.8.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for nono_py-0.8.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 2da548f3cbfd66f96c5533e87bbcad9dae6bee955ad77a7153da6f3a17e19f6d
MD5 68478b04e61d50001c1980e8f9b53b6b
BLAKE2b-256 1128352b21241d6861400ed6fa34dbf8a9a4a05ed7b7c4e4d17c2bdd23c43996

See more details on using hashes here.

Provenance

The following attestation bundles were made for nono_py-0.8.0-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: publish.yml on always-further/nono-py

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

File details

Details for the file nono_py-0.8.0-cp312-cp312-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for nono_py-0.8.0-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 56da5802b4b3b8cf3a3ba0ea38acb8589e4fc818393d3e467b47c99404e3d041
MD5 b0109cfc581f4917bb0d1062d89a388c
BLAKE2b-256 061dc859e93e79ca869d225b619cd7bfb2bb28a8e8ed39c32153559000d85058

See more details on using hashes here.

Provenance

The following attestation bundles were made for nono_py-0.8.0-cp312-cp312-macosx_10_12_x86_64.whl:

Publisher: publish.yml on always-further/nono-py

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

File details

Details for the file nono_py-0.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for nono_py-0.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 f837a8b7fde3ddb2242bde15fbd20d80f3ee77ba04f10f3127850b67e5928314
MD5 15194f8e1e0d7202748eb06e03ec9e45
BLAKE2b-256 87ed4a93182d593dfa208554455e8ad16c77dcb04976b4a4eb5152b7c9651e6f

See more details on using hashes here.

Provenance

The following attestation bundles were made for nono_py-0.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish.yml on always-further/nono-py

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

File details

Details for the file nono_py-0.8.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for nono_py-0.8.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 a6fa0d18bdbb210da12d0dc1ec40649e551d5fbf167ea3687be747defed9b45f
MD5 1f3e39346b0a72e5374de45bb5817ab9
BLAKE2b-256 95dea35bbb955abdc2e4ca1d190e2ca5276325c99dfed33079bf1713bfc70b50

See more details on using hashes here.

Provenance

The following attestation bundles were made for nono_py-0.8.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: publish.yml on always-further/nono-py

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

File details

Details for the file nono_py-0.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for nono_py-0.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 8dd5220a5e3d1037a98148134cde7572409e15c2effafd103b69ab4797b27fc3
MD5 74e67f24e3739400a1f850f58285d117
BLAKE2b-256 536135aab23bb294d972489f136ee7828d8c5e027155cffb2f3ee6d06eb2451d

See more details on using hashes here.

Provenance

The following attestation bundles were made for nono_py-0.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish.yml on always-further/nono-py

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

File details

Details for the file nono_py-0.8.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for nono_py-0.8.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 6c18c98fdcd3fbdef7199747961a76f8b6b95e358f18c673f0ee598e1c9bf561
MD5 ba72949632a26f6e2cdadf2d9322eab8
BLAKE2b-256 72289ed0d7b0fc20a55a01c8c5570d4b79f4408b985a71c2d49af6073a412760

See more details on using hashes here.

Provenance

The following attestation bundles were made for nono_py-0.8.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: publish.yml on always-further/nono-py

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

File details

Details for the file nono_py-0.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for nono_py-0.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 e99478b95c3b447c62c63274de4f5fee0ba6ec9a4021755aa3720324f7438381
MD5 d592cbf3bef01ddcab2605513c9a1c3c
BLAKE2b-256 31af8016a209266af54c6fe82b7b3c4e44a744202dbe9127a801993f88d69b0d

See more details on using hashes here.

Provenance

The following attestation bundles were made for nono_py-0.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish.yml on always-further/nono-py

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

File details

Details for the file nono_py-0.8.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for nono_py-0.8.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 501a5510dfe47001dfd2e54a1786178fc9b03cabe53ce4a319cee3c36ee9705f
MD5 0cc232ef2f2637bc56d74b98df0f3db0
BLAKE2b-256 b2e783a6c9744463259b796a8823a3e9ead12d2bb06eb571d21e1ef4a1dd2046

See more details on using hashes here.

Provenance

The following attestation bundles were made for nono_py-0.8.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: publish.yml on always-further/nono-py

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