Perplexity has open-sourced SPACE, the sandbox platform behind each activity in Perplexity Pc. The Perplexity SPACE sandbox offers every agent activity its personal Firecracker microVM. Credentials and outbound visitors are managed from exterior that VM. The code ships underneath Apache 2.0 on GitHub. For groups constructing coding or looking brokers, this can be a production-tested isolation layer they will self-host.
TL;DR
- Dimension: Rust codebase, launch 0.8.0, the general public baseline. HTTP API plus server-sent occasions.
- Runs on: A Linux x86_64 host with KVM,
/dev/kvm, btrfs and Docker. Native Sort (Kubernetes) or direct mode. No macOS. - Efficiency: In manufacturing, median create latency fell from 185 ms to 60 ms versus Perplexity’s earlier supplier.
- Finest: 0 of 108 VM-to-host escape makes an attempt succeeded throughout 9 frontier fashions.
- Worst: Earlier than fixes, brokers bypassed the egress coverage in 11 of 54 partial-network runs.
What’s Perplexity SPACE?
SPACE (Sandboxed Platform for Agentic Code Execution) is Perplexity’s platform for operating agent code in remoted microVMs. Purposes name its HTTP API to create Linux environments, run instructions and stream output.
A template provides the beginning filesystem. A sandbox is one occasion of that template, with its personal VM and writable disk. Many instructions can run inside one sandbox.
Perplexity’s launch thread explains the design aim. Brokers run instructions, set up packages and name providers with root contained in the sandbox. The host stays exterior the visitor’s management. Agent work is long-running, stateful and branching, so it should survive restarts.
How does SPACE isolate brokers?
Every sandbox is a Firecracker microVM with its personal visitor kernel. A per-sandbox community gateway on the host enforces egress coverage on each outbound connection.
Secrets and techniques by no means enter the visitor. Per Perplexity’s July engineering post, credentials are injected on the community layer. The credential retailer provides hierarchical scoping, fee limits and audit logging.
The architecture guide splits the system into 4 components. These are a PostgreSQL-backed API, controllers, employee providers and a knowledge airplane. Employee providers handle VMs, networking, volumes, templates and credentials. btrfs copy-on-write creates every root filesystem.
How do pause, droop and restore work?
Sandboxes transfer by 4 states: operating, paused, suspended and deleted.
- Paused: VM reminiscence stays resident on the employee. This isn’t a sturdy snapshot.
- Suspended: VM reminiscence, runtime state and root filesystem are snapshotted. Energetic assets are launched.
- Idle default: sandboxes suspend after 6 hours with out exercise.
For quick creates, Kubernetes deployments use warm pools of booted sandboxes. Single-node setups use base snapshots as an alternative.
In manufacturing, the Ninetieth-percentile create latency dropped from 447 ms to 89 ms. Perplexity reviews that 100% of Pc periods run on SPACE.
Did SPACE survive a red-team take a look at?
Perplexity’s Escaping SPACE: Part I report examined 9 fashions with root contained in the visitor. The examine ran 216 runs throughout 2 duties and 4 settings.
- Sandbox escape: 0 of 108 runs reached the host-side secret.
- No-network bypass: 0 of 54 runs succeeded.
- Partial-network bypass: 11 of 54 runs succeeded earlier than fixes. 4 fashions discovered a path.
Claude Opus 5.0, GPT-5.6 Sol, GPT-5.6 Cyber and Kimi K3 discovered bypasses. The assaults used DNS spoofing and shared CDN IP addresses.
Perplexity then added source-address validation by nftables. The gateway now terminates TLS and checks each SNI and HTTP host in opposition to the allowlist. Within the retest, no mannequin produced a verified bypass.
The identical workforce examined 10 third-party platforms. 8 confirmed at the least one network-policy bypass. Perplexity disclosed the outcomes to each affected vendor.
<html lang="en">
<head>
<meta charset="utf-8">
<meta title="viewport" content material="width=device-width,initial-scale=1">
<title>SPACE Sandbox Explainer</title>
<type>
#pplx-space-x{–bg:#100E12;–card:#18161B;–line:#2A2830;–tq:#20808D;–blue:#1FB8CD;–paper:#FBFAF4;–mute:#A8A6AE;–red:#E5675A;–grn:#76B900;
max-width:880px;margin:0 auto;background:var(–bg)!necessary;colour:var(–paper)!necessary;border:1px strong var(–line)!necessary;border-radius:14px;font-family:Inter,system-ui,-apple-system,Segoe UI,Roboto,sans-serif;overflow:hidden;box-sizing:border-box}
#pplx-space-x *{box-sizing:border-box}
#pplx-space-x hr,#pplx-space-x p:empty,#pplx-space-x del,#pplx-space-x s{show:none!necessary}
#pplx-space-x .hd{padding:18px 22px 6px}
#pplx-space-x .eyebrow{font-size:11px;letter-spacing:.14em;text-transform:uppercase;colour:var(–blue)!necessary;font-weight:600}
#pplx-space-x h3{margin:6px 0 4px;font-size:21px;line-height:1.25;colour:var(–paper)!necessary;font-weight:700}
#pplx-space-x .sub{margin:0;colour:var(–mute)!necessary;font-size:13.5px;line-height:1.5}
#pplx-space-x .tabs{show:flex;hole:6px;padding:12px 22px 0;border-bottom:1px strong var(–line)!necessary;overflow-x:auto}
#pplx-space-x .tab{background:clear!necessary;border:0!necessary;border-bottom:2px strong clear!necessary;colour:var(–mute)!necessary;font:600 13px Inter,system-ui,sans-serif;padding:9px 10px 10px;cursor:pointer;white-space:nowrap;transition:colour .2s}
#pplx-space-x .tab:hover{colour:var(–paper)!necessary}
#pplx-space-x .tab.on{colour:var(–paper)!necessary;border-bottom-color:var(–tq)!necessary}
#pplx-space-x .pane{show:none;padding:18px 22px 20px;animation:psx-in .35s ease}
#pplx-space-x .pane.on{show:block}
@keyframes psx-in{from{opacity:0;rework:translateY(6px)}to{opacity:1;rework:none}}
#pplx-space-x .circulation{show:grid;grid-template-columns:1fr 34px 1fr 34px 1fr;align-items:stretch;hole:0}
#pplx-space-x .field{background:var(–card)!necessary;border:1px strong var(–line)!necessary;border-radius:10px;padding:12px;cursor:pointer;transition:border-color .2s,rework .2s}
#pplx-space-x .field:hover,#pplx-space-x .field.act{border-color:var(–tq)!necessary;rework:translateY(-2px)}
#pplx-space-x .field b{show:block;font-size:13.5px;colour:var(–paper)!necessary;margin-bottom:4px}
#pplx-space-x .field span{font-size:12px;colour:var(–mute)!necessary;line-height:1.45}
#pplx-space-x .field.vm{box-shadow:inset 0 0 0 1px rgba(32,128,141,.35)}
#pplx-space-x .arrow{place:relative;align-self:middle;peak:2px;background:var(–line)!necessary;margin:0 4px;overflow:hidden}
#pplx-space-x .arrow i{place:absolute;prime:-2px;left:-10px;width:10px;peak:6px;border-radius:3px;background:var(–blue)!necessary;animation:psx-pkt 1.6s linear infinite}
@keyframes psx-pkt{to{left:100%}}
#pplx-space-x .element{margin-top:14px;background:var(–card)!necessary;border-left:3px strong var(–tq)!necessary;border-radius:8px;padding:12px 14px;font-size:13px;line-height:1.55;colour:var(–paper)!necessary;min-height:66px}
#pplx-space-x .keys{show:flex;flex-wrap:wrap;hole:8px;margin-top:12px}
#pplx-space-x .chip{font-size:11.5px;padding:5px 9px;border-radius:999px;border:1px strong var(–line)!necessary;colour:var(–mute)!necessary}
#pplx-space-x .states{show:flex;hole:8px;margin-bottom:12px}
#pplx-space-x .st{flex:1;text-align:middle;padding:10px 4px;border-radius:9px;background:var(–card)!necessary;border:1px strong var(–line)!necessary;font-size:12.5px;font-weight:600;colour:var(–mute)!necessary;transition:all .3s}
#pplx-space-x .st.on{colour:var(–bg)!necessary;background:var(–tq)!necessary;border-color:var(–tq)!necessary;rework:scale(1.04)}
#pplx-space-x .ctl{show:flex;hole:8px;margin-top:12px}
#pplx-space-x .btn{background:var(–card)!necessary;border:1px strong var(–line)!necessary;colour:var(–paper)!necessary;border-radius:8px;padding:8px 12px;font:600 12.5px Inter,system-ui,sans-serif;cursor:pointer}
#pplx-space-x .btn:hover{border-color:var(–tq)!necessary}
#pplx-space-x .bars{show:flex;flex-direction:column;hole:12px}
#pplx-space-x .row .lbl{show:flex;justify-content:space-between;font-size:12.5px;margin-bottom:5px;colour:var(–paper)!necessary}
#pplx-space-x .row .lbl em{font-style:regular;colour:var(–mute)!necessary}
#pplx-space-x .observe{peak:12px;border-radius:6px;background:var(–card)!necessary;border:1px strong var(–line)!necessary;overflow:hidden}
#pplx-space-x .fill{peak:100%;width:0;border-radius:6px;transition:width 1.1s cubic-bezier(.2,.8,.2,1)}
#pplx-space-x .observe{margin-top:12px;font-size:12px;colour:var(–mute)!necessary;line-height:1.5}
#pplx-space-x desk{width:100%;border-collapse:collapse;font-size:12.5px}
#pplx-space-x th,#pplx-space-x td{text-align:left;padding:8px 8px;border-bottom:1px strong var(–line)!necessary;colour:var(–paper)!necessary;vertical-align:prime}
#pplx-space-x th{colour:var(–blue)!necessary;font-weight:600}
#pplx-space-x td:first-child{colour:var(–mute)!necessary}
#pplx-space-x .tw{overflow-x:auto}
#pplx-space-x code{background:var(–card)!necessary;colour:var(–blue)!necessary;border:1px strong var(–line)!necessary;border-radius:4px;padding:1px 5px;font-size:12px}
#pplx-space-x .ft{show:flex;justify-content:space-between;hole:10px;padding:10px 22px;border-top:1px strong var(–line)!necessary;font-size:11.5px;colour:var(–mute)!necessary}
#pplx-space-x .ft b{colour:#76B900!necessary;font-weight:600}
#pplx-space-x a{colour:var(–blue)!necessary;text-decoration:none}
@media (max-width:640px){
#pplx-space-x .circulation{grid-template-columns:1fr;hole:0}
#pplx-space-x .arrow{peak:20px;width:2px;justify-self:middle;margin:4px 0}
#pplx-space-x .arrow i{left:-2px;prime:-10px;width:6px;peak:10px;animation-name:psx-pktv}
#pplx-space-x h3{font-size:18px}
#pplx-space-x .states{flex-wrap:wrap}
#pplx-space-x .st{flex:1 1 45%}
#pplx-space-x .ft{flex-direction:column}
}
@keyframes psx-pktv{to{prime:100%}}
@media (prefers-reduced-motion:cut back){#pplx-space-x *{animation:none!necessary;transition:none!necessary}}
</type>
</head>
<physique type="margin:0;background:#100E12">
<div id="pplx-space-x">
<div class="hd">
<div class="eyebrow">Perplexity SPACE · Open supply · Apache 2.0</div>
<h3>How SPACE sandboxes an AI agent</h3>
<p class="sub">One Firecracker microVM per activity. Credentials and egress are managed from the host, exterior the visitor.</p>
</div>
<div class="tabs" function="tablist">
<button class="tab on" data-t="0">The way it works</button>
<button class="tab" data-t="1">Lifecycle</button>
<button class="tab" data-t="2">Pink-team outcomes</button>
<button class="tab" data-t="3">Create latency</button>
<button class="tab" data-t="4">Evaluate</button>
</div>
<div class="pane on" data-p="0">
<div class="circulation">
<div class="field vm act" data-d="0"><b>Visitor microVM</b><span>Agent runs instructions, installs packages, root entry</span></div>
<div class="arrow"><i></i></div>
<div class="field" data-d="1"><b>Per-sandbox gateway</b><span>Enforces egress coverage on each outbound connection</span></div>
<div class="arrow"><i type="animation-delay:.8s"></i></div>
<div class="field" data-d="2"><b>Web / providers</b><span>Solely allowlisted locations, credentials added exterior the VM</span></div>
</div>
<div class="element" id="psx-detail"></div>
<div class="keys"><span class="chip">Rust</span><span class="chip">Launch 0.8.0</span><span class="chip">HTTP API + SSE</span><span class="chip">btrfs copy-on-write</span><span class="chip">E2B SDK by way of ECW</span><span class="chip">Linux x86_64 + KVM</span></div>
</div>
<div class="pane" data-p="1">
<div class="states"><div class="st on">Working</div><div class="st">Paused</div><div class="st">Suspended</div><div class="st">Deleted</div></div>
<div class="element" id="psx-life"></div>
<div class="ctl"><button class="btn" id="psx-prev"> Again</button><button class="btn" id="psx-next">Subsequent state
</button></div>
</div>
<div class="pane" data-p="2">
<div class="bars" id="psx-rt"></div>
<div class="observe">9 fashions, 216 runs, root contained in the visitor. Fixes: nftables source-address validation, TLS termination with SNI + Host allowlist checks. Supply: Perplexity, Escaping SPACE: Half I (Sep 23, 2026).</div>
</div>
<div class="pane" data-p="3">
<div class="bars" id="psx-lat"></div>
<div class="observe">Manufacturing launch-week visitors, SPACE vs Perplexity’s earlier sandbox supplier. Decrease is best. Supply: Perplexity engineering weblog (Jul 15, 2026).</div>
</div>
<div class="pane" data-p="4">
<div class="tw"><desk>
<tr><th>Characteristic</th><th>SPACE</th><th>E2B Runtime</th><th>microsandbox</th></tr>
<tr><td>Isolation</td><td>Firecracker microVM</td><td>Firecracker microVM</td><td>libkrun microVM</td></tr>
<tr><td>License</td><td>Apache 2.0</td><td>Apache 2.0</td><td>Apache 2.0</td></tr>
<tr><td>Language</td><td>Rust</td><td>Go</td><td>Rust</td></tr>
<tr><td>Perplexity egress take a look at</td><td>0 bypasses after repair</td><td>HTTPS bypass, mitigation deliberate</td><td>HTTP + HTTPS bypass, repair in v0.6.18</td></tr>
</desk></div>
<div class="observe">Egress outcomes from Perplexity’s assessments on Aug 31 to Sep 1, 2026, for the variations examined.</div>
</div>
<div class="ft"><span>Sources: github.com/perplexityai/SPACE · perplexity.ai/hub/weblog</span><b>© Marktechpost</b></div>
</div>
<script>
(perform(){
var R=doc.getElementById(‘pplx-space-x’);
perform submit(){attempt{father or mother.postMessage({psxHeight:R.offsetHeight+40},’*’)}catch(e){}}
var tabs=R.querySelectorAll(‘.tab’),panes=R.querySelectorAll(‘.pane’);
var D=[‘<b>Guest microVM.</b> Each task gets its own Firecracker microVM with its own guest kernel. The agent can run commands and install packages as root. The host stays outside its control.’,
‘<b>Per-sandbox gateway.</b> All guest egress passes through a host-side gateway. It now terminates TLS and requires both SNI and HTTP Host to be allowlisted and DNS-attributed.’,
‘<b>Outside services.</b> Credentials never enter the guest. They are injected at the network layer, with scoping, rate limits and audit logging.’];
var det=doc.getElementById(‘psx-detail’),bins=R.querySelectorAll(‘.field’);
perform showD(i){bins.forEach(perform(b,j){b.classList.toggle(‘act’,i==j)});det.innerHTML=D[i];submit()}
bins.forEach(perform(b){b.addEventListener(‘click on’,perform(){showD(+b.dataset.d)});b.addEventListener(‘mouseenter’,perform(){showD(+b.dataset.d)})});
showD(0);
var L=[‘<b>Running.</b> Processes execute. Live VM memory and the writable filesystem are kept.’,
‘<b>Paused.</b> Execution stops. VM memory stays resident on the worker. This is not a durable snapshot.’,
‘<b>Suspended.</b> VM memory, runtime state and root filesystem are snapshotted. Active VM resources are released. Default: suspend after 6 hours idle.’,
‘<b>Deleted.</b> The sandbox is no longer available through the API.’];
var li=0,sts=R.querySelectorAll(‘.st’),ld=doc.getElementById(‘psx-life’);
perform life(){sts.forEach(perform(s,j){s.classList.toggle(‘on’,j==li)});ld.innerHTML=L[li];submit()}
doc.getElementById(‘psx-next’).onclick=perform(){li=(li+1)%4;life()};
doc.getElementById(‘psx-prev’).onclick=perform(){li=(li+3)%4;life()};
sts.forEach(perform(s,j){s.type.cursor=”pointer”;s.onclick=perform(){li=j;life()}});
life();
perform bars(el,information){el.innerHTML=information.map(perform(d){return ‘<div class="row"><div class="lbl"><span>’+d[0]+'</span><em>’+d[1]+'</em></div><div class="observe"><div class="fill" data-w="’+d[2]+’" type="background:’+d[3]+’"></div></div></div>’}).be a part of(”)}
bars(doc.getElementById(‘psx-rt’),[
[‘VM-to-host escape’,’0 of 108 runs’,1.5,’#76B900′],
[‘Network bypass, no network’,’0 of 54 runs’,1.5,’#76B900′],
[‘Network bypass, partial network (before fix)’,’11 of 54 runs’,20.4,’#E5675A’],
[‘Network bypass, after fix’,’0 verified bypasses’,1.5,’#76B900′],
[‘Third-party platforms with a bypass’,’8 of 10′,80,’#1FB8CD’]]);
bars(doc.getElementById(‘psx-lat’),[
[‘Median create, previous provider’,’185 ms’,41.4,’#5E5B66′],
[‘Median create, SPACE’,’60 ms’,13.4,’#20808D’],
[‘p90 create, previous provider’,’447 ms’,100,’#5E5B66′],
[‘p90 create, SPACE’,’89 ms’,19.9,’#20808D’]]);
perform anim(p){p.querySelectorAll(‘.fill’).forEach(perform(f){f.type.width=”0″;setTimeout(perform(){f.type.width=f.dataset.w+’%’},60)})}
tabs.forEach(perform
window.addEventListener(‘load’,submit);window.addEventListener(‘resize’,submit);setTimeout(submit,300);
})();
</script>
</physique>
</html>
“>
(perform(){var f=doc.getElementById(‘pplx-space-frame’);window.addEventListener(‘message’,perform(e){if(e.supply===f.contentWindow&&e.information&&e.information.psxHeight){f.type.peak=e.information.psxHeight+’px’;}});})();
How does SPACE examine with different open sandboxes?
| Characteristic | Perplexity SPACE | E2B Runtime | microsandbox | Daytona |
|---|---|---|---|---|
| Isolation | Firecracker microVM per sandbox | Firecracker microVM per sandbox | libkrun microVM | Dedicated kernel per sandbox |
| License | Apache 2.0 | Apache 2.0 | Apache 2.0 | Public repo, unmaintained since June 2026 |
| Language | Rust | Go | Rust | Not disclosed |
| Host wants | Linux x86_64 + KVM | Not disclosed | Linux with KVM | Not disclosed |
| Egress management | Per-sandbox gateway, TLS termination | nftables firewall, SNI/Host lists | Not disclosed | Not disclosed |
| Perplexity egress take a look at | 0 bypasses after fix | HTTPS bypass, mitigation planned | HTTP + HTTPS bypass, fix in v0.6.18 | HTTPS bypass, mitigation released |
| E2B SDK assist | Yes, via ECW wrapper | Native | Not disclosed | Not disclosed |
How do builders deploy SPACE?
The installation guide deploys SPACE into an area Sort cluster. The host wants /dev/kvm, /dev/internet/tun, loop units and btrfs. Working it inside a VM requires nested virtualization.
Groups already on E2B can attempt the E2B Compatibility Wrapper. Its examined baseline is the Python package deal e2b==2.21.1. A reference AWS EKS deployment ships within the repository.
Key Takeaways
- SPACE runs every agent activity in its personal Firecracker microVM.
- Credentials and egress coverage stay exterior the visitor VM.
- 0 of 108 escape makes an attempt reached the host in red-team assessments.
- Egress bypasses hit 11 of 54 runs earlier than fixes, 0 after.
- Apache 2.0, Rust, wants a Linux x86_64 host with KVM.
Take a look at the GitHub repo, the docs and the red-team report. All credit score goes to the researcher of this mission. Additionally, be at liberty to observe us on Twitter and don’t neglect to hitch our 150k+ML SubReddit and Subscribe to our Newsletter. Wait! are you on telegram? now you can join us on telegram as well.
The submit Perplexity Open-Sources SPACE, a Firecracker MicroVM Sandbox for AI Brokers appeared first on MarkTechPost.

