PandaStack
Security

Isolation model

Every sandbox, app, and database runs in its own Firecracker microVM with its own kernel — hardware virtualization, not a shared container kernel.

PandaStack runs untrusted code. The isolation boundary reflects that: every sandbox, every deployed app, and every managed database is its own Firecracker microVM — a full hardware-virtualized guest with its own Linux kernel, its own network namespace and TAP device, and its own copy-on-write disk. Nothing you run shares a kernel with another tenant.

Firecracker is the KVM-based virtual machine monitor AWS built for Lambda and Fargate. PandaStack uses it unmodified (v1.16), so the isolation boundary is the same one those services rely on for multi-tenant workloads.

What the boundary is

LayerPer-workload resourceMechanism
CPU / memoryDedicated guest kernel (Linux 5.10) on KVM vCPUsHardware virtualization (VT-x/EPT)
Device surfaceMinimal virtio device model (block, net, vsock)Firecracker — no PCI passthrough, no BIOS, no legacy device emulation
NetworkDedicated Linux network namespace + TAP device, unique /30 subnetPer-VM netns; explicit top-of-chain firewall drops between tenants
DiskPrivate copy-on-write rootfs clone (XFS reflink)Block-level CoW; writes are private to the VM from the first byte
Memory sharingSnapshot pages mapped MAP_PRIVATEKernel CoW — a VM's writes never reach the shared snapshot or any sibling

A guest that gets root inside its VM — which is the normal, supported state for a sandbox — is still on the wrong side of a hardware virtualization boundary. To touch another tenant it would need a guest-to-host escape through KVM or Firecracker's device model, not a container breakout.

Compared with containers and gVisor

An honest comparison, since "isolated" means different things across sandboxing products:

  • Containers (namespaces + cgroups + seccomp) share the host kernel. Every syscall untrusted code makes is handled by the same kernel that serves every other tenant, so the attack surface is the full syscall interface and kernel escapes are container escapes. Containers are a packaging boundary; for arbitrary untrusted code they are not, by themselves, a security boundary.
  • gVisor narrows that by intercepting syscalls in a user-space kernel, which is a real improvement over plain containers — at the cost of syscall compatibility gaps and I/O overhead, and the host kernel is still ultimately underneath.
  • Firecracker microVMs give each workload its own guest kernel behind hardware virtualization. The host-facing surface is KVM plus a deliberately tiny device model (Firecracker is ~50k lines of Rust with no BIOS and no legacy devices), rather than the whole syscall interface. The trade-off used to be boot time and density; PandaStack's snapshot-restore path (how it works) removes that — VMs restore in well under a second, so you get VM isolation at container-like latency.

To be equally honest about what a microVM does not do: the host kernel and KVM must still be correct (we track Firecracker and kernel updates), the network and disk plumbing around the VM is host-side code, and CPU side channels are mitigated at the host level, not eliminated by virtualization. The claim is a much smaller, battle-tested attack surface — not magic.

Network isolation

Each VM lives in a dedicated Linux network namespace containing exactly one TAP device, connected to the host over a veth pair with a unique /30. Namespacing alone doesn't prevent cross-tenant traffic, so we don't rely on it: an explicit DROP rule, inserted at the top of the host's FORWARD chain and pinned by unit tests, blocks all VM-to-VM traffic across the pool. A second top-of-chain drop blocks the link-local range, so a guest cannot reach the cloud metadata service (the classic SSRF-to-cloud-credentials path).

The full ruleset, ordering guarantees, and self-hosting caveats are documented in internals: networking.

Disk and memory isolation

A sandbox's rootfs is a reflink (block-level CoW) clone of its template image — O(metadata) to create, and every write goes to blocks private to that VM. Forked sandboxes share unwritten blocks and unwritten memory pages with their parent, but sharing is strictly read-only: after a fork, neither side can observe the other's writes. Details in internals: fork & copy-on-write.

What this means per product

  • Sandboxes — untrusted, agent-generated code runs as root in its own VM. That's the designed-for case, not an edge case.
  • Apps — each app's build and runtime happen inside a persistent VM belonging to that app. A compromised dependency in one tenant's build cannot see another tenant's.
  • Managed databases — every database is a dedicated PostgreSQL VM with a dedicated durable volume. There is no shared PostgreSQL cluster and no shared kernel between databases.

Going deeper

PandaStack is Apache-2.0 open source, so none of the above has to be taken on faith — the isolation code paths cited on those pages are public and auditable.

On this page