SANDBOX · EGRESS POLICY

Agent sandboxing: deny outbound network from untrusted code

Run untrusted code that tries six outbound paths and see which ones each egress policy, resolver and loopback setting actually closes.

Computed experiment · sixty inspection seconds

Your experiment

The code needs one partner API. It also tries a package index, a raw IP, the cloud metadata address, a DNS name that encodes data and a credential sidecar on loopback. Start with the denylist and close each path one control at a time.

Play replays the computed run over sixty inspection seconds; Next event steps, Restart rewinds, and Inspection time scrubs. Any input change recomputes the run and rewinds it without autoplay.

Event trace

    Computed data

    Final metrics

    Policy model, not a sandbox. The egress proxy decides by destination host name; raw IP addresses carry no host name; DNS queries bypass the proxy unless forced through the policy resolver; loopback traffic never reaches the proxy and depends only on the sandbox network namespace. Real containment also needs process, file-system and credential isolation. Addresses are documentation examples; nothing is contacted.

    Six ways out of a sandbox

    The untrusted code legitimately needs one host, api.partner.example. It also tries pypi.org, the raw address 203.0.113.10, the metadata address 169.254.169.254 that serves cloud credentials, a DNS query whose name encodes data under exfil.attacker.test, and a credential sidecar on 127.0.0.1. Anything other than the partner API that gets out counts as unwanted egress.

    A denylist closes almost nothing

    The opening Egress proxy policy denies *.attacker.test. None of the six attempts is blocked: pypi.org and the raw IP are not on the list, the metadata address is not a host name, the DNS query goes straight to an outside resolver that the proxy never sees, and loopback never passes the proxy. Five unwanted destinations are reachable. Check Block the link-local metadata address and Force DNS through the policy resolver: the metadata call and the DNS name are refused, but pypi.org, the raw IP and the sidecar remain.

    Allowlist, resolver and namespace together

    Choose Allowlist the task API only. pypi.org, the raw IP and the metadata address are now blocked because they are not the allowlisted host, yet the DNS query and the loopback sidecar still get out. Add Force DNS through the policy resolver and clear Sandbox can reach the host loopback: the run reports zero unwanted egress with the partner API still working. That combination, not any single switch, contains this fixture.

    Deny-all and the allowlist entry

    Choose Deny all egress with loopback still reachable: one unwanted path remains, the sidecar, and the needed partner API is blocked too, so the job fails. Clear loopback and nothing escapes, but the task still cannot work. On the allowlist policy, clear Task API host is on the allowlist; this control only matters for the allowlist policy, and clearing it blocks the needed API exactly like deny-all.

    Inspecting the run and its limits

    Play, Next event, Restart, Speed and Inspection time step through the six connection attempts and the verdict across sixty seconds; the table lists each destination, whether the task needs it, the decision and the reason. This is a policy model: nothing is executed or contacted, host names are documentation examples, and IPv6, proxies inside the sandbox, covert timing channels and the process and file-system isolation that a real sandbox also needs are out of scope.