What happens
When an agent inside a network-restricted sandbox runs varlock proxy run --url, its requests ride the tunnel and exit from the broker's machine. The sandbox's own egress allowlist only ever sees the connection to the broker. If the broker's schema uses the default egress="permissive", every unmatched request passes through untouched, so the agent reaches anything the broker can reach.
The net effect is that wiring up a varlock broker silently converts a deny-by-default sandbox into open egress, and neither side reports it. The sandbox's policy log shows one allowed connection to the broker; varlock's audit log shows requests being allowed as designed.
Reproduced
Docker Sandboxes (sbx 0.38.0), Balanced preset, broker on the host with the default egress mode. Only localhost:8080 (the broker) allowed in sbx policy:
sbx policy check network ipinfo.io -> Denied: ipinfo.io:443
direct from the sandbox -> HTTP 403
through the varlock broker -> HTTP 200
Adding @proxyConfig={egress="strict"} to the schema closes it (CONNECT tunnel failed, response 403).
Also reproduced against a stand-in HTTP CONNECT gateway with a one-entry allowlist, so this is not specific to Docker Sandboxes. It applies to any guest whose only egress is a filtering proxy: sbx, and the same shape on E2B or Fly.io network rules.
Suggested behavior
proxy run --url can detect the situation cheaply. At startup it already inspects HTTP_PROXY / HTTPS_PROXY / ALL_PROXY to decide whether to dial the tunnel through a CONNECT proxy (proxyForTunnelUrl in packages/varlock/src/proxy/tunnel.ts). If a proxy applies to the tunnel URL, the guest's egress is filtered by something other than varlock, and the broker's egress mode determines whether that filtering still means anything.
The bootstrap payload would need to carry the broker's egress mode so the guest can tell. Then, when a tunnel proxy applies and the broker is permissive, print a warning along the lines of:
This sandbox routes egress through a proxy, but the broker's egress mode is permissive, so requests through varlock bypass that policy. Set @proxyConfig={egress="strict"} in the schema header to keep the boundary.
A warning rather than a hard error: permissive is a legitimate choice when the operator knows the broker is the only boundary, and failing closed would break existing setups.
Worth considering whether the broker should surface the same thing on proxy start --expose, since that is where the schema author is standing. The guest has the better signal (it can see the proxy env), so the guest warning is the primary one.
Docs
The Docker Sandboxes guide now requires strict for this topology and explains why: #995. This issue is about catching it at runtime for the cases the docs do not cover.
What happens
When an agent inside a network-restricted sandbox runs
varlock proxy run --url, its requests ride the tunnel and exit from the broker's machine. The sandbox's own egress allowlist only ever sees the connection to the broker. If the broker's schema uses the defaultegress="permissive", every unmatched request passes through untouched, so the agent reaches anything the broker can reach.The net effect is that wiring up a varlock broker silently converts a deny-by-default sandbox into open egress, and neither side reports it. The sandbox's policy log shows one allowed connection to the broker; varlock's audit log shows requests being allowed as designed.
Reproduced
Docker Sandboxes (
sbx0.38.0), Balanced preset, broker on the host with the default egress mode. Onlylocalhost:8080(the broker) allowed insbx policy:Adding
@proxyConfig={egress="strict"}to the schema closes it (CONNECT tunnel failed, response 403).Also reproduced against a stand-in HTTP CONNECT gateway with a one-entry allowlist, so this is not specific to Docker Sandboxes. It applies to any guest whose only egress is a filtering proxy: sbx, and the same shape on E2B or Fly.io network rules.
Suggested behavior
proxy run --urlcan detect the situation cheaply. At startup it already inspectsHTTP_PROXY/HTTPS_PROXY/ALL_PROXYto decide whether to dial the tunnel through a CONNECT proxy (proxyForTunnelUrlinpackages/varlock/src/proxy/tunnel.ts). If a proxy applies to the tunnel URL, the guest's egress is filtered by something other than varlock, and the broker's egress mode determines whether that filtering still means anything.The bootstrap payload would need to carry the broker's egress mode so the guest can tell. Then, when a tunnel proxy applies and the broker is permissive, print a warning along the lines of:
A warning rather than a hard error: permissive is a legitimate choice when the operator knows the broker is the only boundary, and failing closed would break existing setups.
Worth considering whether the broker should surface the same thing on
proxy start --expose, since that is where the schema author is standing. The guest has the better signal (it can see the proxy env), so the guest warning is the primary one.Docs
The Docker Sandboxes guide now requires
strictfor this topology and explains why: #995. This issue is about catching it at runtime for the cases the docs do not cover.