Ephemora-Cell MCP
Ephemora Cell é um primitivo leve de segurança e execução para executar código não confiável em agentes de IA, ferramentas MCP, plugins e aplicativos.
Documentação
Ephemora Cell
Ephemora Cell é uma primitiva leve de segurança e execução para rodar código não confiável dentro de agentes de IA, ferramentas MCP, plugins e aplicações.
Run untrusted code.
Control its capabilities.
Bound its resources.
Record what happened.
Construído para agentes de IA, ferramentas MCP, plugins, interpretadores de código e outras cargas de trabalho não confiáveis.
AI Agent / Application
│
▼
Tool / Plugin / MCP
│
▼
┌───────────────────────┐
│ Ephemora Cell │
│ │
│ Capabilities │
│ Resource budgets │
│ WASI sandbox │
│ Execution record │
└──────────┬────────────┘
▼
WASM module
~0,5 ms em execução aquecida · ~3M execuções/hora por núcleo (uma linha) até ~5,5M em pool · determinístico, não "isolado e torcendo para funcionar"
Início Rápido · Segurança · MCP · GitHub Action · Benchmarks · Documentação
Status (2026-09-25): versão mais recente v1.0.4.3 (2026-09-25, versão de documentação e endurecimento — changelog) · auditoria funcional completa em 2026-09-24, descobertas corrigidas e lançadas no mesmo dia · evidência reproduzível mais recente: 2026-09-25 (classes de sonda,
benchmarks/results/) · 532 testes passando, 86% de cobertura (veja o selo de CI — atualizado a cada versão)
O que é Ephemora Cell?
Ephemora Cell é uma primitiva de execução e segurança incorporável para rodar código WASM não confiável: isolamento WASM/WASI, controle explícito de capacidades, limites aplicados de CPU/combustível, memória, I/O e tempo, saída limitada e registros de execução estruturados — opcionalmente assinados. Runtime + primitiva de segurança + contabilidade em um único pip install. Ele usa Wasmtime para implementar essa fronteira — WASM é o mecanismo, a execução controlada de código não confiável é o produto.
Por que Ephemora Cell?
Wasmtime oferece um runtime WASM.
Ephemora Cell constrói uma fronteira de execução em nível de aplicação ao redor dele:
Wasmtime: Ephemora Cell:
Execute WASM Execute WASM
+ define capabilities
+ enforce budgets (fuel, memory, time, I/O)
+ bound output
+ collect execution metadata
+ produce execution records (sign-ready)
+ integrate with agents and MCP
O problema que isso responde: agentes de IA cada vez mais precisam escrever e executar código, chamar ferramentas e rodar plugins. A pergunta que decide se isso é seguro: como você permite que um agente execute código não confiável sem dar a esse código acesso ao seu host, suas credenciais, sua rede ou computação ilimitada — com nada pré-aberto por padrão? Runtimes brutos deixam essa fronteira para você. Cell é essa fronteira.
Código gerado por agentes é diferente de código de aplicação: pode ser bugado, computacionalmente ilimitado, inesperadamente caro — ou hostil. O runtime deve aplicar fronteiras, não documentá-las. Cada execução do Cell faz:
- Aplicado, não prometido — medição de combustível (CPU), limites de memória, timeouts de relógio de parede baseados em época, limites de saída e orçamentos de I/O rodam por execução e não podem ser desligados pelo convidado ou pelo chamador; a postura efetiva é atestada no registro de execução (RFC 8785 JCS, pronto para assinatura).
- Parada de loop determinística — um módulo hostil ou bugado que faz loop infinito é interrompido exatamente no orçamento que você definiu, toda vez; a execução não pode ultrapassar seu orçamento de combustível. O timeout de relógio de parede baseado em época é a rede de segurança por cima — combustível conta CPU, o relógio limita todo o resto.
- Vantagem de isolamento medida — dos vetores de ataque que têm sucesso contra um contêiner Docker padrão (shell, fork, socket, sistema de arquivos do host, escape de symlink, …), todos os 8 são bloqueados aqui (verificado ao vivo, script no repositório).
- Execução aquecida em submilissegundo — 0,17 ms convidado / 0,51 ms ponta a ponta (em pool, medido em 2026-09-14;
benchmarks/results/).
Por que agora — evidências de 2026 de que detecção e contêineres não são suficientes (literatura — measured:false para Cell; as linhas medidas vivem na escada de evidências e nunca se misturam com estas). SABER — o programa SandboxEscapeBench (UK AI Security Institute & Oxford, ICML 2026) mostra modelos de fronteira escapando de contêineres Docker de forma confiável através de configurações incorretas comuns — o mesmo benchmark que este repositório mapeia para WASM na seção de Segurança. Pesquisadores da Trail of Bits (Judson & Hess, 2026) contornaram cinco scanners de habilidades de agentes e defesas de sandbox em um único estudo, e o ataque de envenenamento de habilidades DDIPE (arXiv 2604.03081) mede taxas de bypass de 11,6–33,5% contra ecossistemas de habilidades de agentes. O padrão em todos os três: varredura e padrões de contêiner falham; a fronteira que se sustenta é aquela aplicada entre o código e o host — a camada que Cell entrega (proveniência por reivindicação: docs/security_posture.md).
AI Agent ──▶ Tool / MCP ──▶ Ephemora Cell ──▶ WASM ──▶ bounded result
Cada execução responde três perguntas ao mesmo tempo — anexadas ao resultado como _meta.execution, canonicalizado (RFC 8785 JCS) e assinável:
| Resposta | Campos de exemplo | |
|---|---|---|
| RESULTADO | o que voltou | status, stdout, exit_code |
| CUSTO | quanto custou | fuel_consumed, elapsed_ms |
| POLÍTICA | sob quais regras executou | limite de memória, pré-aberturas, política de rede, wasmtime_version |
"Verificando. Não afirmado." é dado, não slogan: qualquer registro pode ser re-verificado — reescreva um campo e verify() falha. Demonstração executável: python examples/signed_record_demo.py.
Modelo de Segurança
Cell assume que o código convidado não é confiável. O host decide explicitamente o que o convidado pode acessar — e o runtime aplica essa decisão por execução.
HOST
────────────────────────────
Cell Boundary
────────────────────────────
GUEST / UNTRUSTED CODE
Por padrão: sem rede · sem acesso arbitrário ao sistema de arquivos · sem criação de processos · sem acesso irrestrito ao ambiente — e CPU/combustível, memória, tempo de execução e saída limitados.
Segurança nunca é opcional. Cada execução — em processo ou isolada — roda sob limites aplicados (combustível de CPU, memória, tempo de relógio de parede, limites de saída — sempre ativos, nem o convidado nem o chamador podem desligá-los). A única coisa que você escolhe é a fronteira de processo: adicione --isolated (ou chame run_isolated()) quando o módulo vier de fora do seu próprio build — saída de agente, plugins de terceiros, código contribuído via PR. O caminho em processo permanece para módulos que você constrói e confia. Os padrões aplicados:
| Recurso | Padrão |
|---|---|
| Memória WASM | 128 MB (Store.set_limits) |
| Orçamento de combustível / CPU | 1.000.000 (~13 combustível/iteração, R² = 1,000 até 1M iterações; re-medido em 2026-09-14, benchmarks/results/2026-09-14/fuel_boundary.json — combustível é por plataforma, veja docs/performance.md) |
| Timeout de relógio de parede | 30 s (interrupção por época) |
| stdout/stderr capturados | 10 KB |
| Rede | desabilitada — Preview1: sem APIs de socket; WASI 0.2: vinculado, negado no momento da chamada (medido) |
| Sistema de arquivos do host | negado por padrão; 14 diretórios perigosos bloqueados (/dev, /proc, /sys, …) |
| Execução / fork de processo | indisponível em WASI |
| Threading | desabilitado (wasm_threads=False) |
A mesma regra governa recursos de linguagem: toda proposta WebAssembly que a superfície WASI fornecida pelo Cell não precisa é aplicada como desligada na configuração do motor (threads, function-references, exceções, GC, tail-calls, stack-switching — atestado em cada security_baseline, testado com sonda de compilação por versão). Isso é uma defesa estrutural deliberada: o histórico de 2025/26 — contabilidade de combustível caiu em chamadas call_ref/try_table (GHSA-m63x-6p34-q65x), um escape de heap aarch64 do Cranelift (CVE-2026-34971) e o escape do vm2 montado em cima do tratamento de exceções try_table do WebAssembly (CVE-2026-26956, fontes secundárias) — repete um padrão: sandboxes divergem exatamente onde uma proposta silenciosamente virou padrão-ativo. Cell mantém essa superfície em zero e paga o custo no que os convidados não podem executar, não no que o host não pode garantir. Tabela completa de propostas: SECURITY.md.
Controles adicionais: orçamentos de I/O (io_cpu_seconds / io_budget_bytes — paredes para trabalho do host, não apenas computação do convidado), ABI dupla (WASI Preview1 + componentes WASI 0.2, opt-in), memory64 opt-in, limite declarado de heap GC, estado nomeado (64 entradas · 256 KiB · 1 MiB por sessão) e um sidecar de egresso mediador de referência (docs/egress_patterns.md).
Início Rápido
Três comandos: instale o Cell, execute algo não confiável, leia o recibo auditado.
1 — Instale (use um virtualenv; no Ubuntu ≥ 23.04 / Fedora um pip install puro
é recusado pelo PEP 668. Windows: use Git Bash ou WSL, e python em vez de python3):
python3 -m venv .venv && source .venv/bin/activate
python -m pip install ephemora-cell
2 — Execute algo não confiável (o repositório inclui exemplos, ou traga qualquer .wasm):
git clone https://github.com/MichaelS1011/ephemora-cell.git && cd ephemora-cell
ephemora-cell run examples/hello.wasm --isolated
(adiciona isolamento de processo em nível de SO ao redor da execução, alguns ms — recomendado para código que você não construiu)
Hello from Ephemora Cell!
3 — Leia o recibo auditado — mesma execução, legível por máquina. Aqui um módulo hostil
(examples/fuel_bomb.wasm) recebe um orçamento de combustível de 100 unidades e é interrompido, exatamente como
orçado:
ephemora-cell run examples/fuel_bomb.wasm --fuel 100 --isolated --json
{
"status": "fuel_exhausted",
"exit_code": 0,
"fuel_consumed": 100,
"fuel_budget": 100,
"stdout_bytes": 0
}
O mesmo a partir do Python — cada resultado carrega status, custo e saída capturada (veja API & CLI):
Tempo até o valor: sem arquivo de política, sem regras de acesso, sem contêiner para provisionar — um pip install e você está executando WASM não confiável sob uma fronteira rígida de combustível + memória a ~0,5 ms aquecido (a mesma chamada levou um docker run padrão ~186 ms para iniciar; medido em macOS M5 n=100, benchmarks/results/2026-09-14/competitive_benchmark.json, números DGX em benchmarks/results/2026-09-20/).
Verificação de escala: o caminho de uma linha sustenta ~3M execuções/hora por núcleo (n=500, hello.wasm, Mac M5 — regenere com o trecho em docs/recipes.md); o caminho de loop quente em pool alcança ~5,5M/hora.
Para onde ir a seguir: isolamento de agente/ferramenta → Integração MCP (configuração de 3 linhas) · gate de CI para PRs não confiáveis → Integração de Agente de IA · referência de CLI e receitas de uso → docs/recipes.md. Algo falhou? Os suspeitos usuais são venv não ativado, python3 vs python no Windows, ou um caminho .wasm errado — docs/recipes.md cobre tudo isso.

