Skip to content

Network Isolation

Every outbound HTTP and HTTPS request from a sandbox is checked against your network policies before it leaves. Policies are written in the same simple policy DSL used for RBAC — giving you fine-grained control over which external services a sandbox can reach.

This is a core part of Tilde's security model: autonomous agents and automated pipelines should only access the network resources they need, nothing more.

Why Network Policies Matter

When you give an AI agent access to your data and let it run code, it can do anything a program can do — including making HTTP requests. Without network controls, a sandbox could:

  • Exfiltrate data to unauthorized external services
  • Call arbitrary APIs using credentials found in the environment
  • Reach cloud metadata endpoints (like 169.254.169.254) to escalate privileges
  • Access internal services on private networks that should be off-limits
  • Download and execute untrusted code from the internet

Network policies prevent all of this. Every outbound request is evaluated against your organization's policies before it is allowed to proceed.

How It Works

Every outbound HTTP and HTTPS request from a sandbox is evaluated before it leaves:

  1. Baseline rules unconditionally block requests to dangerous destinations (private networks, cloud metadata, loopback). These cannot be overridden by policy.
  2. Network policies check the request against your organization's allow/deny rules.
  3. Allowed requests proceed to the upstream server. Denied requests return 403 Forbidden to the sandbox.

There is no way for code inside a sandbox to opt out — the only path off the sandbox network is through this enforcement layer.

Baseline Protection

Before any policy is evaluated, requests to dangerous network destinations are unconditionally blocked. These rules are always enforced and cannot be overridden by policies:

Range Purpose
10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 Private networks (RFC 1918)
169.254.0.0/16 Link-local addresses, including cloud metadata endpoints (AWS, GCP)
100.64.0.0/10 Carrier-grade NAT (shared address space)
127.0.0.0/8 Loopback
198.18.0.0/15 Benchmark/testing range
IPv6 equivalents ::1, fe80::/10, fd00::/8

DNS is resolved and the resolved IP addresses are checked against these ranges before any connection is established. This prevents DNS rebinding attacks where a hostname initially resolves to a public IP but later resolves to a private one.

Default Policy

Every organization gets a built-in DefaultNetworkAccess policy that provides a sensible starting point. It allows access to common package managers, AI APIs, and code hosting services while denying everything else:

# Language package managers
HttpRequest(host:"registry.npmjs.org")
HttpRequest(host:"registry.yarnpkg.com")
HttpRequest(host:"pypi.org")
HttpRequest(host:"files.pythonhosted.org")
HttpRequest(host:"*.crates.io")
HttpRequest(host:"rubygems.org")
HttpRequest(host:"proxy.golang.org")
HttpRequest(host:"sum.golang.org")

# OS package managers — Debian / Ubuntu (apt)
HttpRequest(host:"deb.debian.org")
HttpRequest(host:"security.debian.org")
HttpRequest(host:"archive.ubuntu.com")
HttpRequest(host:"*.archive.ubuntu.com")
HttpRequest(host:"security.ubuntu.com")
HttpRequest(host:"ports.ubuntu.com")
HttpRequest(host:"changelogs.ubuntu.com")
HttpRequest(host:"keyserver.ubuntu.com")

# OS package managers — Alpine (apk)
HttpRequest(host:"dl-cdn.alpinelinux.org")
HttpRequest(host:"*.alpinelinux.org")

# AI APIs
HttpRequest(host:"api.openai.com")
HttpRequest(host:"api.anthropic.com")

# GitHub (for git clone, releases)
HttpRequest(host:"github.com")
HttpRequest(host:"api.github.com", scheme:"https")
HttpRequest(host:"raw.githubusercontent.com")
HttpRequest(host:"objects.githubusercontent.com")
HttpRequest(host:"release-assets.githubusercontent.com", scheme:"https")

# Tilde API, install script, and releases
HttpRequest(host:"tilde.run", scheme:"https", path:"/api*")
HttpRequest(host:"tilde.run", scheme:"https", path:"/install*")
HttpRequest(host:"tilde.run", scheme:"https", path:"/releases*")

This policy is deny-by-default: any host not explicitly allowed is blocked. You can expand it by attaching additional allow policies, restrict it by attaching deny policies, or replace it entirely with your own custom policies.

