Python SDK

Runtime Safety for Python AI Agents

Enforce kernel-level isolation, network filtering, and atomic rollbacks from Python with nono-py.

pip install nono-py
PyPI →

Secure execution model

nono-py provides Python bindings to nono's core Rust library via PyO3. The SDK exposes four key systems: kernel-level process sandboxing, a network proxy with credential injection, filesystem snapshots with rollback, and a policy engine for composable security profiles.

Two sandboxing modes are available. nono.apply(caps) applies kernel-level restrictions to the current process — irrevocable, inherited by all child processes. nono.sandboxed_exec() runs a command in a sandboxed child process, leaving the parent unsandboxed. Use the first for self-sandboxing agents; use the second for orchestrators that need to spawn isolated workloads.

Full type stubs are included ( py.typed) — mypy, pyright, and IDE autocompletion work out of the box.

Kernel-Level Sandbox

Apply irrevocable filesystem restrictions via Landlock (Linux and Windows) or Seatbelt (macOS). Define per-path access modes — read, write, read-write. Everything not explicitly allowed is denied at the kernel level.

Network Proxy & Credential Injection

Domain-filtered outbound access with per-route credential injection. Supports header, URL path, query parameter, and basic auth injection modes. Real API keys stay outside the sandbox — only phantom tokens enter the process.

Filesystem Snapshots

Content-addressable snapshots with Merkle roots. Create baselines before agent execution, compute diffs after, and roll back to any previous state. Respects .gitignore patterns and custom exclusions.

Sandboxed Child Processes

Run untrusted code in a sandboxed child process via sandboxed_exec(). The parent stays unsandboxed. Set working directory, timeout, and environment variables. Captures stdout and stderr as bytes.

sandbox.py
import nono_py as nono
# Define capabilities — deny by default
caps = nono.CapabilitySet()
caps.allow_path("/project", nono.AccessMode.READ_WRITE)
caps.allow_file("/home/user/.gitconfig", nono.AccessMode.READ)
caps.block_network()
# Apply sandbox (irrevocable — kernel-enforced)
nono.apply(caps)
# Your agent runs sandboxed from here
agent.run()
sandboxed_exec.py
import nono_py as nono
# Run a command in a sandboxed child process
# Parent stays unsandboxed
caps = nono.CapabilitySet()
caps.allow_path("/project", nono.AccessMode.READ_WRITE)
result = nono.sandboxed_exec(
caps,
["python", "untrusted_script.py"],
cwd="/project",
timeout_secs=30,
env=[("API_KEY", "phantom-token-here")]
)
print(result.exit_code)
print(result.stdout.decode())
proxy.py
import nono_py as nono
# Network proxy with credential injection
route = nono.RouteConfig(
prefix="/v1",
upstream="https://api.openai.com",
credential_key="openai_api_key",
inject_mode=nono.InjectMode.HEADER,
inject_header="Authorization",
credential_format="Bearer {credential}"
)
proxy = nono.ProxyConfig(
allowed_hosts=["api.openai.com"],
routes=[route]
)
handle = nono.start_proxy(proxy)
print(f"Proxy on port {handle.port}")
print(handle.env_vars()) # {"HTTP_PROXY": "..."}
print(handle.credential_env_vars()) # phantom tokens
# Drain audit events after the session
events = handle.drain_audit_events()
handle.shutdown()
snapshots.py
import nono_py as nono
# Snapshot the working directory before agent execution
exclusions = nono.ExclusionConfig(
use_gitignore=True,
exclude_patterns=["node_modules", ".next", "__pycache__"]
)
mgr = nono.SnapshotManager("/project", exclusions)
mgr.create_baseline()
# ... agent runs and modifies files ...
mgr.create_incremental()
diff = mgr.compute_restore_diff()
for change in diff:
print(f"{change.change_type}: {change.path}")
# Roll back everything the agent changed
mgr.restore_to(snapshot_number=0)

Core API

CapabilitySet

Builder for filesystem and network rules. allow_path(), allow_file(), block_network(), platform_rule(). Irrevocable after apply().

QueryContext

Dry-run permission checks. query_path() and query_network() test whether access would be allowed before applying the sandbox.

Policy

Load and resolve JSON security profiles. Built-in groups (python_runtime, node_runtime) expand to platform-specific paths. Composable and version-controlled.

ProxyConfig

Network proxy with domain allowlists, per-route credential injection (header, URL, query param, basic auth), and audit event streaming.

SnapshotManager

Content-addressable filesystem snapshots. Baseline, incremental, compute diffs, restore to any point. Merkle root verification.

sandboxed_exec()

Run a command in a sandboxed child process. Set cwd, timeout, env vars. Parent process remains unsandboxed for orchestration.

query.py
import nono_py as nono
# Dry-run permission checks before applying
caps = nono.CapabilitySet()
caps.allow_path("/project", nono.AccessMode.READ_WRITE)
ctx = nono.QueryContext(caps)
result = ctx.query_path("/etc/passwd", nono.AccessMode.READ)
print(result["status"]) # "denied"
print(result["reason"]) # explains why
net = ctx.query_network("api.openai.com", 443)
print(net["status"]) # "denied" (block_network not set, default)

Ship safer agents today