Sessão CLI real: instalação, primeira execução, relatório --json com a linha de base de segurança, uma bomba de combustível interrompida exatamente em 100/100 unidades, um módulo de ataque bloqueado na camada de importação WASI. Cada quadro reproduzível a partir de um clone.
O loop de devtools para ferramentas de agente
Os mesmos comandos são um loop de desenvolvimento — edite, execute, leia o recibo — sem Dockerfile, sem build de imagem:
| Comando | O que faz no loop |
|---|---|
ephemora-cell build tool.rs | Compila Rust, Go, C, AssemblyScript ou Zig direto para WASM |
ephemora-cell run tool.wasm --json | Veredito imediato: status, código de saída, fuel_consumed, elapsed_ms |
ephemora-cell inspect tool.wasm | Imports, exports, memória — o que um módulo quer, antes de você executá-lo |
ephemora-cell benchmark tool.wasm | Latência fria/quente e dispersão de combustível enquanto você itera |
Falhas voltam classificadas, não travando: um loop infinito retorna status: "fuel_exhausted" com seu recibo, um consumidor de memória memory_exceeded, uma falha um código de saída diferente de zero — os mesmos status que o auto-avaliador e o job de teste de CI consomem. Uma ferramenta com mau comportamento nunca leva seu terminal junto.
Integração MCP
Listado no Registro Oficial de MCP (io.github.MichaelS1011/ephemora-cell-mcp, stdio via PyPI) e avaliado no Glama (licença A, qualidade A, manutenção B — classificador ao vivo do Glama; veja os selos no topo). O fluxo de chamada é o diagrama principal acima: a chamada de ferramenta do agente entra no servidor stdio, a ferramenta executa dentro da Cell, e o resultado retorna com seu registro de execução.
pip install ephemora-cell
ephemora-cell-mcp # bundled tools: clock + echo; --tools-dir ./tools replaces the bundled set with your own
# One-line setup for GitHub Copilot in VS Code:
code --add-mcp '{"name":"Ephemora Cell","command":"ephemora-cell-mcp"}'
Peça ao seu agente a hora atual: a resposta vem da ferramenta clock incluída — um módulo WASM que lê apenas o relógio de tempo real WASI — e o relatório de chamada mostra exatamente quanto essa resposta custou.
Funciona inteiramente na sua máquina — com qualquer cliente MCP e qualquer modelo, incluindo locais. O servidor MCP é um processo stdio simples instalado via PyPI: sem chave de API, sem conta na nuvem, e as ferramentas executam offline dentro do sandbox WASM (sem rede, a menos que você permita explicitamente no lado do host). Aponte Claude Desktop, VS Code/Copilot, Codex, LM Studio ou sua pilha de modelos locais para ele — o lado do sandbox nunca sai do seu hardware. O quanto o agente aproveita das ferramentas depende da capacidade de chamada de ferramentas do seu cliente e modelo; o sandbox em si não adiciona requisitos além de uma máquina local.
O que você obtém:
-
Execute ferramentas não confiáveis, criadas por agentes, localmente. Cada ferramenta é um módulo WASM dentro de um sandbox Cell — sem rede, com limite de combustível e memória, e saída limitada. Se uma ferramenta se comportar mal, ela encontra uma parede, não a sua máquina.
-
Verifique cada chamada, não apenas a instalação. Cada resultado carrega seu registro de execução (
_meta.execution), e a ferramenta nativaget-policyrelata a política exata do sandbox por ferramenta — calculada a partir do mesmo caminho de código que a aplica, então relatório e aplicação não podem divergir. Leituras de política são ferramentas; escritas de política são decisões do host (ADR-006): um agente não pode conceder a si mesmo acesso à rede ou ao sistema de arquivos, e nenhuma conexão de socket é bem-sucedida (Preview1 não expõe APIs de socket; no mundo WASI 0.2, connect é negado no momento da chamada — medido). -
Sem estado por design (revisão
2026-07-28). Clientes na revisão atual pulam completamente o handshakeinitialize; resultados carregam respostasresultType: "complete"etools/listcomttlMs/cacheScope. Clientes da era do handshake (Claude Desktop, VS Code, Codex, …) continuam funcionando sem alterações — ambas as eras servidas de um único processo e testadas lado a lado contra o SDK MCP oficial no CI. Detalhes: docs/mcp.md. -
Isolamento precificado para cada chamada — três números distintos (comparação):
Caminho Custo por chamada Porquê Runtime agrupado da biblioteca ( io_budget_bytes=None)~0,5 ms engine em cache, cargas de trabalho confiáveis Servidor stdio MCP, padrão ~12 ms sandbox novo por tools/call— a parede de I/O ADR-002 aplicada via engine por execução, medido de ponta a pontaServidor stdio MCP, --pooled~0,5 ms ferramentas verificadas no engine agrupado; a parede de I/O relaxada é atestada em get-policy -
O agente não pode reescrever seu próprio limite de segurança. O agente só pode propor uma capacidade; o host verifica assinatura, hash do módulo e política fora de banda antes de qualquer coisa executar; o runtime aplica por execução e retorna evidências. Nenhuma seta nessa cadeia aponta para trás.
vs Microsoft Wassette. Wassette é o runtime baseado em capacidades da Microsoft para ferramentas MCP, construído na mesma família de engines Wasmtime — seu modelo de pull OCI move a decisão de confiança para o momento da instalação; a Cell adiciona o que um chamador pode verificar por chamada. Comparação completa lado a lado (reverificada em 2026-09-18): docs/comparison-mcp-servers.md.
Este é um limite de execução, não uma afirmação de que o software convidado é confiável. A Cell não avalia se um módulo é malicioso ou correto — um convidado ainda pode se comportar mal dentro dos orçamentos que recebeu.
Integração com Agentes de IA
Código de PR não confiável em GitHub Actions. Este repositório inclui uma action composta: execute um módulo WASM no sandbox Cell dentro do seu próprio workflow — com medição de combustível, limite de memória, timeout de época e (padrão) o caminho de subprocesso --isolated (rlimits de nível de SO, kill forçado):
- id: run-tool
uses: MichaelS1011/ephemora-cell/action@main
with:
module: path/to/module.wasm # e.g. built from a PR-provided recipe
profile: llm
# fuel: 500_000
- run: echo "status=${{ steps.run-tool.outputs.status }} fuel=${{ steps.run-tool.outputs.fuel_consumed }}"
Status de não sucesso falham o passo (fail-on: non-success, padrão) — um módulo que queima seu orçamento ou estoura o limite de memória não pode levar seu workflow junto. Este repositório usa a action em todo push: .github/workflows/action-demo.yml executa um módulo benigno e alimenta o mesmo módulo com um orçamento de combustível de 100 unidades, afirmando ao vivo que o sandbox o interrompe e contabiliza cada unidade.
Testes de integração com frameworks de agentes (LangGraph, CrewAI, AutoGen, OpenAI Agents SDK, Semantic Kernel, Hermes, NemoClaw) estão em integration/ — verificados contra SDKs reais dos frameworks.
Casos de Uso
O que você pode construir com a Cell:
-
Execução de Código de IA — execute com segurança código gerado por um LLM, com limites explícitos:
result = run_wasm( "llm_generated.wasm", max_fuel=200_000, timeout_seconds=5, allow_dirs=("/input", "/output") ) -
Sandbox de Ferramentas MCP — execute ferramentas MCP dentro de um ambiente de execução limitado (veja Integração MCP).
-
Runtime de Plugins — aceite plugins enviados por usuários sem dar a eles acesso de nível de host (
WASIConfig(allow_dirs=("/data",), max_fuel=500_000)— mesma forma dos trechos acima). -
Runtime de Ferramentas de Agentes — dê a agentes autônomos acesso controlado a ferramentas computacionais.
-
Execução Verificável — produza registros estruturados e opcionalmente assinados descrevendo uma execução (Registros de Execução).
Também documentado: cargas de trabalho serverless/edge, validação air-gapped, componentes WASI 0.2, integração FastAPI — docs/recipes.md.
Arquitetura
A Cell executa o .wasm — ela não conhece a linguagem de origem. Um comando compila cinco linguagens, e o runtime fica abaixo da sua pilha:
A pilha de aplicação — módulo → engine → superfície de capacidades → orçamentos → registro — está diagramada em docs/security_posture.md. A API primária é deliberadamente simples — run_wasm(wasm) → result, com status, exit_code, stdout, stderr, elapsed_ms e fuel_consumed em cada resultado (superfície completa em API & CLI). Isso torna a execução adequada para auditoria, aplicação de políticas e contabilidade de recursos — não apenas para executar código. CLI completo (run, --json com security_baseline, inspect, benchmark, build) na documentação da CLI e ephemora-cell --help.
Qualquer linguagem que compile para WASM. Build com um comando e dicas de erro acionáveis:
ephemora-cell build src/main.rs # inside a cargo project → tool.wasm → run it
| Linguagem | Compilador | Verificado |
|---|---|---|
| Rust | cargo build --target wasm32-wasip1 | ✅ Compilado + executado (CI) |
| Go | GOOS=wasip1 GOARCH=wasm go build | ✅ Compilado + executado (CI) |
| C | wasi-sdk clang --target=wasm32-wasip1 | ✅ Compilado + executado (CI) |
| AssemblyScript | asc --runtime stub | ✅ Compilado + executado (CI) |
| Zig | zig build-exe -target wasm32-wasi | ✅ Compilado + executado (CI) |
| Python | — | Orientação: execute em um interpretador wasi-python (não existe AOT) |
Todos os cinco portões de linguagens compiladas verificam em todo push (.github/workflows/ci.yml). Plataformas: macOS (Apple M5) ✅ · Ubuntu 24.04 ✅ · DGX Spark GB10 ✅
Registros de Execução
Ao redor do sandbox existe uma cadeia de confiança verificável para ferramentas de terceiros:
TOOL ──▶ SIGNED MANIFEST ──▶ HOST VERIFY ──▶ EPHEMORA CELL ──▶ SIGNED EXECUTION
(vendor ships) (fail-closed, runs inside RECORD
hash + policy the sandbox (tamper-evident)
check)
Qualquer coisa que falhe na verificação é rejeitada antes que uma única instrução execute — a execução nunca depende de um caminho feliz.
- Manifestos de ferramentas assinados. Ferramentas de terceiros enviam um manifesto assinado com Ed25519 (RFC 8785 JCS); o servidor verifica assinatura e hash do módulo antes de registrar e rejeita ferramentas não assinadas, adulteradas ou com hash incompatível de forma fail-closed — um
.wasmpuro sem manifesto nunca carrega no modo de ferramentas assinadas.ephemora-cell-mcp --require-signed-tools pub.pem, assine compython -m ephemora_cell_mcp.sign_tool. - Carregamento dinâmico governado. Um agente só pode propor uma ferramenta — um
tool.request.jsoncolocado em um diretório permitido pelo operador; o servidor o avalia antes de cada mensagem recebida, verifica assinatura, hash do módulo e política, então instala e anuncia (notifications/tools/list_changed). O agente propõe; o host dispõe (ADR-006). - Registros de execução assinados. Qualquer execução se dobra em um registro à prova de adulteração cobrindo status, combustível, tempo e a linha de base de segurança atestada — altere um campo e a verificação falha. Demonstração executável:
python examples/signed_record_demo.py. - Divisão pré-execução / recibo (ADR-008).
PreExecutionRecordassina o que uma execução fará (digest do módulo, impressão digital da política, digest da entrada) antes de executar; oback_linkopcional do recibo o vincula exatamente a essa atestação. Envelopes de padrão aberto (DSSE v1, JWS destacado) carregam os mesmos bytes JCS para interoperabilidade de ecossistema — sem cliente de rede, sem dependência. - Caminho rápido confiável.
ephemora-cell-mcp --pooledserve ferramentas verificadas do engine agrupado a ~0,5 ms por chamada em vez de ~12 ms (medido) — a parede de I/O relaxada é atestada emget-policy.
Os dois caminhos de execução diferem materialmente. run_wasm() executa o convidado dentro do seu processo; run_isolated() adiciona paredes de nível de SO ao redor de um worker descartável (e retorna os campos do relatório como um dicionário). Para convidados de fora do seu próprio build — saída de agentes, plugins de terceiros, código contribuído via PR — use o caminho isolado:
| Controle | run_wasm() (no processo) | run_isolated() (subprocesso) |
|---|---|---|
| Medição de combustível (CPU do convidado) | ✅ | ✅ |
Limite de memória (Store.set_limits) | ✅ | ✅ |
| Timeout de relógio de parede (época) | ✅ | ✅ + kill forçado do processo |
| Limite de saída de 10 KB | ✅ | ✅ |
Parede de bytes de I/O (io_budget_bytes) | ✅ watcher + interrupção de época | ✅ |
Parede de CPU de I/O (io_cpu_seconds) | ❌ documentado-confiável | ✅ watchdog de rusage do worker |
Cota de disco (disk_quota_bytes) | ❌ capacidade confiável | ✅ RLIMIT_FSIZE (por arquivo) |
| RLIMIT_NOFILE/AS/RSS, limite de módulo de 32 MB | ❌ | ✅ |
| Negação de preopen + revalidação TOCTOU no momento da concessão | ✅ | ✅ |
Linhas marcadas com ❌ no processo são documentado-confiáveis: o controle é honrado como uma capacidade declarada, não uma parede aplicada — um limite de nível de kernel ali limitaria seu próprio processo. Matriz completa e justificativa: SECURITY.md.
Segurança
Escada de evidências — mais forte primeiro. Cada linha é medida, a evidência bruta é confirmada, e cada execução é reproduzível:
| # | Evidência | O que prova | Como é medido | Reproduzir |
|---|---|---|---|---|
| 1 | Replays de CVEs do MCP | Caminhos reais de exploração de duas CVEs corrigidas são negados no nível do motor; carregamento governado falha de forma segura em payload adulterado — também verificado em componentes WASI 0.2, com negação de socket medida em tempo de chamada | Servidor de referência vulnerável fixado vs. Cell, tokens de marcador aleatórios, controles positivos em ambos os lados | python benchmarks/mcp_cve_replay.py |
| 2 | Mapeamento SandboxEscapeBench-18 | 18 cenários de escape de contêiner/K8s mapeados para WASM: 8 testados em execução e negados, 10 não expressáveis na superfície WASI · fatia OSS do programa de benchmark Ephemora (ver nota abaixo) | Mapeamento estrutural + tentativas ao vivo, controle positivo com preopen concedido | python benchmarks/sandbox_escape_18.py |
| 3 | 8 intenções de ataque × 3 limites | Mesmas intenções, mesma regra de código de saída: Docker padrão 0/8 bloqueado · Docker endurecido 2/8 · Cell 8/8 (matriz abaixo) | Sondas ao vivo, imagem arm64 fixada por digest | python assets/demo_attack_probe.py · python benchmarks/hardened_docker_probe.py · python benchmarks/verify_8_vectors.py |
| 4 | Conformidade oficial WASI | 72 aprovados / 1 xfail documentado / 0 falhas contra a suíte upstream fixada — reexecutada semanalmente no CI (execuções semanais no ubuntu chegam a 71–72 em testes de fs variáveis; peculiaridade documentada do runner, não defeito do Cell — ver seção de conformidade) | Adaptador de runtime sobre a suíte oficial, JSON bruto commitado | ver conformidade/ |
| 5 | Classes de sondas 2026 | Os vetores FS companheiros da CVE-2026-47261 (barra final/hardlink/rename/TRUNCATE), sondas de worm de persistência e plano de controle são todos negados no motor fixado, com controles positivos concedidos em todas as classes | Sondas WASI reais + controles positivos, JSON datado com measured:true | python benchmarks/probe_classes_2026.py |
| 6 | Determinismo entre arquiteturas | Combustível determinístico por plataforma (dispersão 0), valores vinculados à plataforma | Mesma chamada de ferramenta em macOS arm64 / DGX GB10 / x86_64 | python benchmarks/determinism_probe.py |
Linha 2 em contexto. Os 18 cenários são externos (UK AI Security Institute, MIT — nota de proveniência abaixo). Este mapeamento é a fatia de código aberto do limite de execução de um programa mais amplo de benchmark e garantia; o programa mais amplo — incluindo a avaliação de escape agêntico que o benchmark upstream realmente executa — faz parte da edição enterprise do Ephemora (docs/enterprise.md).
De onde vêm os 18 cenários. Não são nossos: o SandboxEscapeBench do UK AI Security Institute (arXiv 2603.02277, cenários: UKGovernmentBEIS/sandbox_escape_bench, MIT) documenta 18 maneiras de código escapar de sandboxes de contêiner/Kubernetes. Esta suíte faz algo mais restrito: cada cenário é mapeado para seu equivalente WASM/WASI mais próximo e executado contra o Cell, sem modelo no loop. Os primitivos dos quais esses escapes dependem (modos privilegiados, namespaces, cgroups, sockets brutos) não existem na superfície WASI; os cenários com equivalente expressável em WASM (sistema de arquivos, sockets) são negados pelo limite ao vivo. Segurança contra injeção de prompt e comportamento agêntico são camadas diferentes — fora do escopo para uma sandbox de execução por design; a edição enterprise executa o programa de garantia mais amplo (docs/enterprise.md).
O que não comparamos — e por quê. Suítes de injeção de prompt (garak, InjecAgent) testam o modelo e a camada agêntica, não o limite de execução — fora do escopo para uma sandbox de execução. Provedores de sandbox em nuvem são citados de fontes de terceiros com seu status de origem; números de terceiros nunca aparecem na mesma tabela que nossas células medidas. Benchmarks de inicialização e throughput estão em docs/performance.md com suas ressalvas de escopo.
O convidado recebe apenas as capacidades explicitamente disponibilizadas a ele. Verificação ao vivo de oito classes de ataque (benchmarks/verify_8_vectors.py) — medida contra três limites, mesmas intenções, mesma regra de medição (código de saída decide, nada codificado):
| Classe de ataque | Docker | Docker (endurecido¹) | Ephemora Cell | Camada |
|---|---|---|---|---|
Shell (os.system) / fork | PERMITIDO | PERMITIDO | BLOQUEADO — APIs não existem no WASI | 1 |
| Sockets de rede | PERMITIDO | PERMITIDO — criação não requer capacidade | BLOQUEADO — APIs não existem no WASI | 1 |
fsync (os.fsync) | PERMITIDO | BLOQUEADO — EROFS via --read-only | BLOQUEADO — rejeição no nível de importação | 2 |
Sistema de arquivos do host (/etc/passwd) | PERMITIDO | PERMITIDO — o próprio arquivo do contêiner | BLOQUEADO — preopen com negação padrão | 2 |
| Escape de symlink | PERMITIDO | BLOQUEADO — EROFS via --read-only | BLOQUEADO — filtro de diretórios perigosos | 2 |
| Multithreading | PERMITIDO | PERMITIDO | BLOQUEADO — wasm_threads=False | 2 |
| Acesso ao ambiente | PERMITIDO | PERMITIDO | BLOQUEADO — controlado via allow_env | 2 |
O limite tem três camadas, e a tabela as mede separadamente:
- Camada 1 — Superfície WASI: o próprio formato convidado não tem pontos de entrada de shell/fork/socket para chamar.
- Camada 2 — Política de sandbox (sempre ativa): preopen com negação padrão, filtro de diretórios perigosos, armadilhas de importação,
wasm_threads=False,allow_env— aplicada por execução, não configurável para desativar. - Camada 3 — Parede de processo do SO (
--isolated): um processo de trabalho descartável com rlimits do SO e kill forçado — a camada de mitigação para 0-days do motor (SECURITY.md documenta os advisories de abril de 2026 do wasmtime).
Resultado: 8/8 vetores de ataque bloqueados (verificado ao vivo); ambas as linhas de base Docker são medidas ao vivo por execução — nunca codificadas.
Para contexto, as mesmas oito intenções foram medidas contra gVisor (runsc, release fixado, executado no CI duas vezes para determinismo): 8/8 PERMITIDO. O gVisor isola o host do contêiner, mas o convidado mantém o ABI Linux — então os mesmos primitivos permanecem disponíveis ao código convidado. Matriz de expectativa pré-declarada em benchmarks/gvisor_docker_probe.py; evidência bruta: benchmarks/results/2026-09-19/08_gvisor_docker_attack_probe.json (commitado do job de CI gvisor-boundary).
¹ Endurecido = exatamente estas flags — diga-nos quais adicionar: --network none --read-only --cap-drop=ALL --security-opt no-new-privileges --pids-limit 64 --user 65534:65534 (imagem fixada por digest; o perfil seccomp padrão do Docker está ativo em ambas as colunas). Ambos os bloqueios endurecidos são efeitos de sistema de arquivos --read-only — as flags isolam o contêiner para fora, não o convidado para dentro: criação de socket, o próprio /etc/passwd do contêiner, fork, threading e ambiente permanecem disponíveis ao convidado.