Writing Network Policies

Network policies use the HttpRequest action from Tilde's policy DSL. They define allow and deny rules that are evaluated against each outbound HTTP/HTTPS request.

Available Modifiers

The HttpRequest action supports the following modifiers for matching requests:

Modifier Description Example
host Hostname (fnmatch pattern) HttpRequest(host:"api.example.com")
scheme "http" or "https" HttpRequest(scheme:"https")
port Port number HttpRequest(port:"443")
method HTTP method HttpRequest(method:"GET")

All modifiers support fnmatch-style patterns (*, ?, [abc]).

Allow and Deny Rules

Policies use the same deny-overrides-allow semantics as RBAC:

  1. If any policy returns a deny (!), the request is blocked
  2. If at least one policy allows (and none deny), the request is allowed
  3. If no policy allows the request, it is blocked (default deny)

Examples

Allow an internal API

HttpRequest(host:"api.internal.example.com")

Block publishing to package registries

Prevent sandboxes from publishing packages while still allowing them to install dependencies:

!HttpRequest(host:"registry.npmjs.org", method:"POST")
!HttpRequest(host:"registry.npmjs.org", method:"PUT")
!HttpRequest(host:"pypi.org", method:"POST")

Allow a domain and all subdomains

# Allow example.com and *.example.com
HttpRequest(host:"example.com")
HttpRequest(host:"*.example.com")

Subdomain matching

Use *.example.com to match subdomains. A bare *example.com pattern would also match evilexample.com. Always use *.example.com (with the dot) for safe subdomain matching.

Allow HTTPS only

HttpRequest(host:"api.example.com", scheme:"https")

Tip

Do not embed secrets in policies. Use repository secrets or agent secrets to inject credentials into sandboxes.

Allow specific hosts with HTTPS only

# Allow only the OpenAI API over HTTPS
HttpRequest(host:"api.openai.com", scheme:"https")

Policy Resolution for Agents

When a sandbox runs as an agent, network policies use restrictive composition — a stricter model than RBAC's union-based merge:

  1. The HttpRequest rules in the agent's inline policy are evaluated independently
  2. The agent's creator's network policies (direct + group-inherited) are also evaluated independently
  3. The request is allowed only if both policy sets independently allow it
  4. The request is denied if either policy set denies it

Direct attachments and group memberships on the agent itself do not contribute to its network access — consistent with the RBAC intersection model. The agent's only source of network grants is the inline policy. If the inline has no HttpRequest allow rules, the sandbox cannot make any outbound HTTP requests, regardless of what the creator can reach.

This ensures an agent can never gain network access beyond what its creator has. If you (the creator) don't have a policy allowing api.internal.example.com, your agents can't reach it either — even if the agent's inline policy allows that host.

For non-agent principals (users, roles), only the principal's own policies apply.

Supported Protocols

Protocol Support
HTTP/1.1 Fully policy-checked
HTTPS Each request is individually policy-checked, including requests sent over a persistent connection
WebSocket (ws://, wss://) Policy-checked on the initial Upgrade request; frames are then relayed without inspection
HTTP/3 (QUIC) Not supported; QUIC (UDP 443) is blocked. HTTP/3-capable clients automatically fall back to HTTPS over TCP, which is fully supported

HTTPS requests work transparently — standard tools (curl, Python requests, Node.js, Go, pip, npm, git) need no special configuration inside the sandbox.

Observability

Every proxied request produces a structured log entry with:

  • Sandbox ID, method, scheme, host, port, path
  • Decision (allow, deny, or baseline_deny)
  • Decision reason and source
  • Names of matched allow/deny policies
  • Upstream status code and latency

Denied requests are logged at the WARN level, making them easy to identify. Use these logs to:

  • Discover which external services your sandboxes actually need
  • Tune your allowlist based on real traffic patterns
  • Investigate sandbox failures caused by blocked network requests
  • Audit agent network activity for security reviews

Limits

Resource Limit
Request header size 64 KB
WebSocket idle timeout 5 minutes (no data in either direction)
Upstream connection timeout 10 seconds
Upstream response header timeout 30 seconds

Next Steps