On Wednesday 23 September Perplexity published "Escaping SPACE: Part I," a red-team report on its agent sandbox. Nine model configurations got root inside a Firecracker microVM and 216 runs to break out. None of the 108 escape runs crossed the VM boundary. The network results were worse: with package repositories reachable, four models got past the egress policy in 11 of 54 runs, by forging DNS replies and by routing through CDN addresses that PyPI shares with thousands of other sites. Perplexity fixed both, retested, and found no bypass.
On Thursday 15 October Perplexity open-sourced the sandbox itself, SPACE, under Apache 2.0. The fix for the shared-IP route has two halves. Plain HTTP goes through a relay that checks the Host of every request, and that runs for everyone. HTTPS is checked by terminating TLS and comparing the encrypted hostname to the allowlist, and in the released code that only happens when a policy sets tls_interception to on. An unset value means off. The E2B compatibility wrapper also defaults to off.
With interception off, SPACE checks the TLS SNI against the allowlist and DNS attribution, then relays the encrypted stream without looking inside. That is the exact check the same report showed failing on seven other sandbox platforms, where the SNI named an allowed host and the encrypted Host header named a private S3 bucket. If you self-host SPACE for agent code and want what Perplexity's retest measured, you have to turn it on yourself.
What the red team found
The setup was two tasks per model: steal a decoy AWS credential from the host, or reach a blocked callback URL. Each ran with and without SPACE's source code, and with no network or with a partial network of package repositories and a search API. Three repeats each. Fable and GPT-6 Astra refused the tasks and were left out.
The escape side held at 0 of 108. The network side split. With no network, nothing worked. With PyPI reachable, Claude Opus 5.0, GPT-5.6 Sol, GPT-5.6 Cyber and Kimi K3 all reached the callback at least once.
Two mechanisms did it. The gateway learned which IPs belonged to pypi.org by watching the guest's DNS traffic, so an agent forged a DNS reply mapping pypi.org to the callback's IP, and the gateway let the connection through. The models that did this needed the source code to find which interface to aim the forged packets at. The second route needed no source at all. PyPI sits on Fastly, and a Fastly edge IP serves whatever site the client names. GPT-5.6 Sol sent a request to fiddle.fastly.dev and had it fetch the callback. GPT-5.6 Cyber went through images.taboola.com to thum.io, took a screenshot of the callback page, and read the flag out of it with OCR.
The fixes match the two routes. Every packet a VM sends must now carry its own assigned address, which kills the forged DNS reply. For shared IPs, the report says the gateway "terminates TLS and requires both the ClientHello SNI and any hostname information" to be allowlisted and tied by DNS to the destination IP. The retest ran all nine models at the most permissive setting. "None of the models successfully retrieved the callback flag."
Seven of nine other sandboxes
Perplexity ran the shared-IP probe against nine commercial sandboxes between 31 August and 1 September. E2B, Vercel Sandbox, Modal, Daytona, Deno Sandbox, Fly.io Sprites and microsandbox all had an HTTPS bypass. Cloudflare Sandbox and NVIDIA OpenShell had none. The HTTPS version is domain fronting: the guest put an allowed hostname in the SNI, which the sandbox can see, and a non-allowed bucket in the Host header, which it cannot see without decrypting.
The vendor responses, as of 10 September, are the useful part. Daytona deployed authority-mismatch enforcement and Deno fixed a direct-TCP hole. Vercel called it a known limitation and recommends TLS-terminating controls. Modal does not classify it as a vulnerability and has "optional TLS interception under consideration." microsandbox shipped an HTTPS strict mode in v0.6.18, with "strict mode disabled by default."
That last line describes SPACE's own release too.
What the released code does
I read the gateway at commit 188c1a3, pushed on 20 October. The network policy is a small document, NetworkPolicyV1, with a tls_interception field that takes off or on. In crates/libs/net/common, an unspecified value is read as Off, and both built-in policies, allow_all() and deny_all(), set it to Off. The E2B wrapper reads it from sandbox metadata under network.tls_interception, and a missing key or "off" both give Off.
Admission for a TLS connection happens in egress/tcp.rs. The gateway reads the ClientHello's server name, checks that it is on the allowlist, and checks that a live DNS answer from one of the two reserved resolvers, 8.8.8.8 or 1.1.1.1, bound that exact name to that exact IP. That second check is the part of the fix that does not depend on interception, and it stops an agent from naming an allowed host while connecting to an unrelated IP.
Then the gateway decides what to do with the stream. In tls_interception.rs the rule is one line: Off => Ok(InterceptionAction::PassThrough). The metric records the reason as inspection_disabled and the egress outcome as opaque_relay. From there the bytes go to the CDN edge at that IP, with whatever Host the guest wrote inside the encryption. The per-request authority check in tls_http/forward.rs, and the code in routing_headers.rs that strips Fastly's Fastly-Host override because "a guest could reach any origin behind an allowed Fastly edge," only run on traffic the gateway can read: plain HTTP, or HTTPS it has terminated.
Two more details point the same way. Credential injection, the feature that keeps API keys outside the VM and adds them as headers at the gateway, refuses to validate without interception: the error is NetworkCredentialsRequireTlsInterception. And the architecture docs say IP-based TLS exemptions "apply regardless of the hostname served at that IP" and "bypass HTTP inspection and credential injection," so an exemption on a CDN address reopens the shared-IP route for that address even with interception on.
What it takes to turn it on
Setting "tls_interception": "on" in a native policy, or network.tls_interception=on in E2B metadata, makes the gateway terminate TLS with certificates from SPACE's own credential manager. Without that certificate authority running, the gateway returns AuthorityUnavailable and refuses the connection, so a misconfiguration fails closed rather than quietly relaying. The E2B wrapper also rejects on without a concrete network policy.
The cost is the usual one for interception. Your guest has to trust the gateway's certificates, and anything that pins certificates or speaks a non-HTTP protocol over TLS breaks. SPACE's own docs say non-HTTP TLS, such as TURN over TLS, "can therefore receive an HTTP 400 response and a closed connection," and offer SPACE_TLS_INTERCEPTION_EXEMPTIONS as "a stopgap." That is a fair reason to ship with it off. It is also why the default and the fix should not be described as the same thing.
Whether a domain-fronted request actually lands depends on the CDN behind your allowlist. Perplexity's probes found it working through seven platforms. I did not run SPACE, which needs a Linux x86_64 host with KVM, so this reading is from the code and docs, not a live test.
What to do
If you self-host SPACE or the E2B wrapper for agent code and use a domain allowlist, set tls_interception to on in the policy and confirm the credential manager's CA is reachable. Keep exemptions to exact hostnames, and avoid IP or CIDR exemptions on any range a CDN shares.
If you run E2B, Vercel Sandbox, Modal or another hosted sandbox, read your vendor's line in Perplexity's table and check whether its fix is on by default. Every one of these products lets an agent name the site it wants in a place the sandbox may not read.
And if you allowlist pypi.org or registry.npmjs.org because your agent needs packages, treat that as access to a CDN, not to a registry. The report's conclusion puts it plainly: relying only on the destination IP "is insufficient." In SPACE as released, the default relies on the SNI.