Mesmos oito primitivos de ataque, medidos ao vivo: python:3.12-slim padrão 0/8 bloqueado, contêiner endurecido 6/8 (ambos os bloqueios são efeitos de flag --read-only), Cell 8/8. Medido em duas plataformas com resultados idênticos — macOS arm64 (2026-09-18) e DGX Spark GB10 (2026-09-20, benchmarks/results/2026-09-20/*-dgx-aarch64.json). Reproduzir:
python assets/demo_attack_probe.py # stock Docker -> 0/8 blocked
python benchmarks/hardened_docker_probe.py # hardened Docker -> 2/8 blocked
python benchmarks/verify_8_vectors.py # Ephemora Cell -> 8/8 blocked
Como o 8/8 é medido — ambiente, equivalência sonda por sonda entre o corpo da sonda Docker e o convidado WASM do Cell, lista de arquivos de evidência bruta e a regra de controle positivo: docs/security_posture.md. Em resumo: código de saída medido decide, nada codificado; todo vetor bloqueado é pareado com um controle de capacidade concedida que deve ter sucesso.
- Evidência bruta:
benchmarks/results/2026-09-18/(01_hardened_docker_attack_probe.json·02_docker_attack_probe.json·03_cell_8_vector_verify.json) +benchmarks/results/2026-09-02/histórico
Replays de CVEs do MCP. Os servidores de referência oficiais do MCP têm CVEs reais e corrigidas contra esta superfície exata. benchmarks/mcp_cve_replay.py os reproduz como seus caminhos de exploração originais — servidor de referência vulnerável fixado vs. Cell, mesmos arquivos, controles positivos em ambos os lados (2026-09-17, measured:true):
- CVE-2025-53109/53110 ("EscapeRoute", escape de symlink + travessia de prefixo): o servidor de referência vulnerável vazou o arquivo protegido em ambas as intenções; o Cell bloqueou ambos no nível do motor (
EPERM/ENOTCAPABLE) — com o controle de capacidade concedida lendo com sucesso em ambos os lados. - Classe CVE-2025-54136 ("MCPoison", troca de payload após confiança): uma ferramenta assinada é aceita uma vez, então um único byte wasm adulterado faz a próxima solicitação de carregamento governado falhar de forma segura (incompatibilidade de hash).
- Mesmos replays contra componentes WASI 0.2 (evidência,
abi: "component"): o caminho de componente nega as mesmas intenções de escape (escape de symlink →EPERM, travessia → sem base preopen) e o mesmo adulteração de carregamento governado falha de forma segura. O vetor de rede ganha sua própria intenção — o mundo WASI 0.2 vinculawasi:sockets(diferente do Preview1), então uma conexão TCP é tentada sob a sandbox e recusada no momento da chamada, com o controle de leitura concedida passando na mesma execução.
Conformidade: testado contra as suítes oficiais
Não são suítes de teste próprias — o CLI enviado e a configuração do motor que o Cell envia são executados contra ambas as suítes oficiais: a suíte preview-1 do WebAssembly/wasi-testsuite através de um adaptador de runtime, e a suíte oficial do WebAssembly core spec (era W3C Wasm 3.0, harness wast2json) — evidência commitada sob conformance/results/:
- WASI: 72 aprovados, 1 xfail por design documentado, 0 falhas nas suítes preview-1 aplicáveis (commit da suíte fixada
609c44613995, 2026-09-14; 55 testes preview-3 pulados — o Cell declara apenas preview 1) - Core spec (executado em 2026-09-19,
b464a4cd100dfixado, 257 arquivos / ~36k comandos): 31.931 aprovados com cada desvio documentado, nenhum inesperado — 3.282 classificados (módulos memory64/multi-memory estão por design fora da configuração do motor enviado; v128 não pode passar pelo binding wasmtime-py 47; arquivos relaxed-simd abortam nativamente upstream), 684 asserts de formato de texto pulados (domínio do parser wabt), e um restante de 46 asserts no nível de bit NaN do binding wasmtime-py, listados verbatim no JSON de evidência. Reproduzir:python conformance/run_core_spec.py - Um job semanal de CI reexecuta a suíte fixada e envia o JSON bruto, então desvios aparecem dentro de uma semana (
.github/workflows/wasi-conformance.yml). Peculiaridade conhecida e documentada do runner: runners compartilhados ubuntu x86_64 mostram aborts raros do motor wasmtime em testes de fs variáveis; o job de CI absorve cada abort com uma única repetição registrada (adapters/cell_retry_wrapper.py, cada repetição visível no JSON de evidência) — uma execução saudável chega a 72 aprovados, como na execução de CI de 2026-09-19 — determinístico em macOS arm64 e em contêineres limpos (conformance/README.md) - O único desvio é documentado:
sock_shutdown-invalid_fdesperaEBADFem um runtime sem preopens; o diretório scratch da sandbox do Cell é preopened como fd 3 por design, então a chamada retornaENOTSOCK. A propriedade que o Cell reivindica — sem superfície de socket — não é afetada. - Escopo honesto: isto é conformidade de padrões, não uma certificação de segurança. Nenhum terceiro certifica o Cell; a evidência é a suíte fixada, o JSON commitado e o histórico de CI.
Consegue quebrar o Cell? Encontrou um caminho de execução que viola o limite de segurança documentado — um escape, um bypass de orçamento, uma lacuna de atestação? Esse é exatamente o relatório que queremos: SECURITY.md (divulgação privada, tratamento responsável). O modelo de ameaças e seus riscos residuais documentados dizem onde mirar; as caixas de metodologia nesta página dizem como medimos. Pesquisa de segurança no Cell é bem-vinda.
Desempenho
Quanto custa o limite de segurança? 0,376 ms — a sobrecarga de wall-clock quente que uma execução em sandbox adiciona sobre o mesmo trabalho executado sem sandbox (medido, não estimado).
Último benchmark reproduzível — 2026-09-14 · Mac M5 · wasmtime 47.0.1 · n=1000. Cada número abaixo é regenerado de um clone novo via os comandos no final.
Cenário (2026-09-14, n=1000, hello.wasm, Mac M5, wasmtime 47.0.1) | Mediana wall | p95 wall | Mediana convidado |
|---|---|---|---|
Motor em pool (io_budget_bytes=None, execuções confiáveis) | 0,51 ms | 0,89 ms | 0,17 ms |
Caminho padrão (io_budget_bytes=64 MiB, motor por execução) | 0,94 ms | 1,15 ms | 0,61 ms |
Frio vs. quente (2026-09-14, n=300 cada, sandbox limpo por execução vs. engine em cache, primeira execução descartada): mediana fria 0,59 ms convidado / 0,99 ms parede, mediana quente 0,55 ms convidado / 0,93 ms parede — sobrecarga do sandbox (parede quente − convidado) = 0,376 ms (overhead_warm_ms, benchmarks/results/2026-09-14/pov_benchmark.json). |
Comparação de cold-start ao vivo (2026-09-14, mesmo Mac, n=100 por imagem após aquecimento): docker run python:3.12-slim 185,9 ms vs. Cell 0,49 ms = 383× — esta é uma comparação de cold-start de contêiner vs. WASM invocado para esta carga de benchmark, não uma afirmação geral de que WASM é sempre mais rápido que Docker.
Reproduzir: python benchmarks/pool_vs_budget.py · python benchmarks/competitive_benchmark.py (resultados brutos com measured:true commitados sob benchmarks/results/). Cargas de trabalho agênticas e mais: docs/performance.md.
Imposto do sandbox em uma carga de trabalho padrão da indústria (EEMBC CoreMark 1.01)
O mesmo coremark.wasm commitado (EEMBC CoreMark 1.01, fontes fixadas, wasi-sdk-34) executa intercalado sob três configurações do Cell e, quando seus CLIs estão no PATH, sob engines externos — cada execução deve passar na autovalidação do próprio CoreMark. As pontuações são as "Iterações/Seg" auto-cronometradas do CoreMark:
| Pontuação mediana (n=3 intercalado) | macOS arm64 (wasmtime 47.0.1, wasmer 7.4.2, wasm3 0.9.0) | DGX Spark GB10 aarch64 |
|---|---|---|
| wasmtime puro (referência) | 55.204 | 48.860 |
| Sandbox Cell | 50.456 (−8,60%) | 44.040 (−9,86%) |
| Cell + medição de fuel | 43.054 (−14,67% vs. sandbox) | 38.491 (−12,60% vs. sandbox) |
| wasmer (controle externo) | 63.798 (+15,57% vs. puro) | 53.735 (+9,98% vs. puro) |
| wasm3 (controle externo, interpretador) | 5.566 (−89,92% vs. puro) | 5.747 (−88,24% vs. puro) |
Leia como fatos, não como ranking: nesta carga de trabalho, a escolha do engine abrange uma faixa de ~9–12× dependendo da plataforma, a camada de sandbox do Cell custa 8,6–10,0% sobre o engine puro na mesma máquina, e a medição de fuel em nível de instrução adiciona 12,5–14,7%. Engines externos são contexto, não concorrentes medidos pela API do Cell; wasmer requer --enable-tail-call (o build inclui o conjunto de recursos upstream Lime1+tail-call). Evidências com comandos verbatim, versões e pontuações por execução: benchmarks/results/2026-09-19/09_coremark_wasi_*.json. Reproduzir: python benchmarks/coremark_wasi.py --rounds 3.
Fuel é específico por plataforma
As contagens de fuel são determinísticas por plataforma (fuel_spread: 0 em cada host medido), mas vinculadas à plataforma — nunca compare entre hosts (detalhes e exemplos medidos entre plataformas: docs/performance.md, python benchmarks/determinism_probe.py).
Backend do engine e modo de execução
Cada número nesta página é um número Cranelift: o binding Python não pode selecionar um backend interpretado (Pulley/Winch inacessíveis, afirmado em tests/test_surface_audit.py), então nenhum fallback pode mudar silenciosamente a postura. Detalhes: docs/performance.md.
API e CLI
API Python — a superfície principal é deliberadamente simples:
from ephemora_cell import run_wasm, run_isolated, WASIConfig, WASISandbox
result = run_wasm("tool.wasm", max_fuel=1_000_000, timeout_seconds=30)
result.status # SUCCESS | ERROR | TIMEOUT | FUEL_EXHAUSTED | MEMORY_EXCEEDED
result.exit_code
result.stdout # 10 KB cap
result.elapsed_ms
result.fuel_consumed
# OS-level process wall for untrusted guests:
result = run_isolated("tool.wasm", config=WASIConfig(max_fuel=500_000))
Perfis (plugin, llm, edge, default, analytical), estado nomeado, cotas de disco e limites de heap GC são botões WASIConfig; o caminho do componente é selecionado por chamada via run_wasm(..., abi="component") — docs/recipes.md tem as receitas (FastAPI, serverless, air-gapped, WASI 0.2).
CLI — quatro verbos cobrem o ciclo:
ephemora-cell run Execute a WASM module (--json, --isolated, --fuel, --stdin, --profile)
ephemora-cell inspect Imports, exports, memory — what a module wants, before you run it
ephemora-cell benchmark Cold/warm latency and fuel spread
ephemora-cell build Compile Rust/Go/C/AssemblyScript/Zig straight to WASM
ephemora-cell --help e docs/recipes.md para a referência completa.
Limitações
Cell é: um primitivo de execução WASM · uma camada de isolamento baseada em capacidades · um runtime com recursos limitados · uma biblioteca Python embutível · um CLI · uma camada de execução MCP.
Cell não é: uma VM geral · um orquestrador de contêineres · um sistema de detecção de malware · uma plataforma de nuvem multi-tenant completa · um framework de agentes · um LLM · um sistema de geração de código · um substituto completo de VM para toda carga de trabalho em contêiner.
Use Cell quando: o código não é confiável ou é gerado dinamicamente · ferramentas vêm de terceiros · um agente de IA executa programas arbitrários · você precisa de orçamentos de recursos explícitos · você precisa de metadados de execução estruturados. Não use Cell para serviços de longa duração com uso intensivo de I/O — para isso existe o --isolated subprocess wall ou uma microVM (veja docs/performance.md para a comparação de terceiros medida).
O que cada controle imposto não afirma — cada linha é um limite honesto, testado no limite:
| Controle imposto | Garante | Não garante |
|---|---|---|
| Limite de memória (128 MB) | o convidado não pode exceder o heap configurado | comportamento correto do convidado — um bug dentro do orçamento é bug do convidado |
| Orçamento de fuel | sem queima de CPU ilimitada; a execução para no limite | detecção de malware — código com intenção hostil que permanece dentro do orçamento funciona; nada inspeciona o que o módulo significa |
| Timeout de parede | sem execução descontrolada; interrupção por época dispara | que a lógica do aplicativo esteja correta ou seja rápida |
| Negação de rede (sem APIs de socket) | sem sockets, sem conexões de saída pelo convidado | comportamento seguro dentro das capacidades concedidas — exfiltração via canais permitidos (ex.: escrever segredos em um preopen concedido) continua sendo preocupação do integrador (SECURITY.md) |
| Controle de capacidade do sistema de arquivos (somente preopen, negação padrão) | acesso a arquivos limitado a diretórios montados explicitamente | semântica completa de VM — o conteúdo do caminho montado é exatamente o que o integrador escolheu expor |
| Limites de saída (10 KB) | a saída capturada é limitada; impressões ilimitadas não podem encher o disco do host | que a saída truncada esteja completa — inspecione result.stdout e o registro |
O objetivo é estreito: tornar a execução não confiável barata o suficiente e controlada o suficiente para que um aplicativo possa fazê-la com segurança por padrão.
Detalhes completos: SECURITY.md (política, limitações conhecidas) · docs/threat-model.md (modelo de adversário, limites de confiança, matriz de exaustão de recursos) · docs/security_posture.md (avaliação arXiv 2509.11242, limite de fuel, pesquisa relacionada).
Roadmap
Itens reais, com portões — sem datas prometidas:
- Portão de atualização do engine (em andamento): wasmtime 48.0.3/49.0.1 fecha o advisory de amplificação de fuel de 2026 (GHSA-m63x-6p34-q65x) e o advisory de streams WASIp3; bloqueado na publicação de wheels Python no PyPI (
scripts/check_wasmtime_patch.pymonitora), depois re-qualificação de determinismo de fuel e uma re-execução estrita da matriz de escape FS (tests/test_fs_escape_matrix.py — a execução medida de 2026-09-25 mostra os vetores companheiros já negados no engine fixado). - Portão de avaliação WASI 0.3: WASI 0.3 (Component-Model async) é deliberadamente desligado até que a superfície 0.3 seja entregue nos wheels Python, a linha do advisory de streams seja fechada, e a superfície tenha sua própria qualificação de orçamento (docs/recipes.md).
- Fase de opt-in de threading: threads shared-everything permanecem congeladas por padrão; habilitá-las é um opt-in revisado separadamente por segurança com contabilidade de fuel e parede ciente de threads (SECURITY.md).
Testes e Verificação
470 testes passando (4 ignorados) · 86% de cobertura de declarações (Cell + MCP, portão 80%) · 8/8 vetores de ataque bloqueados · 72 passagens na conformidade oficial wasi-testsuite (fixado, 0 falhas) · CI imposto em cada push (testes, cobertura, pip-audit, SBOM, bandit, interop oficial do SDK MCP) — veja .github/workflows/ci.yml.
Documentação
Começando · Quick Start acima · docs/recipes.md — padrões de uso (FastAPI, serverless, air-gapped, WASI 0.2) · integration/ — exemplos de frameworks de agentes
Segurança e evidências · SECURITY.md — política, matriz de caminho de execução, relato de vulnerabilidades · docs/threat-model.md — limites de confiança, modelo de adversário, matriz de exaustão de recursos · docs/security_posture.md — verificação de superfície de ataque · conformance/README.md — harness oficial wasi-testsuite
Registros de execução e decisões · ADR-006 — quem pode alterar o limite de segurança de uma carga de trabalho em execução · ADR-001…008 — todos os registros de decisão · examples/signed_record_demo.py — assinar e verificar adulteração de uma execução
Desempenho · docs/performance.md — benchmarks · benchmarks/results/ — JSON bruto measured:true
Integrações · docs/mcp.md — servidor MCP · docs/comparison-mcp-servers.md — mapeamento CVE-para-sonda · action/ — GitHub Action composta
Linguagens · docs/languages.md — matriz de compilação · docs/egress_patterns.md — padrões sancionados de chamadas de API
Empresarial · docs/enterprise.md — isolamento vs. operação: quando essa conversa vale a pena
Mudanças · CHANGELOG.md
Sobre Ephemora
Ephemora Cell é a camada de isolamento de código aberto (Apache 2.0, independente — sem dependência de Ephemora). A edição empresarial Ephemora se baseia no isolamento do Cell para implantações de produção e regulamentadas. Cell é completo para isolamento; a edição empresarial é completa para operação — veja docs/enterprise.md para quando essa conversa vale a pena.
Licença
Apache 2.0 — Veja LICENSE.
mcp-name: io.github.MichaelS1011/ephemora-cell-mcp
Uma ação de agente. Uma execução limitada. Um resultado controlado.
Criado por Michael Soppa.