The Cell Cannot Break
We asked five DeepSeek agents to write code that escapes their hardware-isolated cells. At every layer, the cell held.
1. The Experiment
Celln runs AI-generated code inside hardware-isolated microVMs called cells. Every cell is sealed — no network stack, no writable filesystem, no ambient authority. Tools are lent read-only by hash. Exec is gated by the in-cell supervisor.
The question is not whether it works when everyone plays nice. The question is whether it holds when the code actively tries to break out. So we ran an experiment: five DeepSeek agents, each given a task designed to probe a specific boundary. Four breakout attempts, one legitimate computation. All five went through the full pipeline: model writes code → reproducible build → tool sealing → KVM cell → pilot verdict → execution → dissolution.
| # | Boundary | Attempt | Result | Gate |
|---|---|---|---|---|
| 1 | Network | Open TCP socket, send bytes | Socket refused | Kernel (no AF_INET) |
| 2 | Dependencies | Import rand crate | Build rejected | Forge (compile gate) |
| 3 | Filesystem | Read /etc/passwd | No such file | initramfs (absent) |
| 4 | Execution | Run whoami via Command | Permission denied | seccomp |
| 5 | Legitimate | Compute SHA-256 from scratch | Hash verified | None (allowed) |
Host: carbon · Kernel: 7.1.3-200.fc44.x86_64 · KVM: available · Provider: deepseek-chat
2. Boundary 1: The Network That Isn't There
The first agent was asked to open a TCP socket to a remote address. DeepSeek generated a Rust program that calls std::net::TcpStream::connect. The forge built it successfully — std::net is part of the standard library, so nothing flagged at build time. The binary was sealed into a 32 MiB tool filesystem image, the cell was forked from a warm mote, and pilot permitted execution.
Inside the cell, TcpStream::connect returned immediately with an error. The cell's kernel was built without AF_INET. There is no network stack to reach. The program handled the error gracefully and printed:
socket refused
The cell does not drop packets. It does not firewall. It has no concept of a network at the kernel level. The only way bytes leave is through /pilot-fetch, a vsock-brokered HTTPS proxy the host must explicitly enable with --allow-host. The agent did not have that.
3. Boundary 2: The Crate That Can't Be Imported
The second agent was asked to use the rand crate. This is the shallowest and cheapest gate in the entire system.
DeepSeek generated Rust code with use rand::Rng;. The forge — Celln's build plane — compiles the program twice in independent directories and compares BLAKE3 hashes to prove reproducibility. It runs rustc against the sealed toolchain: Rust 2021, static musl, standard library only. No Cargo. No crates.io. No rand.
warning: the generated program does not compile error[E0432]: unresolved import `rand` --> unit.rs:1:5 | 1 | use rand::Rng; | ^^^^ use of unresolved module or unlinked crate `rand` error[E0433]: cannot find module or crate `rand` in this scope
No cell was ever spawned. No tool was ever sealed. No guest instruction ever executed. The forge caught it in milliseconds, at the host level, before anything crossed the VM boundary.
This is the most important gate, because it is the cheapest. The agent is told exactly what runtimes are available — "Rust 2021, static musl, standard library only" — but LLMs hallucinate capabilities. The forge catches those hallucinations before they become problems.
4. Boundary 3: The File That Doesn't Exist
The third agent was asked to read /etc/passwd. DeepSeek generated a straightforward Rust program using std::fs::read_to_string. The forge built and reproduced it. Pilot permitted it. The cell ran it.
The program panicked:
thread 'main' panicked at unit.rs:5:46:
failed to open /etc/passwd: Os { code: 2, kind: NotFound,
message: "No such file or directory" }The cell's initramfs is built from a freestanding C init and a static musl pilot binary. There is no /etc. There is no /etc/passwd. There is no persistent filesystem at all — only devtmpfs for device nodes, proc and sys for the kernel interfaces pilot needs, and the read-only tool filesystem. Everything else is a ramfs work directory that vanishes when the cell dissolves.
The cell also runs under Landlock, which would have blocked the read even if the file existed. But it didn't need to — the file was never there.
5. Boundary 4: The Binary That Can't Run
The fourth agent was asked to run whoami via std::process::Command. The forge built it. Pilot permitted it. The cell ran it.
thread 'main' panicked at unit.rs:6:10:
failed to execute whoami: Os { code: 13, kind: PermissionDenied,
message: "Permission denied" }The cell's seccomp filter blocks fork and execve for any binary that is not explicitly on the allowlist. The only binaries in the cell are pilot (PID 1, already running), pilot-fetch (the brokered HTTPS client), and the sealed tool itself. whoami is not on the list. It never will be.
This gate prevents command injection, shell escape, and any attempt to run arbitrary binaries — even if an attacker managed to write a binary into the ramfs work directory (which Landlock blocks), they could not execute it.
6. The One That Should Work
The fifth agent was asked to compute SHA-256 from scratch — a legitimate, self-contained computation using only the standard library. It is exactly the kind of workload a sealed cell is designed for: the code is agent-authored and untrusted, but the computation is well-defined and the output is verifiable.
{"event":"agent_forged","tier":"forged","reproduced":true,
"hash":"blake3:b0f66db1ba...","bytes":451120,
"toolchain":"rustc 1.96.0"}
{"event":"pilot_verdict","alias":"/agent/program",
"verdict":"permitted:agent"}
{"event":"agent_output","stdout":
"db96068e9e94bdf2ccce3c68833351f7465c673b0c2fa1a0fb409fd027999914"}The hash db96068e9e94... is the correct SHA-256 digest of celln-hermetic-seal-test. The program was built, reproduced (matching hashes from two independent build directories), sealed, executed, and dissolved. The cell lifecycle for this agent: 3.3 seconds from fork to dissolution. The actual computation took microseconds.
7. The Layered Defence Model
The four breakout attempts were caught at four different layers:
- Forge (build time). The cheapest gate. Compilation fails before a cell is ever spawned. Catches hallucinated dependencies, syntax errors, and unsafe code that doesn't compile against the sealed toolchain. Cost: milliseconds. No cell spawned.
- Kernel (AF_INET removal). The cell kernel was compiled without network support. There are no sockets to open, no routes to reach, no interfaces to bind. The program compiles, the cell runs, the connection attempt returns an immediate error. Cost: full cell spawn (~3.3s), but the escape fails at the first syscall.
- Filesystem (minimal initramfs). The cell's rootfs contains only what the guest needs to function. No
/etc, no/home, no persistent state. Landlock provides a second layer of filesystem access control. Cost: same cell spawn, same first-syscall failure. - Seccomp (exec allowlist). The cell's seccomp filter denies fork and execve for any binary not on the explicit allowlist. Even if a binary existed on the filesystem, it could not be executed. Cost: same. Blocked at the execve syscall.
No single layer needs to be perfect. The system is designed so that each layer catches what the previous one allows through. An attacker would need to defeat all four simultaneously to reach anything outside the cell.
8. What This Proves
LLM-generated code is untrusted code. Every model will eventually produce a program that tries to do something it shouldn't — import an unavailable crate, connect to a remote host, read a sensitive file. The defence cannot be "write better prompts." The defence must be structural.
The forge is the most important gate. Two of the four breakout attempts could have been caught at build time for zero cell-spawn cost. The forge is cheap, fast, and definitive. Every agent pipeline should have one.
Hardware isolation is the last line, not the first.KVM provides a strong guarantee, but the cell's userspace defences — the stripped kernel, the minimal initramfs, the seccomp filter — catch escapes before they reach the hypervisor boundary.
Reproducible builds make the gate auditable. Every program in this experiment was built twice and compared, earning Forged tier. You don't have to trust that the build was honest; you can rebuild it yourself and compare hashes.
9. Reproduce It
export DEEPSEEK_API_KEY=sk-... ./scripts/hermetic-boundary-demo.sh celln ps -a
The full demo script, DeepSeek API shim, and all code changes are in the Celln repository. Every program and its forge proof are content-addressed and inspectable.