nono wraps any command with an OS-level sandbox. You specify what the command is allowed to access, and nono enforces those restrictions at the kernel level.
Your First Sandbox
nono run --allow . -- <COMMAND> [ARGS...]
The -- separator is recommended. Everything after it is the command to run.
# Grant read+write access to current directory, run claude
nono run --allow . -- claude
Or use a built-in profile that bundles the right permissions for a known tool:
nono run --profile claude-code -- claude
nono run --profile codex -- codex
See Profiles & Groups for all built-in profiles and how to create your own.
Commands
| Command | Description |
|---|
nono run | Run a command inside the sandbox (supervised, default) |
nono shell | Start an interactive shell inside the sandbox |
nono wrap | Apply sandbox and exec into command (no parent process, minimal overhead) |
nono why | Check why a path/network operation would be allowed or denied |
nono rollback | Manage rollback sessions - list, show, restore, verify, cleanup snapshots |
nono audit | View audit trail - list and inspect past sandboxed sessions |
nono learn | Discover required paths - trace a command to find what it accesses |
nono trust | Manage instruction file trust - sign, verify, and manage attestation |
nono setup | System setup and verification - generate profiles, check shell integration |
Permissions
nono provides three levels of filesystem access:
| Flag | Access Level | Use Case |
|---|
--allow / -a | Read + Write | Working directories, project folders |
--read / -r | Read Only | Source code, configuration |
--write / -w | Write Only | Output directories, logs |
Directory flags (--allow, --read, --write) grant recursive access. File flags (--allow-file, --read-file, --write-file) grant access to a single file.
# Recursive access to entire directory
nono run --allow ./project -- command
# Access to single config file only
nono run --read-file ./config.toml -- command
Network Access
Network is allowed by default. Use --block-net to disable outbound connections:
nono run --allow . --block-net -- cargo build
For granular control, use --network-profile for host-level filtering or --open-port for localhost IPC between sandboxes:
# Host-level filtering via proxy
nono run --allow . --network-profile claude-code -- my-agent
# Allow specific domains through the proxy
nono run --allow . --allow-domain api.openai.com -- my-agent
# Localhost IPC (e.g., MCP server on port 3000)
nono run --block-net --open-port 3000 --allow . -- my-agent
See Networking and CLI Reference for details.
Interactive Shell (nono shell)
Start a shell with the same sandbox permissions as nono run:
# Shell with access only to current directory
nono shell --allow .
# Shell with a named profile
nono shell --profile claude-code
# Override the shell binary
nono shell --allow-cwd --shell /bin/zsh
Exit the shell with Ctrl-D or exit.
Checking Path Access (nono why)
The why command checks if a path or network operation would be allowed or denied. It’s designed for both human debugging and programmatic use by AI agents.
# Check if a sensitive path would be blocked
nono why --path ~/.ssh/id_rsa --op read
# Output: DENIED - sensitive_path (SSH keys and config)
# Check with capability context
nono why --path ./src --op write --allow .
# Output: ALLOWED - Granted by: --allow .
# JSON output for AI agents
nono why --json --path ~/.aws --op read
# {"status":"denied","reason":"sensitive_path","category":"AWS credentials",...}
# From inside a sandbox, query own capabilities
nono run --allow-cwd -- nono why --self --path /tmp --op write --json
| Flag | Description |
|---|
--path | Filesystem path to check |
--op | Operation: read, write, or readwrite (default: read) |
--host | Network host to check (instead of --path) |
--port | Network port (default: 443) |
--json | Output JSON for programmatic use |
--self | Query current sandbox state (inside sandbox) |
This is particularly useful for AI agents - when an operation fails, the agent can call nono why --self to get a structured JSON response explaining why and how to fix it.
What Happens at Runtime
- Parse - nono parses your capability flags
- Canonicalize - All paths are resolved to absolute paths (prevents symlink escapes)
- Apply Sandbox - Kernel sandbox is initialized (irreversible)
- Execute - nono exec()s into your command, inheriting the sandbox
- Enforce - Kernel blocks any unauthorized access attempts
Sensitive Paths
The following paths are always blocked by default to protect credentials:
~/.ssh - SSH keys
~/.aws, ~/.gcloud, ~/.azure - Cloud credentials
~/.gnupg - GPG keys
~/.kube, ~/.docker - Container credentials
~/.zshrc, ~/.bashrc, ~/.profile - Shell configs (often contain secrets)
~/.npmrc, ~/.git-credentials - Package manager tokens
Use nono why --path <path> --op read to check if a specific path is blocked and why. See Profiles & Groups for the full list and how group policy controls these.
Agent Integration
For setting up nono with a specific AI agent:
If there is an Agent you want supported please open an issue or PR to add it!
Next Steps