Skip to main content

Ephemora Cell

Isolated WASM sandbox for untrusted code — sub-millisecond, capability-based. No network, no filesystem, no host access; capped at 128 MB memory / 1 M fuel / 30 s by default.

Python 3.10+ License Status

Quick Start

git clone https://github.com/MichaelS1011/ephemora-cell.git
cd ephemora-cell
pip install -e .

# Run your first isolated module (compiled from examples/hello.wat):
ephemora-cell run examples/hello.wasm
Hello from Ephemora Cell!
from ephemora_cell import run_wasm

result = run_wasm("examples/hello.wasm")
print(result.stdout)        # Hello from Ephemora Cell!
print(result.status.name)   # SUCCESS

Why Cell

  • AI agents and MCP tools execute untrusted code — Docker, shells and system Python give no isolation guarantees at agent scale. Cell sandboxes every execution.
  • Enforced, not promised — fuel metering (CPU), memory caps, epoch-based wall-clock timeouts, output caps and I/O budgets are enforced per run, with the effective posture attested in a signed execution record.
  • Sub-millisecond warm execution — 0.16 ms guest / 0.46 ms end-to-end (pooled, measured) enables plugin and edge scale.

Features

  • Fuel metering — CPU limits per execution; catches infinite loops (~13 fuel/iteration, R² = 1.000)
  • 🧠 Memory limits — 128 MB WASM memory max via Store.set_limits
  • ⏱️ Timeout — 30 s wall-clock default (epoch interruption)
  • 🔒 Preopen deny — 14 dangerous directories blocked by default (/dev, /proc, /sys, …)
  • 🚫 No network, no host access — no socket, exec or fork APIs in WASI Preview1; imports rejected at instantiate
  • 📦 Output capping — stdout/stderr capped at 10 KB (prevents buffer bloat)
  • 🧬 Dual-ABI — WASI Preview1 (default) and WASI 0.2 components (opt-in via abi="component" or auto-detection)
  • 🧱 I/O budgets — walls for host work, not just guest compute: WASIConfig(io_cpu_seconds=…, io_budget_bytes=…) (defaults 2.0 s / 64 MiB; None = unlimited for trusted runs; measured attack basis in benchmarks/io_dos/)

Also included: memory64 opt-in (memory64=True / --memory64, off by default), GC-heap declared cap (max_gc_heap_mb, recorded in the security baseline — wasmtime-py 47 binds no GC-heap limiter, fuel remains the effective bound), named state (state_set/state_get host imports, capped at 64 entries · 256 KiB · 1 MiB per session), and an egress sidecar reference mediator (allowlist-validated host-side API calls, no guest sockets — docs/egress_patterns.md).

Performance

Scenario (n=1000, examples/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

Measured 2026-08-29, reproducible: python benchmarks/pool_vs_budget.py (raw: benchmarks/results/2026-08-29/pool_vs_budget.json, measured:true). Budgeted runs force a per-run engine (ADR-002).

Docker comparison (2026-08-30, live, same Mac): docker run python:3.12-slim 171 ms vs Cell 0.40 ms cold = 427× — reproducible: python benchmarks/competitive_benchmark.py (raw: benchmarks/results/2026-08-30/competitive_benchmark.json, docker_measured:true). Agentic workloads (50 tool-calls, n=500 pooled): 0.24–0.26 ms median, p95 0.29 ms — detail in docs/performance.md.

Architecture

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 -.-> blocked

Security

Ephemora Cell blocks attack vectors that are fully allowed in Docker (verified on DGX Spark GB10):

Attack Vector Docker Ephemora Cell
Shell access (os.system) ALLOWED BLOCKED — no exec/system in WASI Preview1
Fork (os.fork) ALLOWED BLOCKED — no fork() in WASI Preview1
Network (socket) ALLOWED BLOCKED — no socket() in WASI Preview1
fsync (os.fsync) ALLOWED BLOCKED — import-level rejection at instantiate
Host FS (/etc/passwd) ALLOWED BLOCKED — preopen default-deny
Symlink escape ALLOWED BLOCKED — dangerous directory filter
Multi-threading ALLOWED BLOCKEDwasm_threads=False enforced
Env access ALLOWED BLOCKED — controlled via allow_env

Result: 8/8 attack vectors blocked (live-verified via benchmarks/verify_8_vectors.py). Docker attacks are measured live per run via benchmarks/competitive_benchmark.py — never hardcoded.

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).

Compatibility & Integrations

Ephemora Cell is a WASM execution primitive, not a framework library — drop it into any agent framework, use it with any LLM, compile from any language that targets WASM. Integration tests live in integration/: Hermes, NemoClaw, LangGraph, CrewAI, AutoGen, OpenAI Agents SDK, Semantic Kernel, and model independence (tested live against Ollama). The pattern is always the same: execute(wasm_path) → isolated result.

MCP Server

Ephemora Cell ships a dependency-free MCP stdio server whose tools are WASM modules executed inside the Cell — determinism, fuel metering, 10 KB output cap, no network, SEP-2787-ready signed execution records:

pip install -e .           # from a clone (PyPI package ships with the first release)
ephemora-cell-mcp          # bundled echo tool included; register your own: --tools-dir ./tools

See docs/mcp.md and docs/comparison-mcp-servers.md.

Programming Languages (WASM Universal)

