nono
v0.74.0 open-sourcesafe execution paths for agents - zero trust, zero setup, zero latency.
deny_domain:
- "*.ads.example.com"
nono --deny-domain '*.ads.example.com'
case_insensitive_vars: true
allow:
- "AWS_*_SESSION"
- "*_TOKEN"
ambient:
- name: anthropic-oauth
format: "sk-ant-oat01-{}"
# ... other credential fields
nono ps --remote --all --json
nono connect local:host:abc123
{
"command_policies": {
"commands": {
"my-tool": {
"export_env": ["PYTHONPATH"]
}
}
}
}
{
"command_policies": {
"credentials": {
"vault-oidc": {
"type": "proxy",
"upstream": "https://vault.example.com",
"inject_header": "X-Vault-Token",
"credential_format": "Bearer {}"
}
},
"commands": {
"vault": {
"from": {
"session": {
"sandbox": {
"open_port": 8250,
"credentials": [{ "name": "vault-oidc" }]
},
"invocation_policy": {
"default": "deny",
"allow": [
{ "argv": { "prefix": ["login", "-method=oidc"] } }
]
}
}
}
}
}
}
} Summary
nono is an open-source, Apache 2.0-licensed sandbox for running AI coding agents — Claude Code, Codex, Copilot, OpenCode and similar tools — with least-privilege isolation and no daemon, container, or VM to set up. It runs as a command-line tool on macOS, Linux, and Windows (WSL2), and is aimed at developers and platform teams who need to let AI agents execute and touch the network without giving them free rein: profiles can restrict egress to specific domains, methods, and paths, intercept and inspect proxied TLS traffic, and control which environment variables or credentials an agent session can see. It's built by the team behind Sigstore, which the README notes as prior work rather than a direct comparison, placing nono in the broader AI-agent security and sandboxing space. Development is active, with 98 contributors, over 1,700 commits in the past year, and a release 21 days ago.
safe execution paths for agents - zero trust, zero setup, zero latency.
What nono answers
Does it slow down or add friction to an agent session that's already running?
traffic goes through a local proxy that intercepts and inspects TLS inline, adding no daemon or background process to manage
What happens when an agent tries to reach a domain or path that isn't allowed?
the request is denied and shown in the output as a suppressed denial, with an interactive picker to allow it afterward instead of hand-editing config
Can it stop an agent from reading credentials it shouldn't have?
environment variables and credentials are opt-in per profile, with a deny list for specific variables and no credential access enabled by default
Will this work in a locked-down CI runner or minimal Linux image?
it drops the daemon-bus dependency Linux builds used to need and ships RPM packages, and it detects CI automatically so it won't hang waiting on keychain prompts or show update nagging
How do I keep the same policy across many machines or repos without copying files?
profiles can extend a shared entry pulled from a registry reference instead of a local copy, so one definition applies everywhere
Can I let an agent call AWS APIs without handing it real credentials?
outbound AWS calls can be authenticated through the built-in proxy, so the agent never holds the actual keys
Examples
Command line
No option matches that search.
| option | found in | since | description |
|---|
No option matches that search.
Values are placeholders taken from each option’s declared default. Nothing is executed here — the output shown is a recording of a run that already happened.
Release history
- docs update
nono adds
deny_domainconfig key and--deny-domainCLI flag with three wildcard forms for fine-grained proxy blocking.└──▷ USE ITBlock ad-serving subdomains as an exception inside a broad allow rule, using the config file.deny_domain: - "*.ads.example.com"
Override the deny list on the fly from the CLI to block a specific subdomain pattern without editing the profile.$ nono --deny-domain '*.ads.example.com'
- ›Adds
deny_domainconfig key to block specific hosts through the proxy before the allowlist is checked, letting it carve exceptions out of broad network profile entries. - ›Adds
--deny-domainCLI flag as the command-line equivalent of thedeny_domainconfig key. - ›Supports three wildcard forms in
deny_domainentries: a bare wildcard matches any host; a leading*(e.g.*.example.com) matches one or more subdomain labels but not the apex; and a mid-pattern*occupying a whole label (e.g.jenkins.*.ci.example.com) matches exactly one label at that position. - ›
deny_domainis additive across profile inheritance, accumulating entries from parent profiles.
- ›Adds
- docs update
nono adds wildcard pattern matching and
case_insensitive_varsfor environment variable filtering in profiles└──▷ USE ITAllow only AWS session vars and any token vars into a command, matching case-insensitively so bothgh_tokenandGH_TOKENare accepted.case_insensitive_vars: true allow: - "AWS_*_SESSION" - "*_TOKEN"
- ›Adds
case_insensitive_vars: trueconfig key to match environment variable patterns case-insensitively (ASCII only), so patterns like'gh_token'matchGH_TOKEN,Gh_Token, etc. - ›Supports wildcard
*patterns anywhere in environment variable allow/block rules — leading ('*_TOKEN'), trailing ('AWS_*'), middle ('AWS_*_SESSION'), or substring ('*SECRET*') — while a pattern with no*requires an exact full-name match. - ›Makes
case_insensitive_vars: truesticky acrossextends: once a base profile sets it, child profiles cannot silently revert it to false. - ›Rejects malformed patterns — empty strings or patterns containing a NUL byte — at profile load time rather than silently ignoring them at runtime.
- ›Adds
- docs update
nono tool-sandbox ambient credentials gain a
formatfield to shape phantom token prefixes for picky clients└──▷ USE ITWhen a consuming client (e.g. an Anthropic SDK) sniffs the token prefix and rejects bare phantoms, declare aformaton the ambient credential so issued phantoms look like real Anthropic OAuth tokens.ambient: - name: anthropic-oauth format: "sk-ant-oat01-{}" # ... other credential fields- ›Adds
formatto ambient credential declarations in the tool-sandbox config: a literal template with exactly one{}placeholder (e.g."sk-ant-oat01-{}") that wraps the phantom's 64-hex body, so clients that classify tokens by prefix accept the phantom — the template is stripped on egress so the real credential is never exposed. - ›
formatis rejected on non-ambient credentials, when the value contains control characters, or when the minting rule also setsshape: "jwt".
- ›Adds
- v0.74.0
nono v0.74.0 adds remote session connect/ps, subtool audit surfacing, export_env pass-through, and configurable approval backends
└──▷ GET THIS VERSION$ git clone --branch v0.74.0 https://github.com/nolabs-ai/nono.git # already have the repo? check out this version: $ git checkout v0.74.0
└──▷ TRY ITList all live and exited sessions running on the enrolled nono-console tenant, in JSON for scripting or SIEM ingestion.$ nono ps --remote --all --json
Attach your terminal directly to a specific remote session by its global session ID, useful for live incident inspection.$ nono connect local:host:abc123Allow a sandboxed tool to forward a specific interpreter env var (e.g. PYTHONPATH) to child processes it spawns, without opening the full allow_vars list.{ "command_policies": { "commands": { "my-tool": { "export_env": ["PYTHONPATH"] } } } }- ›Adds
nono connectsubcommand to attach a local terminal to a session hosted by nono-console, withnono connectfor interactive discovery ornono connect <session-id>to attach directly by global session ID. - ›Extends
nono pswith--remoteflag to list sessions hosted by the enrolled tenant's nono-console, combinable with--alland--jsonfor full remote session visibility. - ›Adds
export_envto tool-sandbox command policy config, letting callers declare specific environment variables to pass through to child tools verbatim, bypassing theallow_varsblocklist — supports exact names, trailing-*prefixes, or bare*. - ›Adds
session_export_envkey tocommand_policiesconfig for declaring env pass-through when the resolved caller is the session itself rather than a mediated command. - ›Adds configurable approval backend for supervised-mode prompts via the profile's
approval_backendsandapproval_defaultsconfig fields.
+2 moreshow less
- ›Surfaces subtool audit events in
nono audit, making child-tool activity visible alongside the parent session's audit trail. - ›Extends sandbox policy to allow
unlinkfor atomic write temp files, enabling tools that perform atomic writes (write-then-rename) to clean up temp files within policy.
- ›Adds
- v0.73.0
nono v0.73.0 adds glob pattern support in filesystem path fields for profile sandboxes.
└──▷ GET THIS VERSION$ git clone --branch v0.73.0 https://github.com/nolabs-ai/nono.git # already have the repo? check out this version: $ git checkout v0.73.0
- ›Supports glob patterns in filesystem path fields (e.g.
fs_read,fs_write) within profile sandboxes, enabling wildcard-based path grants without enumerating individual paths.
- ›Supports glob patterns in filesystem path fields (e.g.
- v0.72.0
nono v0.72.0 adds a static seccomp network baseline on Linux, explicit deny-path reporting in
why, and ships a musl release artifact.└──▷ GET THIS VERSION$ git clone --branch v0.72.0 https://github.com/nolabs-ai/nono.git # already have the repo? check out this version: $ git checkout v0.72.0
- ›Adds a static seccomp network baseline on Linux (alongside Landlock) under the
auto--sandbox-policymode, strengthening network restriction on kernels where Landlock ABI < V4. - ›Extends the
whysubcommand to report explicit deny paths from sandbox policy, making it easier to diagnose why a specific network or filesystem access was blocked. - ›Ships a musl release artifact, enabling deployment on musl-based Linux distributions without a glibc dependency.
- ›Removes
openclawandswivalas built-in profiles; users relying on them must supply their own profile going forward.
└──▷ BREAKING ON UPGRADE- !The
openclawandswivalbuilt-in profiles have been removed; anynono run --profile openclawornono run --profile swivalinvocation will fail after upgrading. - !The
externalvalue for--sandbox-policyon Linux now keeps Landlock active for filesystem/process policy while only delegating TCP enforcement externally, rather than installing no sandbox at all.
- ›Adds a static seccomp network baseline on Linux (alongside Landlock) under the
- v0.71.0
nono v0.71.0 adds a
platformsubcommand for audit control-plane enrollment and removes the deprecatedlearncommand.└──▷ GET THIS VERSION$ git clone --branch v0.71.0 https://github.com/nolabs-ai/nono.git # already have the repo? check out this version: $ git checkout v0.71.0
- ›Adds
nono platformsubcommand for enrolling with and inspecting an audit control plane, enabling centralised audit delivery at scale. - ›Removes the deprecated
nono learncommand (deprecated since v0.50.1).
└──▷ BREAKING ON UPGRADE- !The
nono learnsubcommand has been removed. Any scripts or workflows invokingnono learnwill break; usenono runinstead.
- ›Adds
- v0.70.0
nono v0.70.0 adds SPIFFE/SPIRE workload identity, per-route rate limiting, JWT-shaped capture nonces, Vault OIDC mediation, and profile-declared no_proxy bypass
└──▷ GET THIS VERSION$ git clone --branch v0.70.0 https://github.com/nolabs-ai/nono.git # already have the repo? check out this version: $ git checkout v0.70.0
└──▷ USE ITMediatevault login -method=oidcinside a sandboxed tool policy, injecting the token via a custom header and opening a per-command port for the OIDC callback.{ "command_policies": { "credentials": { "vault-oidc": { "type": "proxy", "upstream": "https://vault.example.com", "inject_header": "X-Vault-Token", "credential_format": "Bearer {}" } }, "commands": { "vault": { "from": { "session": { "sandbox": { "open_port": 8250, "credentials": [{ "name": "vault-oidc" }] }, "invocation_policy": { "default": "deny", "allow": [ { "argv": { "prefix": ["login", "-method=oidc"] } } ] } } } } } } }- ›Adds
CapturedNonceShapewith ajwtoption for capture intercepts, emitting a<header>.<payload>.nono_<64hex>token so consumers that validate JWT structure before use can still resolve the embedded nonce. - ›Adds per-route request rate limiting via
RouteRateLimiteron proxy upstream routes, letting profiles cap how many requests an agent or tool can send through a given route. - ›Adds SPIFFE/SPIRE workload identity auth for upstream proxy routes, enabling mutual workload attestation without static credentials.
- ›Adds mediation for
vault login -method=oidcwith support for a custominject_headerand a per-commandopen_port, so Vault OIDC flows can complete inside a sandboxed tool policy. - ›Adds profile-declared
no_proxybypass support, letting profiles explicitly list hosts that should skip the proxy.
+1 moreshow less
- ›New CLI prompt at session exit offers to save denied open-url origins, turning one-off denials into persistent policy without manual profile edits.
- ›Adds