Core Principle
Deny by default, allow explicitly. When you run a command through nono, it can only access what you explicitly grant. Everything else is blocked at the kernel level.Trust Boundaries
What nono Protects Against
Path Traversal Attacks
An agent cannot use../ sequences to escape allowed directories:
Symlink Escapes
Paths are canonicalized at grant time. An agent cannot create a symlink pointing outside the sandbox:Credential Theft
Sensitive paths are blocked by default, even if a parent directory is allowed:~/.ssh/- SSH keys~/.aws/- AWS credentials~/.gnupg/- GPG keys~/.kube/- Kubernetes config- Shell history and config files
- And more…
Network Exfiltration
Network is allowed by default. Use--net-block to completely disable network access and prevent an agent from making any outbound connections.
Privilege Escalation
The sandbox is applied before exec(). There is no window where the agent runs with elevated privileges.Child Process Escape
All child processes inherit the sandbox. An agent cannot spawn an unrestricted subprocess.What nono Does NOT Protect Against
Kernel Exploits
If the kernel itself has a vulnerability, an attacker with code execution could potentially escape the sandbox. This is true of any sandboxing solution.Covert Channels
An agent could potentially leak small amounts of information through timing side channels, CPU usage patterns, etc. nono does not attempt to prevent covert channels.Resource Exhaustion
nono does not limit CPU, memory, or disk usage. A malicious agent could attempt denial-of-service through resource exhaustion.Data Within Allowed Paths
If you grant access to a directory, the agent can read/write anything in that directory. nono cannot protect files within allowed paths.TOCTOU Races
There is a small window between path canonicalization and sandbox application where a time-of-check-time-of-use race could theoretically occur. This window is minimized but not eliminated.Sensitive Path Protection
nono blocks access to sensitive paths by default, even if a parent directory is explicitly allowed:| Path | Contains |
|---|---|
~/.ssh/ | SSH private keys |
~/.aws/ | AWS credentials |
~/.gnupg/ | GPG private keys |
~/.kube/ | Kubernetes credentials |
~/.docker/ | Docker credentials |
~/.npmrc | npm auth tokens |
~/.netrc | Network credentials |
~/.gitcredentials | Git credentials |
~/.bash_history | Command history |
~/.zsh_history | Command history |
~/.bashrc, ~/.zshrc | Shell configs (may contain secrets) |
Security Properties
Irreversibility
Once the sandbox is applied, there is no API to expand or remove it. Not even nono itself can undo the restrictions.Fail-Closed
If sandbox initialization fails, nono exits with an error rather than running the command unrestricted.Minimal Attack Surface
nono applies the sandbox and immediately exec()s into the target command. It does not remain running as a supervisor (in Phase 1).Best Practices
- Grant minimal access - Only allow what the command actually needs
- Use read-only where possible - Use
--readinstead of--allowfor source directories - Block network when not needed - Use
--net-blockfor offline operations like builds or tests - Test with dry-run - Use
--dry-runto preview capabilities before execution - Review agent output - Even sandboxed agents can produce malicious output files
Next Steps
- macOS Seatbelt - How nono uses Seatbelt on macOS
- Linux Landlock - How nono uses Landlock on Linux
- Why OS-Level Controls - Why kernel enforcement beats application-level controls