Any language that compiles to WASM works — Cell executes the .wasm, it does not know the source language. One-command build: ephemora-cell build <source> detects the toolchain and maps failed builds to actionable hints from the measured friction matrix (benchmarks/build_friction/).

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: the CI build-recipes job installs each toolchain and runs a real build + sandbox execution per language (.github/workflows/ci.yml).

Platforms: macOS (Apple M5, ARM64) ✅ · Ubuntu 24.04 (x86_64, CI) ✅ · DGX Spark GB10 (Grace ARM64) ✅

Configuration

from ephemora_cell import WASISandbox, WASIConfig

config = WASIConfig(
    max_memory_mb=64,        # 64 MB WASM memory
    max_fuel=500_000,        # CPU fuel (None = unlimited)
    timeout_seconds=10,      # Wall-clock timeout
    allow_dirs=("/data",),   # Only /data pre-opened
)

sandbox = WASISandbox(config=config)
result = sandbox.run("examples/hello.wasm", args=["--input", "file.txt"])

result contains: status (ExecutionStatus.SUCCESS | ERROR | TIMEOUT | FUEL_EXHAUSTED | MEMORY_EXCEEDED), exit_code, stdout/stderr (capped at 10 KB), elapsed_ms, fuel_consumed.

ephemora-cell run examples/hello.wasm              # execute
ephemora-cell run examples/hello.wasm --json       # JSON on stdout, guest output on stderr
ephemora-cell run examples/hello.wasm --profile analytical
ephemora-cell inspect examples/hello.wasm          # module metadata
ephemora-cell benchmark examples/hello.wasm --n 300

Explicit CLI flags override the selected --profile; profiles add nothing you did not ask for. --profile analytical runs data-analysis workloads beyond the 128 MB wall (64-bit memories, 4.5 GiB linear memory, 50 M fuel, 120 s timeout — measured guarantees in benchmarks/analytical_breakpoint/, design in docs/decisions/ADR-003). In --json mode the payload includes security_baseline and stdin_capped; piped stdin beyond 9,216 B is refused (wasmtime host cap) — use a preopened file for bigger inputs.

Use Cases

Plugin Systems

Run user-uploaded plugins in isolation — even if they are malicious:

from ephemora_cell import WASISandbox, WASIConfig

# Only /data is accessible — no /etc, no network, no shell
config = WASIConfig(allow_dirs=("/data",), max_fuel=500_000)
sandbox = WASISandbox(config=config)
result = sandbox.run("user_plugin.wasm")

AI Agent Code Execution

Sandbox LLM-generated code — prevent credential theft, infinite loops, and network exfiltration:

result = run_wasm(
    "llm_generated.wasm",
    max_fuel=200_000,
    timeout_seconds=5,
    allow_dirs=("/input", "/output")
)
# Output capped at 10KB — no buffer bloat
csv_analysis = result.stdout

More recipes — serverless functions, air-gapped validation, WASI 0.2 components, FastAPI integration — in docs/recipes.md.

Limitations

What Ephemora Cell guarantees: host isolation (the guest cannot access host filesystem, network, or processes outside preopened directories) and resource limits (CPU via fuel, memory, wall-clock time).

What Ephemora Cell does NOT guarantee: it does not evaluate whether guest code is good (a well-crafted module can still produce unexpected output within its budget); I/O system calls run on the host and cost minimal fuel (the 10 KB output budget caps captured output; see the fuel boundary analysis in docs/security_posture.md); and it does not provide multi-tenant isolation between concurrent modules sharing the same host process.

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). The full control matrix is in SECURITY.md.

Language-interpreter guidance (CPython-WASI, custom interpreters) is in docs/languages.md.

Testing & Verification

357 tests · 74% statement coverage · 8/8 attack vectors blocked · CI-enforced on every push (tests, coverage, pip-audit, SBOM) — see .github/workflows/ci.yml and the verification commands in docs/security_posture.md.

Relationship to Ephemora

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.

License

Apache 2.0 — See LICENSE.


Isolated. Limited. Deterministic.

Created by Michael Soppa.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ephemora_cell-1.0.0.tar.gz (142.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ephemora_cell-1.0.0-py3-none-any.whl (99.9 kB view details)

Uploaded Python 3

File details

Details for the file ephemora_cell-1.0.0.tar.gz.

File metadata

  • Download URL: ephemora_cell-1.0.0.tar.gz
  • Upload date:
  • Size: 142.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.13

File hashes

Hashes for ephemora_cell-1.0.0.tar.gz
Algorithm Hash digest
SHA256 cae744992c1acf64b6276aa677aaf2f324e62e9f8d062c75bfd189d027d532ee
MD5 70e73790254f3ae884f2b677c8a18e98
BLAKE2b-256 8145aa4134b5f4dca2e41caa0f842dd765bccddbe52e0a2ac75dca042f90c8f9

See more details on using hashes here.

File details

Details for the file ephemora_cell-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: ephemora_cell-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 99.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.13

File hashes

Hashes for ephemora_cell-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a263d77033824541e4808327247814674155a91a8ebc6e5b76bbaebc6753889f
MD5 eb46612c1bbde66de10f2728ec8f93c8
BLAKE2b-256 ad9c55e0a83f8f2071e920463d6579fd77f1c109d39c7bbe5a2c2d6befe97367

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page