AI agent security that makes the dangerous bits structurally impossible.
From the creator of
Sigstore
The standard for secure software attestation, used by PyPI, npm, brew, and Maven Central
Warning
This is an early alpha release that has not undergone comprehensive security audits. While we have taken care to implement robust security measures, there may still be undiscovered issues. We do not recommend using this in production until we release a stable version of 1.0.
Note
🎉 v0.6.1 has shipped! 🎉 we have completed work to separate the CLI from the core library!
AI agents get filesystem access, run shell commands, and are inherently open to prompt injection. The standard response is guardrails and policies. The problem is that policies can be bypassed and guardrails linguistically overcome.
Kernel-enforced sandboxing (Landlock/Seatbelt) blocks unauthorized access at the syscall level. Every filesystem change gets a rollback snapshot with integrity protection. Destructive commands are denied before they run. Secrets are injected without touching disk. When the agent needs access outside its permissions, a kernel-mediated supervisor intercepts the syscall via seccomp BPF, opens the file after user approval, and injects only the file descriptor — the agent never executes its own open(). No root or CAP_SYS_ADMIN required. Runs on any Linux kernel 5.13+ — bare metal, containers(Docker,Podman,K8s), Firecracker, Kata.
nono run --profile claude-code -- claude
nono run --read ./src --write ./output -- cargo buildBuilt-in profiles for Claude Code, OpenCode, and OpenClaw — or define your own with custom permissions.
The core is a Rust library that can be embedded into any application via native bindings. The library is a policy-free sandbox primitive -- it applies only what clients explicitly request.
Rust — crates.io
use nono::{CapabilitySet, Sandbox};
let mut caps = CapabilitySet::new();
caps.allow_read("/data/models")?;
caps.allow_write("/tmp/workspace")?;
Sandbox::apply(&caps)?; // Irreversible — kernel-enforced from here on
Python — nono-py
from nono_py import CapabilitySet, AccessMode, apply
caps = CapabilitySet()
caps.allow_path("/data/models", AccessMode.READ)
caps.allow_path("/tmp/workspace", AccessMode.READ_WRITE)
apply(caps) # Apply CapabilitySet
TypeScript — nono-ts
import { CapabilitySet, AccessMode, apply } from "nono-ts";
const caps = new CapabilitySet();
caps.allowPath("/data/models", AccessMode.Read);
caps.allowPath("/tmp/workspace", AccessMode.ReadWrite);
apply(caps); // Irreversible — kernel-enforced from here onnono applies OS-level restrictions that cannot be bypassed or escalated from within the sandboxed process. Permissions are defined as capabilities granted before execution -- once the sandbox is applied, it is irreversible. All child processes inherit the same restrictions.
| Platform | Mechanism | Minimum Kernel |
|---|---|---|
| macOS | Seatbelt | 10.5+ |
| Linux | Landlock | 5.13+ |
# Grant read to src, write to output — everything else is denied by the kernel
nono run --read ./src --write ./output -- cargo buildTwo modes: proxy injection keeps credentials entirely outside the sandbox — the agent connects to localhost and the proxy injects real API keys into upstream requests. Env injection loads secrets from the OS keystore or 1Password and injects them as environment variables before the sandbox locks.
# Proxy mode — agent never sees the API key, even in its own memory
nono run --network-profile claude-code --proxy-credential openai -- my-agent
# Env mode — simpler, but secret is in the process environment
nono run --env-credential openai_api_key --allow-cwd -- my-agent
# 1Password — use op:// URIs with an explicit env var name
nono run --env-credential 'op://Development/OpenAI/credential=OPENAI_API_KEY' --allow-cwd -- my-agentInstruction files (SKILLS.md, CLAUDE.md, AGENT.MD) and associated artifacts such as scripts are a supply chain attack vector. nono cryptographically signs and verifies them using Sigstore attestation with DSSE envelopes and in-toto / SLSA style statements. It supports keyed signing (system keystore) and keyless signing (OIDC via GitHub Actions + Fulcio + Rekor). Upon execution, nono verifies the signature, checks the signing certificate against trusted roots, and validates the statement predicates (e.g. signed within the last 30 days, signed by a trusted maintainer).
Sign instruction files directly within GitHub Actions workflows. Users can then verify that files originate from the expected repository and branch, signed by a trusted maintainer.
Allowlist-based host filtering via a local proxy. The sandbox blocks all direct outbound connections — the agent can only reach explicitly allowed hosts. Cloud metadata endpoints and private network ranges are hardcoded as denied. DNS rebinding protection checks resolved IPs against the deny list before connecting.
nono run --supervised --proxy-allow api.openai.com --proxy-allow api.anthropic.com -- my-agentOn Linux, seccomp user notification intercepts syscalls when the agent needs access outside its sandbox. The supervisor prompts the user, then injects the file descriptor directly — the agent never executes its own open(). Sensitive paths are never-grantable regardless of approval.
nono run --rollback --supervised --allow-cwd -- claudeContent-addressable snapshots of your working directory taken before and during sandboxed execution. SHA-256 deduplication and Merkle tree commitments for integrity verification. Interactively review and restore individual files or the entire directory. Known regenerable directories (.git, target, node_modules, etc.) and directories with more than 10,000 files are auto-excluded from snapshots to prevent hangs on large projects.
# Zero-flag usage — auto-excludes large/regenerable directories
nono run --rollback --allow-cwd -- npm test
# Force-include an auto-excluded directory
nono run --rollback --rollback-include target -- cargo build
# Exclude a custom directory from rollback
nono run --rollback --rollback-exclude vendor -- go test ./...
# Disable rollback entirely
nono run --no-rollback --allow-cwd -- npm test
nono rollback list
nono rollback restoreSecurity policy defined as named groups in a single JSON file. Profiles reference groups by name — compose fine-grained policies from reusable building blocks.
{
"deny_credentials": {
"deny": { "access": ["~/.ssh", "~/.gnupg", "~/.aws", "~/.kube"] }
},
"node_runtime": {
"allow": { "read": ["~/.nvm", "~/.fnm", "~/.npm"] }
}
}Dangerous commands (rm, dd, chmod, sudo, scp) are blocked before execution. Selectively allow or block additional commands per invocation.
$ nono run --allow-cwd -- rm -rf /
nono: blocked command: rmWarning
Command blocking is defense-in-depth layered on top of the kernel sandbox. Commands can bypass this via sh -c '...' or wrapper scripts — the sandbox filesystem restrictions are the real security boundary.
Every session records command, timing, exit code, tracked paths, and cryptographic snapshot commitments as structured JSON.
nono audit show 20260216-193311-20751 --jsonbrew tap always-further/nono
brew install nonoNote
The package is not in homebrew official yet, give us a star to help raise our profile for when we request approval.
See the Installation Guide for prebuilt binaries and package manager instructions.
See the Development Guide for building from source.
nono ships with built-in profiles for popular AI coding agents. Each profile defines audited, minimal permissions.
| Client | Profile | Docs |
|---|---|---|
| Claude Code | claude-code |
Guide |
| OpenCode | opencode |
Guide |
| OpenClaw | openclaw |
Guide |
nono is agent-agnostic and works with any CLI command. See the full documentation for usage details, configuration, and integration guides.
| Project | Repository |
|---|---|
| claw-wrap | GitHub |
nono is structured as a Cargo workspace:
- nono (
crates/nono/) -- Core library. A policy-free sandbox primitive that applies only what clients explicitly request. - nono-cli (
crates/nono-cli/) -- CLI binary. Owns all security policy, profiles, hooks, and UX. - nono-ffi (
bindings/c/) -- C FFI bindings with auto-generated header.
Language-specific bindings are maintained separately:
| Language | Repository | Package |
|---|---|---|
| Python | nono-py | PyPI |
| TypeScript | nono-ts | npm |
We encourage using AI tools to contribute to nono. However, you must understand and carefully review any AI-generated code before submitting. The security of nono is paramount -- always review and test your code thoroughly, especially around core sandboxing functionality. If you don't understand how a change works, please ask for help in the Discord before submitting a PR.
If you discover a security vulnerability, please do not open a public issue. Instead, follow the responsible disclosure process outlined in our Security Policy.
Apache-2.0