Skip to content

always-further/nono

Repository files navigation

nono logo

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

License CI Status Documentation

Join Discord nono-attest GitHub Action

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.

CLI

nono run --profile claude-code -- claude
nono run --read ./src --write ./output -- cargo build

Built-in profiles for Claude Code, OpenCode, and OpenClaw — or define your own with custom permissions.

Library

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 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 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 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 on

Features

Kernel-Enforced Sandbox

nono 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 build

Credential Injection

Two 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-agent

Agent SKILL Provenance and Supply Chain Security

Instruction 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).

nono-attest GitHub Action

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.

Network Filtering

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-agent

Supervisor and Capability Expansion

On 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 -- claude

Undo and Snapshots

Content-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 restore

Composable Policy Groups

Security 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"] }
  }
}

Destructive Command Blocking

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: rm

Warning

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.

Audit Trail

Every session records command, timing, exit code, tracked paths, and cryptographic snapshot commitments as structured JSON.

nono audit show 20260216-193311-20751 --json

Quick Start

macOS

brew tap always-further/nono
brew install nono

Note

The package is not in homebrew official yet, give us a star to help raise our profile for when we request approval.

Linux

See the Installation Guide for prebuilt binaries and package manager instructions.

From Source

See the Development Guide for building from source.

Supported Clients

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.

Projects using nono

Project Repository
claw-wrap GitHub

Architecture

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

Contributing

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.

Security

If you discover a security vulnerability, please do not open a public issue. Instead, follow the responsible disclosure process outlined in our Security Policy.

License

Apache-2.0

About

Secure, kernel-enforced sandbox CLI and SDKs for AI agents. Capability-based isolation with secure key management, atomic rollback, cryptographic immutable audit chain of provenance. Run your agents in a zero-trust environment.

Topics

Resources

License

Stars

Watchers

Forks

Packages