
Capability-based WASM runtime for executing untrusted AI-generated code with enforced CPU, memory, time, I/O, and filesystem limits. Provides sub-millisecond warm execution, signed execution records, and an MCP server for integration.
Fast, capability-based WASM execution with explicit CPU, memory, time, I/O, and filesystem limits — sub-millisecond warm execution with signed execution records.
Built for AI agents, MCP tools, plugins, code interpreters, and other untrusted workloads.
AI agents increasingly need to write and execute code, call tools, and run plugins. The question that decides whether that is safe:
How do you let an agent execute untrusted code without giving that code access to your host, your credentials, your network, or unlimited compute?
AI Agent ──▶ Tool / MCP ──▶ Ephemora Cell ──▶ WASM ──▶ bounded result
Ephemora Cell is a small, capability-based WASM execution runtime for exactly that job: an execution primitive — not an agent framework — that sits underneath your existing agent stack, MCP server, plugin system, or application.
pip install ephemora-cell
# Run your first isolated module (grab the repo's examples, or bring any .wasm):
git clone https://github.com/MichaelS1011/ephemora-cell.git
ephemora-cell run ephemora-cell/examples/hello.wasm
Hello from Ephemora Cell!
from ephemora_cell import run_wasm
result = run_wasm("my_module.wasm")
print(result.stdout) # captured output (10 KB cap)
print(result.status.name) # SUCCESS
print(result.elapsed_ms) # wall time
print(result.fuel_consumed) # compute actually used

Real CLI session: install, first run, machine-readable --json report with the security baseline, and an attack module (exploit.wasm) blocked at the WASI import layer. Verify every frame: the commands run as shown from a clone.

