Blocking All Network
network.block to true:
Domain Filtering
The proxy starts whenever any domain-filtering flag is present:--network-profile, --allow-domain, --credential, or --upstream-proxy (from CLI args or profile config). It restricts outbound traffic to a set of allowed domains.

How It Works
When domain filtering is active:- An HTTP proxy starts on a random localhost port (or a fixed port via
--proxy-port) - The child sandbox restricts outbound to only
localhost:<port> HTTP_PROXYandHTTPS_PROXYare set in the child environment- Every CONNECT request is validated against the domain allowlist
Proxy-Authorization header), preventing other localhost processes from using the proxy.
The proxy resolves DNS itself and checks all resolved IPs against the deny list before connecting. This prevents DNS rebinding attacks where a malicious DNS server maps an allowed hostname to an internal IP.
Proxy Port
By default the proxy binds to an OS-assigned ephemeral port. Use--proxy-port to fix it when the application requires a known port:
OPENAI_BASE_URL, ANTHROPIC_BASE_URL, etc. from the environment don’t need --proxy-port — nono sets these automatically.
Network Profiles
Network profiles are named sets of allowed domains composed from groups. They are defined innetwork-policy.json (embedded in the binary) and activated with --network-profile or via a profile’s network.network_profile field.
Built-in Profiles
| Profile | Groups | Use Case |
|---|---|---|
minimal | llm_apis | LLM API access only |
developer | llm_apis, package_registries, github, sigstore, documentation | General development |
claude-code | llm_apis, package_registries, github, sigstore, documentation | Claude Code agent |
codex | Same as developer + bundled openai credential | Codex agent |
opencode | Same as developer + bundled google-ai credential | OpenCode agent |
enterprise | All groups + google_cloud, azure, aws_bedrock | Corporate environments |
Groups
Each group maps to a set of allowed hostnames and wildcard suffixes:| Group | Hosts |
|---|---|
llm_apis | api.openai.com, api.anthropic.com, generativelanguage.googleapis.com, … |
package_registries | registry.npmjs.org, pypi.org, crates.io, … |
github | github.com, api.github.com, raw.githubusercontent.com, … |
sigstore | fulcio.sigstore.dev, rekor.sigstore.dev, tuf-repo-cdn.sigstore.dev |
documentation | docs.python.org, developer.mozilla.org, doc.rust-lang.org, … |
google_cloud | *.googleapis.com |
azure | *.openai.azure.com, *.cognitiveservices.azure.com |
aws_bedrock | *.bedrock.amazonaws.com, *.bedrock-runtime.amazonaws.com |
Adding Domains
Use--allow-domain on the command line or allow_domain in a profile to add domains on top of the network profile:
Upstream Proxy
For corporate environments with a mandatory outbound proxy, chain domain-filtered traffic through it with--upstream-proxy. This is typically paired with the enterprise network profile:
Bypassing the Upstream Proxy
Some domains may need to bypass the upstream proxy and connect directly:*. wildcard suffixes (case-insensitive). Matching hosts route directly; everything else goes through the upstream proxy.
This can also be configured in a profile:
Localhost IPC
Use--open-port to allow bidirectional localhost TCP on a specific port (connect + listen). This enables IPC between sandboxed processes — for example, an MCP server in one sandbox and an AI agent in another.
--open-port works alongside domain filtering. Outbound to allowed hosts goes through the proxy; IPC stays on localhost:
connect() and bind() on the specified port, in addition to the proxy port.
See CLI Reference for full details and platform limitations.
Listen-Only Ports
Use--listen-port when a sandboxed process needs to accept inbound connections but does not need to initiate outbound connections on that port (e.g., a server or gateway):
Always-Denied Destinations
The following destinations are always blocked by the proxy, regardless of configuration. These cannot be overridden.| Destination | Why |
|---|---|
169.254.169.254 | AWS/GCP/Azure instance metadata |
metadata.google.internal | GCP metadata alias |
metadata.azure.internal | Azure metadata alias |
169.254.0.0/16 (resolved IP) | IPv4 link-local — DNS rebinding protection |
fe80::/10 (resolved IP) | IPv6 link-local — DNS rebinding protection |
Platform Behavior
Linux
Network filtering uses Landlock V4+ per-port TCP rules. The sandbox restrictsconnect() to only the proxy port. All other outbound TCP is blocked at the kernel level.
Requirements: Landlock ABI v4+ (Linux 6.7+)
macOS
Network filtering uses Seatbelt rules. The sandbox allows only(remote tcp "localhost:PORT") and denies all other network operations.
Audit Logging
All proxy decisions are logged viatracing:
Limitations
- HTTP/1.1 only — The CONNECT tunnel passes raw bytes (HTTP/2 works end-to-end), but the reverse proxy mode speaks HTTP/1.1 to upstream
- No per-port filtering on macOS — Seatbelt cannot filter outbound by destination port
- Domain filtering requires supervised execution — The proxy runs in the unsandboxed parent process, so
nono wrap(Direct mode) is incompatible. Usenono runinstead.
Next Steps
- Credential Injection — Keep API keys out of the sandbox
- CLI Reference — Complete flag documentation