Guide
How do I restrict which domains an AI agent can reach?
Start from deny-all and allow only the hosts the agent's work needs. On Sanbox, every template has a network policy: outbound traffic is denied by default, each rule allows one destination on the ports you list, and a blocked request names the host it couldn't reach, so you add hosts on purpose rather than by guesswork. On your own machines the same idea means an egress proxy or firewall with an allowlist. Inbound access is a separate setting and is off by default.
Run this with your agent
Read https://sanbox.cloud/kb/security/restrict-which-domains-an-agent-can-reach.md and follow it to give my agent a template with an egress allowlist.
If the Sanbox CLI is missing, install it with `npm install -g @sanlabs/sanbox-cli@latest`
and sign in with `sanbox login`. Show me each command before you create, stop or delete a Computer.
How does a Sanbox network policy work?
- Deny by default. A template without a policy reaches nothing except what Sanbox manages for it, such as the model provider configured on the template.
- One rule per destination. Each rule names a host and a range of ports, with an optional description of up to 120 characters. A template can own at most 16 rules, so list what the work needs, not everything it might.
- Outbound only. The policy says nothing about who can reach the Computer.
- Everything inside goes through it. On a Docker Computer, containers and image builds use the same proxy and the same rules.
- Your own agents need their own hosts. If you install Claude Code or Codex in a Computer, allow its API host yourself.
Steps
1. Write the policy
This example lets a Node and Python coding agent install packages and read from GitHub. Save it as policy.json:
{
"default_action": "deny",
"rules": [
{ "destination": "registry.npmjs.org", "ports": [{ "from": 443, "to": 443 }], "description": "npm" },
{ "destination": "pypi.org", "ports": [{ "from": 443, "to": 443 }], "description": "PyPI index" },
{ "destination": "files.pythonhosted.org", "ports": [{ "from": 443, "to": 443 }], "description": "PyPI files" },
{ "destination": "github.com", "ports": [{ "from": 443, "to": 443 }], "description": "git over HTTPS" },
{ "destination": "codeload.github.com", "ports": [{ "from": 443, "to": 443 }], "description": "GitHub archives" }
]
}
2. Create the template
Creating templates needs the admin or owner role. The same option works for every Computer type:
sanbox templates create --name "Node and Python agent" --type opencode-computer \
--model-provider <provider-id> --model <model-id> \
--network-policy policy.json --json
sanbox templates validate <template-id> --json
runnable: true means the template can start. It doesn't check that the policy allows the sites your task needs.
3. Test from a Computer
Start a Computer, wait until it's running, then try an allowed host and one you left out:
sanbox run --template <template-id> --json
sanbox exec <run-id> -- curl -sS -o /dev/null -w '%{http_code}\n' https://registry.npmjs.org/
sanbox exec <run-id> -- curl -sS https://example.org/
The first prints an HTTP status code. The second fails, because the policy blocks the connection.
4. Add hosts on purpose
When a package install or image pull is blocked, its error names the host it couldn't reach. Decide whether you trust that host, then add it in the template's Network access tab in the console. Test the change on a new Computer. A Secret Proxy grant with --add-network-access also adds an HTTPS rule for the proxy's host.
Which hosts do common tools need?
| Tool | Hosts | Port |
|---|---|---|
| npm | registry.npmjs.org | 443 |
| pip and PyPI | pypi.org, files.pythonhosted.org | 443 |
| apt on Debian | deb.debian.org, and security.debian.org if your sources list it | 80 or 443, as your sources say |
| Docker Hub | registry-1.docker.io, auth.docker.io, production.cloudfront.docker.com, production.cloudflare.docker.com | 443 |
| GitHub Container Registry | ghcr.io, pkg-containers.githubusercontent.com | 443 |
| GitHub | github.com, api.github.com, codeload.github.com | 443 |
| GitHub release downloads | objects.githubusercontent.com, release-assets.githubusercontent.com | 443 |
| Raw files on GitHub | raw.githubusercontent.com | 443 |
| Claude API | api.anthropic.com | 443 |
| OpenAI API | api.openai.com | 443 |
Two things to watch:
- Debian sources often use plain HTTP. Look in
/etc/apt/sources.list.d/and allow the port the source URL uses, or switch the sources tohttps://. - Downloads often redirect. A file requested from one host may be served from a separate download or CDN host, and each host in the chain needs a rule. GitHub publishes its current domains in its meta API.
How do I find out what a tool needs?
- Run it once in a Computer and read the host it couldn't reach from the error.
- Check the tool's documentation. Claude Code, for example, publishes the domains it needs:
api.anthropic.comfor the API, plusclaude.aiandplatform.claude.comfor signing in. - Prefer specific hosts. Allow
api.github.comfor an API client rather than every GitHub host.
What about inbound traffic?
Inbound access is off by default and separate from the network policy. To reach a service inside a Computer, an admin adds ports to the template with --inbound-port <port> at creation or sanbox templates inbound set <template-id> --port <port> --json later. Callers then need a short-lived token from sanbox ports connect <run-id> --port <port> --expires 1h --json, or a local forward with sanbox ports forward <run-id> 3000:<port>. Nothing becomes public. HTTP and SSE work; WebSockets and raw TCP don't.
What this doesn't do
- An allowed host can receive data. If the agent can reach
github.comor an API, it can send what it reads there. An allowlist narrows the ways out; it doesn't remove them. - Rules work per host and port, not per URL path. To limit what an agent can do with an API credential, use Secret Proxy path and method rules.
- It doesn't promise a fixed source IP. If a service only accepts known IP addresses, ask support@sanlabs.ai before you plan on it.
- It isn't a database tunnel. This page covers web traffic. Ask support before you plan on reaching a database over its own protocol.
Related
- Why can't my AI agent reach a website or package registry?
- How do I give an AI agent API keys without exposing them?
- How do I preview the dev server my agent is running?
- How do I run Docker Compose inside an AI agent's sandbox?
Sources
- npm: registry, default registry URL (checked 2026-11-06)
- PyPI: Index API,
pypi.organdfiles.pythonhosted.org(checked 2026-11-06) - Debian wiki: SourcesList, HTTP and HTTPS sources (checked 2026-11-06)
- GitHub meta API, published GitHub domains (checked 2026-11-06)
- Claude API overview,
api.anthropic.com(checked 2026-11-06) - OpenAI API reference,
api.openai.com(checked 2026-11-06) - Claude Code: Network access requirements (checked 2026-11-06)