39 releases (breaking)
| new 0.39.0 | Apr 21, 2026 |
|---|---|
| 0.37.1 | Apr 17, 2026 |
| 0.26.1 | Mar 31, 2026 |
#1481 in Development tools
33 downloads per month
3MB
64K
SLoC
nono-cli
CLI for capability-based sandboxing using Landlock (Linux) and Seatbelt (macOS).
Installation
Homebrew (macOS/Linux)
brew install nono
Cargo
cargo install nono-cli
From Source
git clone https://github.com/always-further/nono
cd nono
cargo build --release
Usage
# Allow read+write to current directory
nono run --allow . -- command
# Separate read and write permissions
nono run --read ./src --write ./output -- cargo build
# Multiple paths
nono run --allow ./project-a --allow ./project-b -- command
# Block network access
nono run --allow-cwd --block-net -- command
# Use a built-in profile
nono run --profile claude-code -- claude
# Use the Codex profile
nono run --profile codex -- codex
# Keep a profile but temporarily allow unrestricted network
nono run --profile claude-code --allow-net -- claude
# Start an interactive shell inside the sandbox
nono shell --allow .
# Check why a path would be blocked
nono why --path ~/.ssh/id_rsa --op read
# Dry run (show what would be sandboxed)
nono run --allow-cwd --dry-run -- command
Themes
The CLI supports named output themes for banners, summaries, warnings, and status text.
Available themes: mocha, latte, frappe, macchiato, tokyo-night, minimal
# Per invocation
nono --theme tokyo-night run --allow-cwd -- claude
# Environment variable
export NONO_THEME=latte
# Config file
# ~/.config/nono/config.toml
# [ui]
# theme = "frappe"
Precedence is: CLI flag, then NONO_THEME, then config file, then the default mocha.
Built-in Profiles
| Profile | Command |
|---|---|
| Claude Code | nono run --profile claude-code -- claude |
| Claude Code (No Keychain) | nono run --profile claude-no-kc -- claude |
| Codex | nono run --profile codex -- codex |
| OpenCode | nono run --profile opencode -- opencode |
| OpenClaw | nono run --profile openclaw -- openclaw gateway |
| Swival | nono run --profile swival -- swival |
Profile Inheritance
User profiles can extend built-in or other user profiles with the extends field. The child inherits all settings from the base and only declares additions or overrides.
{
"extends": "claude-code",
"meta": { "name": "my-claude" },
"filesystem": {
"allow": ["/opt/my-tools"],
"read": ["/etc/my-app"]
}
}
You can also extend multiple profiles at once. Bases are merged left-to-right, then the child overrides:
{
"extends": ["claude-code", "node-dev"],
"meta": { "name": "my-fullstack" },
"filesystem": { "allow": ["/opt/extra"] }
}
Save to ~/.config/nono/profiles/my-claude.json, then:
nono run --profile my-claude -- claude
Merge semantics
- Lists (filesystem paths, security groups, rollback patterns): appended and deduplicated
- HashMaps (credentials, hooks): merged, child wins on same key
- Booleans (
network.block,interactive): OR — either activates - Scalars (
meta): child overrides - Nullable scalars (
network_profile): absent inherits,nullclears, string overrides
When extending multiple bases, they are merged left-to-right using the same rules. The child then overrides the accumulated base.
Chaining
Profiles can form chains (up to 10 levels deep). Circular dependencies are detected and rejected. Shared transitive bases are deduplicated.
my-dev.json → team-base.json → claude-code (built-in)
Deprecated Command Blocking
Command blocking is deprecated in v0.33.0. It is only checked against the
directly-invoked startup command, not enforced for child processes, and should
not be treated as a sandbox security boundary.
Dangerous commands are still startup-blocked by default in v0.33.x:
| Category | Commands |
|---|---|
| File destruction | rm, rmdir, shred, srm |
| Disk operations | dd, mkfs, fdisk, parted |
| Permission changes | chmod, chown, chgrp |
| Privilege escalation | sudo, su, doas |
Compatibility overrides still exist temporarily:
# Per invocation
nono run --allow-cwd --allow-command rm -- rm ./temp-file.txt
# Via profile
cat > ~/.config/nono/profiles/my-profile.json << 'EOF'
{
"meta": { "name": "my-profile" },
"filesystem": { "allow": ["/tmp"] },
"security": { "allowed_commands": ["rm"] }
}
EOF
nono run --profile my-profile -- rm /tmp/old-file.txt
Prefer resource-based controls instead: narrower filesystem grants,
add_deny_access, unlink_protection, and network policy.
Documentation
License
Apache-2.0
Dependencies
~120MB
~2.5M SLoC