Repository navigation
Releases: MichaelS1011/ephemora-cell
Release list
v1.1.0 — Interpreter-blocker release
Ephemeral, stateless, capability-bound execution boundary for untrusted AI and agent-generated code.
The evidence persists. The execution state does not.
create → constrain → execute → prove → destroy
What 1.1 enforces, with the number that proves it
| Claim | Measured |
|---|---|
| Release gate on this commit | 957 passed / 4 skipped (961 collected), 89.98 % statement coverage |
| CI matrix | 8/8 legs green — macOS 3.10.11/3.11.9/3.12.10/3.13.15 at 955/6, Ubuntu 3.10.21/3.11.16/3.12.14/3.13.15 at 953/8 |
| Signed egress grants | cap inclusive, window, revocation enforced by a fail-closed GrantLedger; grant authenticated on load against a trust root outside the grants directory (DSSE v1, Ed25519) |
| Grant scope | a grant intersects --egress-allow and never widens it; per request and per redirect hop; the stricter cap wins |
| Strict mode | --egress-grants-required denies ungranted tools with limit: "grant-required" |
| Resolve-time SSRF | Cell's own special-use registry; embedded IPv4 (mapped / 6to4 / NAT64) decoded from the bytes and judged by destination — same 67-address decision vector on ten CPython builds |
| Host file boundary | no host path follows a guest-writable name (O_NOFOLLOW, regular-file check, atomic publication) — including governed tool loading |
| Resource caps | fuel, memory, output bytes, wall deadline, I/O budget; one canonical number per run |
| Signed evidence | DSSE v1 receipt bound to the exact _meta.execution; tamper and wrong-key both rejected |
| MCP ordering | requests before initialize refused with -32600 unless they declare a protocol version in params._meta |
| Dependencies | pip-audit clean against the pinned wasmtime==47.0.1 |
| Shipped artifact | 48/48 wheel-smoke checks; sdist clean-room container run 778 passed / 138 skipped / 0 failures as root |
Install
pip install "ephemora-cell[tools-signing]"No daemon, no FUSE or FSKit mount, no Node in the documented install path. Cell is
a pip install and an import; the MCP server runs over stdio.
What Cell is, and what it is not
It is a minimal execution boundary around a WASM guest with a host-mediated egress
path and a signed receipt. It is not a persistent workspace, not a VM, and not a
general container replacement.
Known limits
Ten deliberate open points are listed in SECURITY.md
and docs/security_review_2026-10-05.md
— including that key status is a startup property, that the in-process library path
is unauthenticated by design, that trust-root distribution stays the operator's
channel, and that the WASI 0.2 component path carries no sync blockade.
Full change list: CHANGELOG.md.
Artifacts of this release
Built from tag v1.1.0, which peels to 75b7bc244c1440876091bb02740480d86074d250,
and uploaded to PyPI as version 1.1.0. PyPI reports the same two digests for the
files it serves:
| artifact | bytes | sha256 |
|---|---|---|
| ephemora_cell-1.1.0-py3-none-any.whl | 240098 | 94cf392f8c984414dfe912d7f98b2aaf262758e49508ab9650748492ec989d58 |
| ephemora_cell-1.1.0.tar.gz | 511965 | f4ec76bb53617dd53c1f2037fb93cf6d41b46ff240bd4ca4083b6821066a4820 |
No byte-for-byte reproducibility claim: identical content and identical member
list, a few bytes of drift from the build clone's mtimes.
Install: pip install "ephemora-cell[tools-signing]"
Post-publish verification (2026-10-05, against the index — not a local build)
Installed ephemora-cell==1.1.0 from PyPI into a clean Python 3.12 venv:
ephemora-cell --version→ephemora-cell 1.1.0;ephemora_cell.__version__andephemora_cell_mcp.__version__both1.1.0- one real execution with the shipped
echotool: statussuccess, fuel22214, stdout{"echo": {"msg": "hello from the published artifact"}} - two consecutive runs → two distinct sandbox directories, no residue reused
- receipt: DSSE v1 envelope for
https://ephemora.dev/execution-report.v1verifies against the signing key; an editedfuel_consumedis rejected; a foreign key is rejected
v1.0.5 — Licensing & security-readiness release
v1.0.5 — Licensing & security-readiness release
Licensing, security-readiness and evidence release. The license changes
from Apache-2.0 to the Business Source License 1.1 (BUSL-1.1) —
source-available, free for non-production use, converting back to
Apache-2.0 four years after each version's first public release; all
versions ≤ 1.0.4.3 remain Apache-2.0 (ADR-010). The 2026-09-24 wasmtime
advisory wave — three GHSAs this repo did not previously track — is
triaged against the 47.0.1 pin with measured evidence, the sandbox
receives three security fixes, and the engine-config construction is
consolidated so the blocked M2 engine upgrade touches one site instead
of three.
Security
- Denylist drift on the component path (fix + regression test).
Mapping-stylehost:guestpreopen grants bypassed the string denylist
on the component ABI:ComponentSandbox._filter_dangerous_dirschecked
the raw"host:guest"string where the Preview1 path splits the
mapping first — an entry like/etc::guest-etcpassed the component
filter. One shared dir-guard (ephemora_cell/_sandbox_common.py) now
serves both ABI paths. Guarded bytests/test_dir_guard.py(verified
to fail on the pre-fix implementation) and the component security
matrix. - Verifier alg pinning (audit finding, closed).
ExecutionReport.verify
andPreExecutionRecord.verifyacceptexpected_alg(forwarded by
verify_manifest): a record whosealgfield is missing or differs
fails closed. Calls without the parameter behave exactly as before. - JCS safe-integer guard (audit finding, closed). Canonicalization
rejects integers beyond ±(2^53−1) instead of silently serializing them
as strings — third-party verifiers (Rust/JS) would read such records
differently. Fail-closed on sign and verify. - 2026-09-24 advisory wave triaged (measured, 2026-09-29):
GHSA-j2g9-4prp-pf6h reproduces on the in-process component path — a
guest can panic the host (SIGABRT) via filesystem datetime overflow;
fuel, epoch and memory caps do not apply inside the host call. Measured
containment: the subprocess path survives (worker dies, parent reports
a clean error) — run untrusted guests withuse_subprocess=Trueuntil
the M2 engine upgrade. GHSA-c9gc-w9vx-w86p is structurally unreachable:
guests are never linked against wasi-http (pinned in
tests/test_surface_audit.py). GHSA-jqpg-j7w6-42pr does not apply as
read (statically-typed host, no dynamic-Val lifting); re-check at M2.
Full table in SECURITY.md; fresh evidence in
benchmarks/results/2026-09-29/(Preview1 + component CVE replays
PASS,datetime_overflow_ghsa_j2g9.jsonPASS).
Added
- Root
.mcp.json(project-scope MCP config): launches the server via
uvx --from ephemora-cell ephemora-cell-mcp— the same start command
assmithery.yaml. Clients that honor project-scope.mcp.json
offer the server with a one-time user approval, and agent-plugin
scanners (Open Plugins / Cursor Directory) now detect the repo as
carrying an MCP component. Floating PyPI version, no secrets, no
config required (bundled tool set). scripts/watch_upstream.py— watches the three ADR-009 external gates
(patched wasmtime wheels on PyPI, wasmtime-pyadd_wasip3surface,
GC-heap limiter binding) with--jsonoutput; offline unit tests in
tests/test_watch_upstream.py. The ADR-009 watcher statement is now
true.- Component-path security matrix (
tests/test_component_security.py,
10 tests): fuel bomb stops budget-exact (1k / 1M / 0 boundary), memory
bomb faults exactly at the cap, 10 KB output cap, 9,216 B stdin cap,
dangerous-dir fail-closed end-to-end (incl. the mapping regression),
named-state gap pinned explicitly. WAT-generated fixtures — runs in CI
without a toolchain. Evidence for the dual-ABI claim. - CI test-count guard (
scripts/check_test_count.py+ ci.yml step, run
in strict mode): the static test-count claims in README and the
comparison doc must match the real pytest collection — mechanizes
"CI counter = README number". - Project-meta pins:
tests/test_project_meta.py(SPDX BUSL-1.1 headers
on every shipped file, LICENSE copies byte-equal, license parameters
present) andtests/test_mcp_config.py(.mcp.json/smithery command
parity). - Python 3.13: CI matrix, classifiers, SUPPORT.md/requirements.txt
(smoke-tested locally on 3.13.14: surface/policy + component/state/
security suites green). - Troubleshooting section in docs/recipes.md (fulfils the README promise:
venv/PEP 668, Windowspython, tool-path resolution, fuel/timeout
tuning, 10 KB output cap) and documented--abi/--no-memory64
flags.
Fixed
- Test-count drift across public docs: badge/freshness (532), "Testing &
Verification" (470) and the comparison doc (424) disagreed — now
single-sourced from the pytest collection and CI-guarded (589 passing,
4 skipped, 87% coverage). ephemora_cell/LICENSEshipped with the unfilled
Copyright [yyyy] [name of copyright owner]placeholder since 1.0.0 —
replaced by the canonical license text (see Changed).
Changed
- License: Apache-2.0 → BUSL-1.1. Ephemora Cell is now
source-available under the Business Source License 1.1: free for
non-production use (evaluation, development, research, testing);
business/production use requires a license from Ephemora; every version
converts back to Apache-2.0 four years after its first public release.
All versions ≤ 1.0.4.3 remain Apache-2.0 permanently. Decision and
consequences in ADR-010; contribution terms (BUSL-1.1 + relicensing
grant) in CONTRIBUTING.md. SPDX headers unified on all 23 package files
(BUSL-1.1, Michael Soppa — resolving the header/LICENSE copyright
mismatch). GitHub license detection will show BUSL-1.1; the
Glama license grade is expected to drop and is no longer claimed in the
README. - Engine-config single-sourcing (behavior-identical). One
build_engine_config(ephemora_cell/_engine_config.py) serves
wasi_runtime,engine_poolandwasi_02— the next advisory
hardening edits one site instead of three; shared sandbox helpers
replace the component path's private imports from the runtime.
tests/test_proposal_policy.py(SpyConfig) stays green untouched.
v1.0.4.3 — Docs & hardening release
v1.0.4.3 — Docs & hardening release
First release carrying the 2026-09-25 hardening line. Development followed the audit → finding → fix → regression-test → release cycle:
| Step | What |
|---|---|
| Full functional audit (2026-09-24) | H-1 (signed-tools load path missed the register-time re-hash), M-1 (oversized-line transport bug) — both fixed, regression-tested and released in 1.0.4.2 the same day |
| Follow-up hardening (2026-09-25, this release) | Load-path TOCTOU closure, 2026 probe classes with measured evidence, ADR-008 record split, version-sync guard |
| External review (2026-09-25) | README reorientation: start-here navigation, freshness block, content tiering (−21 %, zero evidence loss) |
Security
- Atomic publication + per-call module binding: every tool-publishing producer writes temp + fsync +
os.replace; the registry load-guard registers only settled, magic-prefixed modules within the size cap; in signed-tools mode every execution is bound to the register-time digest (expected_sha256on all three execution paths) — a swapped on-disk file fails closed instead of executing. Module cache keyed by content hash. ADR-006 amendment. - Version-sync guard in CI: pyproject.toml, both
__version__modules, bothserver.jsonfields and the latest tag must agree — the single-source versioning invariant is proven on every push.
Added
- 2026 probe classes with dated, reproducible evidence (
benchmarks/probe_classes_2026.py): FS escape matrix (all CVE-2026-47261 companion vectors denied on the pinned engine), persistence/worm (run-N marker invisible to run N+1), supervisor/control-plane reachability, trust-handoff (verification never inherits across delegation hops). - ADR-008 record split:
PreExecutionRecordsigns what a run will do before it runs; the receipt's optionalback_linkbinds it to exactly that attestation (verify_chain(), fail-closed). DSSE v1 envelopes and detached JWS (RFC 7797) over the same RFC 8785 JCS bytes — transparency-ready with no network client and no dependency. - README: start-here navigation, freshness block, −21 % content tiering with zero evidence loss.
Verification
532 tests passing / 4 skipped / 5 xpassed (macOS arm64) · 528 passed / 8 skipped (DGX Spark aarch64) · 8/8 attack vectors blocked on both platforms · 86 % coverage · version-sync guard green at tag.
v1.0.4.2 — Security interim release
Security interim release addressing the September 2026 wasmtime advisories.
Security
- Fuel-determinism hardening (GHSA-m63x-6p34-q65x, CVSS 5.7):
call_ref(function-references) andtry_table(exceptions) can discard callee fuel on wasmtime 47.0.x — with fuel metering always on in Cell, deterministic fuel accounting requires the proposals off. Every engine Config construction site now enforceswasm_function_references/wasm_exceptions/wasm_gc/wasm_tail_call=False(empirically verified: guests using the opcodes fail to compile, fail-closed; WASI 0.2 component linking unaffected). security_baselineattests the posture: new keysfunction_references_enabled,exceptions_enabled,gc_enabled,tail_calls_enabled— a signed record cannot claim features the engine rejects.- Exposure statement for both advisories (incl. CVE-2026-47261, wasmtime-wasi filesystem escape, CVSS 7.5) in SECURITY.md.
scripts/check_wasmtime_patch.pywatches PyPI for the pending patch wheels (48.0.3 / 49.0.1 / 47.0.4); the full engine upgrade + fuel re-qualification is planned as the next step.
Breaking: guests that legitimately need exceptions/GC cannot run on this release; documented trade-off to keep "deterministic fuel accounting" honest.
Fixed (2026-09-24 audit)
- ADR-006 register-time re-hash: signed-tools mode now re-hashes the module against the manifest's
wasm_sha256at load — a module tampered or swapped after signing (MCPoison class) is rejected fail-closed; sidecars without the binding are rejected too. - stdio transport: an oversized line no longer swallows the following message; the transport-limit reply is sent immediately (documented behavior now holds).
- Governed loading (
--tool-requests-dir) works on the shipped stdio server — requests are evaluated before each incoming message; rejections surface on stderr. --stdinwith an unreadable file prints a clean error instead of a traceback;run_isolated()results supportdict(result)/len(result).- CI pins
pytest<9; Docker image hygiene (1.45 GB → 271 MB, non-root user).
Evidence: full-functional audit report (TEST_REPORT_2026-09-24.md), CVE replays + escape-18 mapping committed under benchmarks/results/2026-09-24/.
Ephemora Cell 1.0.4.1 — MCP discover-TTL correctness + single-source version
Patch on 1.0.4. MCP server/discover now reports the registry's real freshness (shared Server._registry_ttl_ms) so a cached discover result can no longer outlive notifications/tools/list_changed under governed loading. Release version single-sourced across all four files (pyproject, MCP _version, server.json, core init); the version guard now asserts the core file too. 440 tests, black+ruff clean.
Ephemora Cell 1.0.3 — Black fix + Registry 1.0.3
Fixed
- Black formatting for ephemora_cell/init.py hybrid wrapper (long line split).
Registry
- MCP Registry 1.0.3 active (PyPI 1.0.3, server.json 1.0.3)
PyPI: https://pypi.org/project/ephemora-cell/1.0.3/
Registry: io.github.MichaelS1011/ephemora-cell-mcp 1.0.3 active
Ephemora Cell 1.0.2 — MCP Registry + UX polish
Added
- MCP Registry publication as
io.github.MichaelS1011/ephemora-cell-mcp(server.json, PyPI mcp-name in README). Published to registry.modelcontextprotocol.io (1.0.2 active). - GitHub Topics 11 -> 17 (wasmtime, wasi-preview1, wasm-sandbox, mcp-server, capability-based-security, code-execution)
- WASI preview-1 conformance harness (72 pass) + benchmark guard in CI
Fixed
- --allow-env / --allow-dirs repeated flags no longer overwrite
- allow_dirs host::guest preopen naming
- CLI --no-memory64 to override analytical profile
- allow_dirs nonexistent warns instead of silent skip
- _HybridExecutionResult unifies run_isolated return type
- Builder unified Rust output to project/.wasm like Go/C/Zig
PyPI: https://pypi.org/project/ephemora-cell/1.0.2/
Registry: io.github.MichaelS1011/ephemora-cell-mcp 1.0.2 active
Ephemora Cell 1.0.1 — release metadata and MCP surface hardening
Release metadata and MCP surface hardening, published to PyPI. The 1.0.0 PyPI metadata publicly exposed a personal email that the repository no longer carries — this upload replaces it.
pip install ephemora-cell==1.0.1Added
- Bundled
clockMCP tool — second tool alongsideecho(dependency-free Rust, reads only the WASI real-time clock; every call fuel-metered with an execution_metawitness). - Native
get-policymeta tool (read-only) — reports the effective sandbox policy per tool or registry-wide, derived from the same path execution enforces: reported and enforced policy cannot drift. Policy reads are tools; policy writes remain host decisions (ADR-006). - MCP SDK interop CI gate — the shipped stdio server is verified against the official MCP Python SDK (
initialize,tools/list, a realtools/call). - Daily metrics snapshots (PyPI downloads, GitHub stars/forks/traffic) appended to a public
metricsbranch — distribution channels only, no in-package telemetry. code --add-mcpone-liner for VS Code; Wassette row in the MCP comparison; ADR-006 (governed dynamic tool loading) and ADR-007 (browser interaction stays out of scope by design; mediated via host sidecar).
Changed
- Development Status: Beta → Production/Stable; version single-sourced via
ephemora_cell_mcp/_version.py; downloads/stars badges.
Coverage
- Statement coverage 74% → 85% over
ephemora_cell+ephemora_cell_mcp(hard gate 70% → 80%).
Fixed
- Fuel exhaustion inside host-function calls /
linker.instantiatenow classifies asFUEL_EXHAUSTEDinstead of a generic ERROR (regression test added). run_isolated()return contract documented with an example; macOS/tmppreopen trap documented; Rustbuildrequires a cargo project context (README aligned); Zig build failures hint at the CI-pinned toolchain version;--tools-dirreplaces the bundled tool set explicitly.- Repository-wide audit hygiene: remaining German text translated, private paths redacted, the package
LICENSEreplaced with the canonical Apache-2.0 text, "signed execution records" softened to the measured sign-ready, benchmark evidence aligned with tracked JSONs, dead references removed.
Full details: CHANGELOG.
Ephemora Cell 1.0.0 — first public release
First public release, published to PyPI.
pip install ephemora-cell
ephemora-cell run examples/hello.wasmHighlights: WASM isolation with fuel metering, memory caps, epoch timeouts, output caps and I/O budgets · WASI Preview1 + 0.2 components · 8/8 attack vectors blocked (live-verified) · signed execution records (RFC 8785) · dependency-free MCP stdio server · five-language CI build gates · 357 tests. See CHANGELOG.md for details.