Skip to main content
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 used for visual clarity, to help the reader distinguish between nono flags and the command being run. It’s not strictly required if there are no flag conflicts, but we recommend using it consistently to avoid ambiguity.
Anything which is a process, can be run inside a nono sandbox - CLI tools, scripts, even interactive shells. The sandbox is applied to the entire process tree, so any child processes will also be restricted by the same permissions.

Pre-Built Profiles

To get you going quickly, we provide pre-built profiles for popular AI agents and tools. These profiles bundle the right permissions for each tool, so you can get up and running with a single command. Just search for your favorite coding agent from the registry
nono search opencode
always-further/opencode	-	Official Always Further Opencode Plugin
And then run..
nono run --profile always-further/claude -- claude
nono run --profile always-further/codex -- codex
nono run --profile always-further/pi -- pi

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 Policy Access (nono why)

The why command checks if a filesystem path, network operation, kernel scope, or Tool Sandbox command invocation 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",...}

# Check an Tool Sandbox  command/argv policy denial
nono why --profile gh --command gh -- issue comment 1052
# Output: DENIED - agents may read issues but not comment on them

# From inside a sandbox, query own capabilities
nono run --allow-cwd -- nono why --self --path /tmp --op write --json
FlagDescription
--commandTool-sandbox command name to check
--callerCommand-policy caller edge (default: session)
--pathFilesystem path to check
--opOperation: read, write, or readwrite (default: read)
--hostNetwork host to check (instead of --path)
--portNetwork port (default: 443)
--jsonOutput JSON for programmatic use
--selfQuery 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

  1. Parse — nono parses your capability flags
  2. Canonicalize — All paths are resolved to absolute paths (prevents symlink escapes)
  3. Apply Sandbox — Kernel sandbox is initialized (irreversible)
  4. Fork & Execute — nono forks a sandboxed child process and runs your command inside it. The unsandboxed parent stays alive for audit recording, rollback, and diagnostics.
  5. 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 the agent you want to use cannot be found, create an issue to request consideration for adding it to the registry, or fork an existing profile and submit a PR with the new agent profile. See Package Publishing for details on publishing profiles.

Build your own profile

It’s likely that you are going to want to customize the pre-built profiles or create your own for different tools and needs. You can do this easily with nono profile init which will create a new profile based on an existing one, with the option to customize it interactively.
nono profile init claude --extends always-further/claude --full

nono profile Created profile at /Users/jdoe/.config/nono/profiles/claude.json
nono profile Validate with: nono profile validate claude
nono profile For editor autocomplete: nono profile schema -o nono-profile.schema.json
You can now call your own profile with --profile claude just like the pre-built ones. From here, move to Profiles & Groups for more indepth details on how to create and manage profiles, groups, and the policy engine.

Next Steps