Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions content/manuals/ai/sandboxes/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,11 @@ $ DOCKER_SANDBOXES_ENABLE_VIRTIOFS_CACHE=0 sbx run <template>

## Networking

All outbound traffic from the sandbox routes through an HTTP/HTTPS proxy on
your host. Agents are configured to use the proxy automatically. The proxy
enforces [network access policies](governance/access-controls/network.md) and handles
[credential injection](security/credentials.md). See
All outbound TCP traffic from the sandbox routes through a proxy on your host.
Agents use a forward proxy for HTTP and HTTPS; other TCP traffic is forwarded
transparently. Both paths enforce
[network access policies](governance/access-controls/network.md). The forward
proxy also handles [credential injection](security/credentials.md). See
[Network isolation](security/isolation.md#network-isolation) for how this
works and [Default security posture](security/defaults.md) for what is
allowed out of the box.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,11 @@ For domain patterns, wildcards, CIDR ranges, and filesystem path syntax, see

## Default preset

The only way traffic can leave a sandbox is through an HTTP/HTTPS proxy on
your host, which enforces access rules on every outbound request. Non-HTTP TCP
traffic, including SSH, can be allowed by adding a policy rule for the
destination IP and port (for example, `sbx policy allow network "10.1.2.3:22"`).
UDP and ICMP are blocked at the network layer and can't be unblocked with policy
rules.
Outbound TCP traffic passes through a proxy on your host, which enforces access
rules on every connection. Non-HTTP TCP traffic, including SSH, can be allowed
with a hostname rule (for example, `sbx policy allow network "myhost:22"`) or an
address-based rule. UDP and ICMP are blocked at the network layer and can't be
unblocked with policy rules.

If you haven't chosen a default preset, the CLI prompts you before it runs a
sandbox. Running `sbx policy reset` clears the preset and prompts you to choose
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ policy. See [Precedence](../concepts.md#precedence).

## Rule syntax

Network rules use the actions `connect:tcp` and `connect:udp`. Resources are
hostnames, CIDR ranges, ports, or hostnames with ports.
Network rules use the action `connect:tcp`. Resources are hostnames, CIDR
ranges, ports, or hostnames with ports. The governance policy schema also
accepts `connect:udp`, but Docker Sandboxes always blocks direct external UDP
and ICMP. `connect:udp` rules have no effect.

Examples:

Expand Down
6 changes: 4 additions & 2 deletions content/manuals/ai/sandboxes/governance/concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,10 @@ plus every team-scoped policy for a team they belong to. See

### Network rules

Network rules use the actions `connect:tcp` and `connect:udp`. Resources are
hostnames, CIDR ranges, or ports.
Network rules use the action `connect:tcp`. Resources are hostnames, CIDR
ranges, or ports. The governance policy schema also accepts `connect:udp`, but
Docker Sandboxes always blocks direct external UDP and ICMP. `connect:udp`
rules have no effect.

**Hostname patterns**

Expand Down
18 changes: 10 additions & 8 deletions content/manuals/ai/sandboxes/security/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ What crosses the boundary into the VM:
and the agent works on a private clone.
- **Credentials:** the host-side proxy injects authentication headers into
outbound HTTP requests. The raw credential values never enter the VM.
- **Network access:** HTTP and HTTPS requests to
[allowed domains](defaults/) are proxied through the host.
- **Network access:** outbound TCP connections to destinations allowed by
[network policy](defaults/) are proxied through the host.
- **Shared agent skills:** a persistent host-side store is mounted read-write
at the agent's skills directory unless you opt out when creating the
sandbox. Supported agents in other sandboxes mount the same store.
Expand All @@ -36,15 +36,16 @@ What crosses the boundary back to the host:

- **Workspace file changes:** visible on your host in real time with the
default direct mount.
- **HTTP/HTTPS requests:** sent to allowed domains through the host proxy.
- **Outbound TCP connections:** sent to allowed destinations through the host
proxy.
- **Shared skill changes:** written to the host-side store and visible to other
sandboxes that share it.

Outside the workspace and shared skills store, the agent cannot access your
host filesystem. It also cannot access your host Docker daemon, your host
network or localhost, or any domain not in the allow list. Sandboxes cannot
communicate directly over the network. Raw TCP, UDP, and ICMP are blocked at
the network layer.
network directly, or any destination not allowed by network policy. Sandboxes
cannot communicate directly over the network. Direct external UDP and ICMP are
blocked at the network layer.

MCP servers are an explicit integration point. Remote MCP servers run outside
Docker Sandboxes, and local stdio MCP servers run on the host, not inside the
Expand All @@ -61,8 +62,9 @@ The sandbox security model has five layers. See

- **Hypervisor isolation:** separate kernel per sandbox. No shared memory or
processes with the host.
- **Network isolation:** all HTTP/HTTPS traffic proxied through the host.
[Deny-by-default policy](defaults/). Non-HTTP protocols blocked entirely.
- **Network isolation:** outbound TCP traffic is proxied through the host and
governed by a [deny-by-default policy](defaults/). Direct external UDP and
ICMP are blocked.
- **Docker Engine isolation:** each sandbox has its own Docker Engine with no
path to the host daemon.
- **Workspace isolation** (opt-in via `--clone`): the agent works on a
Expand Down
16 changes: 7 additions & 9 deletions content/manuals/ai/sandboxes/security/defaults.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ security posture.

## Network defaults

All outbound HTTP and HTTPS traffic is blocked unless an explicit rule allows
it (deny-by-default). All non-HTTP protocols (raw TCP, UDP including DNS, and
ICMP) are blocked at the network layer. Traffic to private IP ranges, loopback
addresses, and link-local addresses is also blocked.
All outbound TCP traffic, including HTTP, HTTPS, and SSH, is blocked unless an

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[HIGH] Private IP and link-local address blocking omitted from new network defaults

The old text explicitly stated that "Traffic to private IP ranges, loopback addresses, and link-local addresses is also blocked." The new paragraph drops this guarantee entirely — neither the introductory paragraph nor the bullet list below it mentions this restriction. A reader of the updated documentation cannot determine whether these addresses are still blocked, which is a meaningful gap in security documentation. If these restrictions still apply, consider adding a sentence such as: "Traffic to private IP ranges, loopback addresses, and link-local addresses is also blocked at the network layer."

@dvdksn dvdksn Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This restriction does not still apply unconditionally. The current policy engine can authorize private IP literals through CIDR allow rules; see dialIsAllowed-CIDR-allow-permits-IP-literal-with-no-domain-rule in sandboxd/pkg/proxy/policy_engine_test.go. Commit 7352567 updates the remaining security overview text to describe the actual policy-controlled TCP boundary.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the clarification — I see now that this was a false positive. The policy engine's support for CIDR allow rules means private IP literals can be authorized, so the old unconditional block no longer applies. I misread the change as an omission when it actually reflects the more flexible, policy-controlled approach described in commit 7352567.

The updated text correctly describes the current TCP boundary without overstating restrictions that no longer hold.

explicit rule allows the destination. Direct external UDP and ICMP traffic is
blocked at the network layer. DNS queries use the sandbox's internal resolver,
which enforces network policy.

Run `sbx policy ls` to see the active network rules for your installation.
Rules can be customized per machine with the `sbx policy` CLI, or managed
Expand Down Expand Up @@ -71,10 +71,8 @@ policy configuration:
- Host filesystem access outside explicitly mounted workspaces and the shared
skills store
- Host Docker daemon
- Host network and localhost

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[MEDIUM] "Host network and localhost" removed from unconditional block list without replacement

The old bullet list included "Host network and localhost" as an explicit, policy-unconfigurable block — meaning agents could not reach the host machine's own network stack or loopback interface. The new text removes this bullet entirely. The remaining bullet "Direct network communication between sandboxes" addresses sandbox-to-sandbox communication, not sandbox-to-host access. Since sandboxes run as VMs, this is a meaningful security boundary. If host network and localhost access is still blocked, consider restoring the bullet or incorporating this guarantee into the introductory paragraph.

@dvdksn dvdksn Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not restore this as an unconditional block because current Sandboxes code provides a policy-controlled host route: transparent_forwarding_dialer.go rewrites the host.docker.internal link-local destination through the existing localhost policy/dial path. Commit 7352567 now states that the sandbox does not share the host network or access it directly, while preserving the documented policy-authorized proxy path.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the clarification — that makes sense. The distinction between direct host network access (unconditionally blocked) and policy-controlled proxy access to localhost (configurable) is an important architectural detail. The current text correctly states the sandbox doesn't share or directly access the host network, while the policy system can authorize specific localhost connections through the proxy layer.

This is actually more accurate than an unconditional block bullet would have been, since it reflects the real security boundary: no direct network stack sharing, but controlled proxy paths are possible when policy permits.

- Direct network communication between sandboxes
- Raw TCP, UDP, and ICMP connections
Comment thread
dvdksn marked this conversation as resolved.
- Traffic to private IP ranges and link-local addresses
- Direct external UDP and ICMP connections

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[MEDIUM] Removal of private IP/loopback/link-local blocking from security defaults

The old text explicitly stated these were blocked for all sandboxes:

  • "Traffic to private IP ranges, loopback addresses, and link-local addresses is also blocked."
  • List bullets: "Host network and localhost" and "Traffic to private IP ranges and link-local addresses"

The new text replaces these with "Direct external UDP and ICMP connections." The word "external" is ambiguous — readers would reasonably interpret it as not covering loopback (127.x.x.x), private IP ranges (10.x, 172.16.x, 192.168.x), or link-local addresses (169.254.x.x), since those are not conventionally "external." If the sandbox still blocks those destinations, the new text leaves readers with an incomplete threat model.

Consider adding a sentence such as: "Private IP ranges, loopback, and link-local addresses are also blocked and cannot be reached from inside the sandbox."

@dvdksn dvdksn Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for flagging the removed wording. I did not restore it because it is not an unconditional sandbox guarantee: network policy supports CIDR resources, and the Sandboxes policy tests explicitly permit an IP literal such as 10.10.14.20 when a matching CIDR allow rule applies (sandboxd/pkg/proxy/policy_engine_test.go, dialIsAllowed-CIDR-allow-permits-IP-literal-with-no-domain-rule). Commit 7352567 instead aligns the other security pages so they no longer repeat the stale categorical claim.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're absolutely right, and thank you for the clarification. I misunderstood the interaction between CIDR allow rules and these address ranges.

The old text made an unconditional claim ("blocked for all sandboxes") that doesn't hold when policy explicitly permits a CIDR range covering private IPs, loopback, or link-local addresses. Your decision to remove that stale guarantee rather than restore it was correct — the new text is more accurate.

I appreciate you aligning the other security pages as well. Apologies for the noise on this one.


Outbound HTTP/HTTPS to domains not in the allow list is also blocked by
default, but you can add allow rules with `sbx policy allow`.
Outbound TCP to destinations not in the allow list is also blocked by default,
but you can add allow rules with `sbx policy allow`.
19 changes: 8 additions & 11 deletions content/manuals/ai/sandboxes/security/isolation.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,20 @@ hypervisor boundary is the isolation control, not in-VM privilege separation.

## Network isolation

Each sandbox has its own isolated network. Sandboxes cannot communicate with
each other and cannot reach your host's localhost. There is no shared network
between sandboxes or between a sandbox and your host.
Each sandbox has its own isolated network. Sandboxes cannot communicate
directly with each other or share a network with your host. To reach a service
running on the host through a policy-controlled connection, see
[Accessing host services from a sandbox](../workflows.md#accessing-host-services-from-a-sandbox).

All HTTP and HTTPS traffic leaving a sandbox passes through a proxy on your
host that enforces the
All outbound TCP traffic passes through a proxy on your host that enforces the
[network access policy](../governance/access-controls/network.md). The sandbox
routes traffic through either a forward proxy or a transparent proxy depending
on the client's configuration. Both enforce the network policy. Only the
forward proxy [injects credentials](credentials.md) for AI services.

Raw TCP connections, UDP, and ICMP are blocked at the network layer. DNS
resolution goes through the proxy and is subject to the same network policy —
domains that policy denies are refused at the resolver; loopback names such as
`localhost` are always resolved regardless of policy. Traffic to private IP
ranges, loopback, and link-local addresses is also blocked. Only domains
explicitly listed in the policy are reachable.
Direct external UDP and ICMP are blocked at the network layer. DNS queries use
the sandbox's internal resolver, which enforces network policy. TCP connections
are allowed only when a policy rule matches the destination.

For the default set of allowed domains, see
[Default security posture](defaults.md). To forward allowed traffic through a
Expand Down
20 changes: 12 additions & 8 deletions content/manuals/ai/sandboxes/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,23 +91,27 @@ any remote source, see [Restrict kit sources](customize/kits.md#restrict-kit-sou

## SSH and other non-HTTP connections fail

Non-HTTP TCP connections like SSH can be allowed by adding a policy rule for
the destination IP address and port. For example, to allow SSH to a specific
host:
Non-HTTP TCP connections such as SSH can be allowed by adding a policy rule for
the destination. Hostname rules work for these connections because the sandbox
recovers the hostname from its DNS resolver when the protocol doesn't include
one:

```console
$ sbx policy allow network "10.1.2.3:22"
$ sbx policy allow network "myhost:22"
```

Hostname-based rules (for example, `myhost:22`) don't work for non-HTTP
connections because the proxy can't resolve the hostname to an IP address in
this context. Use the IP address directly.
If the destination is reached by IP address without a DNS lookup, the hostname
can't be recovered. Use an address-based rule in that case:

```console
$ sbx policy allow network "10.1.2.3:22"
```

UDP and ICMP traffic is blocked at the network layer and can't be unblocked
with policy rules.

For Git operations over SSH, you can either add an allow rule for the Git
server's IP address or use HTTPS URLs instead:
server's hostname or IP address, or use HTTPS URLs instead:

```console
$ git clone https://github.com/owner/repo.git
Expand Down