Network Filtering
Block all network access, allow specific domains, filter individual API endpoints, and route through upstream proxies. The proxy starts on a random localhost port and the kernel sandbox restricts the child to that port only.
How it works
By default, sandboxed processes have unrestricted network access. When you enable domain filtering via --network-profile, --allow-domain, or --credential, an HTTP proxy starts on a random localhost port (or a fixed port via --proxy-port). The child sandbox is restricted to that port only, and a 256-bit session token authenticates every request.
# Block all network accessnono run --allow-cwd --block-net -- cargo build# Allow specific domains onlynono run --allow-cwd --allow-domain api.openai.com \--allow-domain api.anthropic.com -- my-agent# Use a built-in network profilenono run --allow-cwd --network-profile claude-code -- claude# Add custom domains to a profilenono run --allow-cwd --network-profile developer \--allow-domain my-internal-api.example.com -- my-agent
Built-in Network Profiles
Pre-configured domain sets for common workflows:
minimal— LLM API access onlydeveloper— General developmentclaude-code— Claude Code agentcodex— Codex agent with OpenAI credentialenterprise— Corporate environments
Always-Denied Destinations
These destinations are blocked regardless of configuration and cannot be overridden:
169.254.169.254— AWS/GCP/Azure metadatametadata.google.internal— GCP metadata169.254.0.0/16— IPv4 link-localfe80::/10— IPv6 link-local
Domain group profiles
Network profiles are composed from domain groups. Key groups include llm_apis (OpenAI, Anthropic, Google), package_registries (npm, PyPI, crates.io), github, sigstore, and cloud platform groups for google_cloud, azure, and aws_bedrock. You can extend any profile with additional domains via CLI flags or profile configuration.
{"network": {"network_profile": "developer","allow_domain": ["my-internal-api.example.com"]}}
$ nono run -vv --network-profile claude-code --allow-cwd -- my-agentALLOW CONNECT api.openai.com:443ALLOW CONNECT github.com:443DENY CONNECT 169.254.169.254:80 reason=denied_cidrALLOW REVERSE openai POST /v1/chat/completions -> 200
Endpoint filtering
Beyond domain-level control, you can restrict access to specific API endpoints. Patterns support exact paths, single-segment wildcards (*), and multi-segment wildcards (**). Method can be a specific HTTP verb or * for any.
# Allow only chat completions on OpenAInono run --allow-cwd --credential openai \--allow-endpoint 'openai:POST:/v1/chat/completions' \-- my-agent# Fine-grained GitHub API accessnono run --allow-cwd --credential github \--allow-endpoint 'github:GET:/repos/*/issues/**' \--allow-endpoint 'github:POST:/repos/*/issues/*/comments' \-- my-agent
{"network": {"custom_credentials": {"gitlab": {"upstream": "https://gitlab.example.com","credential_key": "gitlab_token","endpoint_rules": [{"method": "GET","path": "/api/v4/projects/*/merge_requests/**"},{"method": "POST","path": "/api/v4/projects/*/merge_requests/*/notes"}]}}}}
Upstream proxy
For corporate environments, route all filtered traffic through an upstream proxy. Bypass rules let internal hosts skip the upstream proxy while still being subject to nono domain filtering. Configuration also works via NONO_UPSTREAM_PROXY and NONO_UPSTREAM_BYPASS environment variables.
# Route through corporate proxynono run --allow-cwd --network-profile enterprise \--upstream-proxy squid.corp:3128 -- my-agent# Bypass proxy for internal hostsnono run --allow-cwd --network-profile enterprise \--upstream-proxy squid.corp:3128 \--upstream-bypass git.internal.corp \--upstream-bypass "*.dev.local" \-- my-agent
{"network": {"network_profile": "enterprise","upstream_proxy": "squid.corp:3128","upstream_bypass": ["git.internal.corp","*.dev.local"]}}
Localhost IPC
Open specific localhost ports for inter-process communication, even when all external network access is blocked. Use --open-port for bidirectional access or --listen-port for listen-only. Both can be combined with domain filtering.
# Bidirectional localhost IPC on port 3000nono run --block-net --open-port 3000 \--allow ./mcp-server -- node server.js# Combine with domain filteringnono run --network-profile claude-code \--open-port 3000 --allow-cwd -- claude# Listen-only port for dev serversnono run --allow-cwd --network-profile developer \--listen-port 3000 -- npm run dev
Platform behaviour
Linux: Requires Landlock ABI v4+ (Linux 6.7+). Uses per-port TCP rules for full enforcement.
macOS: Uses Seatbelt rules limiting the child to localhost:PORT only. No per-port destination filtering.
WSL2: --block-net works; domain filtering is disabled by default due to kernel limitations. Enable with wsl2_proxy_policy: "insecure_proxy" in profile security config.
See the networking docs for full details.
Get started with nono
Runtime safety infrastructure that works on macOS, Linux, Windows, and in CI.