Same eight attack primitives, measured live in one run (2026-09-02): a stock python:3.12-slim container lets every one through (0/8 blocked), the Ephemora Cell boundary blocks all eight (8/8). Reproduce both columns:
python3 assets/demo_attack_probe.py # left column -> 0/8 blocked (stock Docker)
python benchmarks/verify_8_vectors.py # right column -> 8/8 blocked (Ephemora Cell)
Agent-generated code is different from application code: it can be buggy, computationally unbounded, unexpectedly expensive — or hostile. The runtime must enforce boundaries, not document them. Every Cell run does:
Every execution runs under explicit limits — no opt-in security:
| Resource | Default |
|---|---|
| WASM memory | 128 MB (Store.set_limits) |
| Fuel / CPU budget | 1,000,000 (~13 fuel/iteration, R² = 1.000) |
| Wall-clock timeout | 30 s (epoch interruption) |
| Captured stdout/stderr | 10 KB |
| Network | disabled — no socket APIs in WASI |
| Host filesystem | denied by default; 14 dangerous dirs blocked (/dev, /proc, /sys, …) |
| Process exec / fork | unavailable in WASI |
| Threading | disabled (wasm_threads=False) |
Additional controls: I/O budgets (io_cpu_seconds=2.0 / io_budget_bytes=64 MiB — walls for host work, not just guest compute), dual-ABI (WASI Preview1 + WASI 0.2 components, opt-in), memory64 opt-in, GC-heap declared cap (recorded in the security baseline; fuel remains the effective bound), named state (64 entries · 256 KiB · 1 MiB per session), and an egress sidecar reference mediator (allowlist-validated host-side API calls — docs/egress_patterns.md).
The guest receives only the capabilities explicitly made available to it. Live verification of eight attack classes (benchmarks/verify_8_vectors.py):
| Attack class | Docker | Ephemora Cell |
|---|---|---|
Shell (os.system) / fork / network sockets | ALLOWED | BLOCKED — APIs don't exist in WASI |
fsync (os.fsync) | ALLOWED | BLOCKED — import-level rejection |
Host filesystem (/etc/passwd) | ALLOWED | BLOCKED — preopen default-deny |
| Symlink escape | ALLOWED | BLOCKED — dangerous directory filter |
| Multi-threading | ALLOWED | BLOCKED — wasm_threads=False |
| Environment access | ALLOWED | BLOCKED — controlled via allow_env |
Result: 8/8 attack vectors blocked (live-verified); Docker baselines are measured live per run — never hardcoded.
This is an execution boundary, not a claim that guest software is trustworthy. Cell does not evaluate whether a module is malicious or correct — a guest can still misbehave within the budgets it was given. Execution paths differ materially: the default runs the guest inside your process; run_isolated() adds OS-level walls (rlimits, disk quota, I/O CPU watchdog, hard kill).
Full details: SECURITY.md (policy, execution-path control matrix, known limitations) · docs/threat-model.md (adversary model, trust boundaries, residual risks) · docs/security_posture.md (arXiv 2509.11242 evaluation, fuel boundary, related research).
Sandbox every execution without paying container-scale startup costs.
Scenario (n=1000, hello.wasm, Mac M5, wasmtime 47.0.1) | Wall median | Wall p95 | Guest median |
|---|---|---|---|
Pooled engine (io_budget_bytes=None, trusted runs) | 0.46 ms | 0.60 ms | 0.16 ms |
Default path (io_budget_bytes=64 MiB, per-run engine) | 0.92 ms | 1.26 ms | 0.60 ms |
Live cold-start comparison (2026-08-30, same Mac): docker run python:3.12-slim 171 ms vs Cell 0.40 ms = 427× — this is a container-cold-start vs invoked-WASM comparison for this benchmark workload, not a general claim that WASM is always faster than Docker.
Reproduce: python benchmarks/pool_vs_budget.py · python benchmarks/competitive_benchmark.py (raw results with measured:true committed under benchmarks/results/). Agentic workloads and more: docs/performance.md.
Cell executes the .wasm — it does not know the source language. One-command build with actionable error hints from the measured friction matrix:
ephemora-cell build tool.rs # → tool.wasm → run it
| Language | Compiler | Verified |
|---|---|---|
| Rust | cargo build --target wasm32-wasip1 | ✅ Compiled + executed (CI) |
| Go | GOOS=wasip1 GOARCH=wasm go build | ✅ Compiled + executed (CI) |
| C | wasi-sdk clang --target=wasm32-wasip1 | ✅ Compiled + executed (CI) |
| AssemblyScript | asc --runtime stub | ✅ Compiled + executed (CI) |
| Zig | zig build-exe -target wasm32-wasi | ✅ Compiled + executed (CI) |
| Python | — | Guidance: run on a wasi-python interpreter (no AOT exists) |
All five compiled-language gates verify on every push (.github/workflows/ci.yml). Platforms: macOS (Apple M5) ✅ · Ubuntu 24.04 ✅ · DGX Spark GB10 ✅
AI-generated code — run agent-produced tools with explicit limits:
result = run_wasm(
"llm_generated.wasm",
max_fuel=200_000,
timeout_seconds=5,
allow_dirs=("/input", "/output")
)
Plugin systems — accept user-uploaded plugins without giving them unrestricted host access:
config = WASIConfig(allow_dirs=("/data",), max_fuel=500_000)
result = WASISandbox(config=config).run("user_plugin.wasm")
Also documented: serverless/edge workloads, air-gapped validation, WASI 0.2 components, FastAPI integration — docs/recipes.md. Agent-framework integration tests (LangGraph, CrewAI, AutoGen, OpenAI Agents SDK, Semantic Kernel, Hermes, NemoClaw) live in integration/.
Ephemora Cell ships a dependency-free MCP stdio server whose tools are WASM modules executed inside the Cell — determinism, fuel metering, output cap, no network, SEP-2787-ready signed execution records:
pip install ephemora-cell
ephemora-cell-mcp # bundled echo tool included; register your own: --tools-dir ./tools
flowchart TB
guest["Guest WASM Module<br/>(isolated)"]
subgraph sandbox["WASI Sandbox — capability-based isolation"]
fuel["Fuel Meter<br/>~13 fuel/iteration"]
mem["Memory Limit<br/>128 MB max"]
timeout["Timeout Guard<br/>epoch interruption"]
syscalls["WASI Preview1 — capability-based,<br/>preopened dirs only<br/>fd_read · fd_write · path_open · clock_time_get<br/>proc_exit · environ_get · random_get"]
end
blocked["Blocked by design:<br/>exec · fork · socket · /dev · /proc · /sys · threads"]
guest --> syscalls
fuel -.-> sandbox
mem -.-> sandbox
timeout -.-> sandbox
sandbox -.-> blockedThe primary API is deliberately simple: execute(wasm) → result. Every execution returns structured, auditable information:
result.status # SUCCESS | ERROR | TIMEOUT | FUEL_EXHAUSTED | MEMORY_EXCEEDED
result.exit_code
result.stdout # 10 KB cap
result.stderr
result.elapsed_ms
result.fuel_consumed
That makes execution suitable for auditing, policy enforcement, and resource accounting — not just running code. Full CLI (run, --json with security_baseline, inspect, benchmark, build, profiles incl. --profile analytical) in the CLI docs and ephemora-cell --help.
Cell is: a WASM execution primitive · a capability-based isolation layer · a resource-bounded runtime · an embeddable Python library · a CLI · an MCP execution layer.
Cell is not: an agent framework · an LLM · a code-generation system · a malware detector · a full VM · a replacement for every container workload.
The goal is narrow: make untrusted execution cheap enough and controlled enough that an application can safely do it by default.
379 tests · 85% statement coverage (Cell + MCP, gate 80%) · 8/8 attack vectors blocked · CI-enforced on every push (tests, coverage, pip-audit, SBOM, bandit) — see .github/workflows/ci.yml.
SECURITY.md — security policy and controls · docs/threat-model.md — trust boundaries · docs/security_posture.md — attack-surface verification · docs/performance.md — benchmarks · docs/mcp.md — MCP server · docs/recipes.md — usage patterns · docs/languages.md — language support · CHANGELOG.md — changes
Ephemora Cell is the open-source isolation layer (Apache 2.0, standalone — no Ephemora dependency). The Ephemora enterprise edition builds on Cell's isolation for production and regulated deployments. Cell is complete for isolation; the enterprise edition is complete for operation — see docs/enterprise.md for when that conversation is worth having.
Apache 2.0 — See LICENSE.
One agent action. One bounded execution. One controlled result.
Created by Michael Soppa.