matapan
Conceda acesso de API com escopo ao Chatgpt ou Claude ao seu repositório via um contêiner docker. Isolado por padrão, as alterações não afetam seu repositório a menos que você permita.
Documentação
Matapan
Matapan é um plano de controle transacional local-first para código produzido por agentes. Agentes de codificação (ChatGPT, Claude, Codex) recebem workspaces descartáveis e isolados em contêineres e retornam trabalho apenas como propostas imutáveis e baseadas em evidências, aplicadas via compare-and-swap. Seu checkout ativo nunca está no caminho de escrita do agente.
O ciclo:
importar fonte confiável → workspace isolado descartável → ferramentas/runtime com escopo → capturar edições + verificação → selar proposta imutável contra uma base esperada → revisar → aplicar via compare-and-swap → revogar e destruir → trilha de auditoria redigida permanece.
Matapan é um gerenciador de transações de workspace — não é um IDE, não é um agente, não é um sandbox genérico, não é uma GUI de Git.
Status
0.1.0-beta.1 — todas as oito sprints planejadas foram concluídas: núcleo de segurança, ciclo de vida do workspace (leases + GC), runtime endurecido (gVisor experimental), superfície de ferramentas MCP, mecanismo de propostas MVP, perfis de política, corretor de segredos, proxy de egresso, retenção de auditoria, limite do adaptador Charon, empacotamento e endurecimento adversarial (matriz de fuzz + borda). Consulte CHANGELOG.md, docs/MVP-acceptance.md e docs/docker-limitations.md.
Início rápido
Do zero, no macOS ou Linux (requer git, Go 1.25.12+ para compilar a partir do código-fonte e um daemon Docker local para workspace_run):
# Install (builds and installs to /usr/local/bin, or --user for ~/.local/bin)
scripts/install.sh
# Verify the environment
matapan doctor
# git ok git version 2.50.1
# config ok ~/.matapan/config.json
# database ok ~/.matapan/matapan.db (schema v7)
# obol key ok ~/.matapan/obol.key (perms 600)
# docker ok daemon reachable
# runtime image ok present, digest matches
# runtime spawn ok hardened container ran, exit 0
# Pre-pull the digest-pinned runtime image
matapan runtime pull
# Create a workspace from a git repo (worktree at an exact commit)
matapan workspace create --repo ~/src/my-app --base main
# {"ID": "019f…", "State": "ready", "Branch": "matapan/019f…", …}
# Start the daemon, then connect an agent (see docs/quickstart-claude.md)
matapand &
O agente então conduz workspace_file_edit / workspace_run / workspace_commit contra esse ID de workspace. Quando o trabalho estiver concluído:
# Seal the workspace into an immutable proposal (via the agent or MCP),
# then review and apply with compare-and-swap:
matapan proposal list
matapan proposal show <id> # diff, digests, evidence, lineage
matapan proposal apply <id> --expected-base <commit>
# {"ProposalID": "019f…", "AppliedHead": "7f84…", "Strategy": "auto",
# "Rollback": "git -C ~/src/my-app reset --hard <commit>"}
# Housekeeping
matapan workspace destroy <id> # verified teardown
matapan gc --dry-run # what idle/expired GC would collect
Outros tipos de fonte: --source snapshot --path /dir (cópia defendida de um diretório não-Git), --source fresh [--git-init] (scaffold vazio). Flags úteis: --profile restricted (perfil de política), --lease 24h (expiração do GC), --egress proxy.example.com (concessão de egresso humano).
Conectando agentes
- Claude Code / agentes locais (stdio):
matapand --stdiocomMATAPAN_OBOLdefinido — consulte docs/quickstart-claude.md. - ChatGPT (túnel HTTPS): StreamableHTTP autenticado em
/mcpvia um túnel gerenciado pelo usuário — consulte docs/quickstart-chatgpt.md.
Superfície de ferramentas
- Perfis (
mcp.tool_profileem config.json, padrãominimal): minimal é o núcleo de 12 ferramentas;fulladicionaworkspace_file_globeworkspace_file_greptipados para hosts que preferem busca tipada em vez derg/findde shell (paridade DevSpace). - Descoberta de capacidades:
matapan_capabilitiesretorna a versão do servidor, perfil, ferramentas + anotações, limites rígidos e flags de recursos para que qualquer agente possa se autoconfigurar. - Erros tipados: falhas de ferramentas retornam um campo
{"error": {"code", "message"}}estruturado com códigos estáveis (unauthorized,not_found,path_escape,workspace_locked,stale_base,spec_refused,state_conflict,invalid_argument,egress_denied,unsupported,unavailable,internal). - Instruções:
AGENTS.md/CLAUDE.mdraiz são descobertos e retornados emworkspace_status, e seus digests são registrados em cada selo de proposta. O conteúdo das instruções é dado para o agente, nunca entrada de controle — não pode alterar política, escopos ou limites. - Concessões de egresso: a rede permanece
nonea menos que o workspace tenha uma concessão de um humano (matapan workspace create --egress DOMAINou a ferramentaworkspace_grant_egress, escopoworkspace.grant— principais agentes não a recebem). Execuções concedidas passam pelo proxy de egresso do matapan (allowlisting de proxy CONNECT/HTTP): HTTP(S) para domínios concedidos funciona, todo o resto é negado e registrado no ledger. Honestidade de aplicação: no Docker Linux nativo, o contêiner se conecta a uma rede interna sem rota direta de saída (aplicação total); no Docker Desktop, o contêiner roda na bridge padrão com o proxy como único caminho configurado — HTTP(S) é filtrado, mas egresso de IP bruto é uma lacuna documentada até o proxy sidecar chegar.
Perfis de política, segredos e identidade
- Perfis de política (
default,restricted,open;matapan policy list/show): allowlists de imagens, política de egresso, denylists de comandos argv[0], tetos de recursos. Atribuídos por workspace na criação (--profile); o digest do perfil é selado em cada proposta comopolicy_digest. - Segredos:
matapan secret setarmazena valores criptografados com AES-256-GCM (chave em 0600, nunca texto puro em repouso; valor lido de stdin ou--env, nunca argv). Humanos concedem segredos a workspaces (workspace_grant_secret/matapan secret grant); execuções injetam apenas segredos concedidos como variáveis de ambienteMATAPAN_SECRET_<NAME>; concessões são revogadas automaticamente no selo da proposta e na destruição do workspace. Valores são registrados com o redator do ledger no momento da injeção. - Modo Charon:
auth.mode: charon+auth.charon_urlalterna a validação de token para o endpoint de validação Charon (5s, fail-closed, audiencematapanaplicado de qualquer forma).review.prevent_self_approval(padrão true no modo charon) bloqueia o criador de uma proposta de aplicá-la ou rejeitá-la — revisão independente. - Modo OAuth:
auth.mode: oauthtorna a instância um servidor de autorização OAuth 2.0 completo para conectores que exigem OAuth (ChatGPT, Claude). Tokens de acesso JWT HS256 (24h, mesmo arquivo de chave HMAC que obols), cliente PKCE públicochatgpt-mcp, descoberta de metadados em/.well-known/e um portão de aprovação do proprietário: o endpoint de autorização renderiza um formulário exigindo a senha do proprietário (MATAPAN_OAUTH_OWNER_PASSWORDna inicialização do daemon — com hash em memória, nunca armazenada; a inicialização recusa o modo oauth sem ela). Sem matrícula aberta: apenas o cliente configurado e URIs de redirecionamento na allowlist são aceitos. Tokens mapeiam para um principalagent-<client_id>específico do conector (AgentScopes: semworkspace.grant, semproposal.apply) — o conector não pode conceder egresso ou segredos e não pode aplicar propostas; aplicar permanece humano. A página de aprovação renderiza os escopos efetivos exatos. Obols continuam funcionando junto com JWTs.matapan config oauth-setupimprime as instruções exatas do conector. - Retenção de auditoria:
ledger.retention_days(90) eledger.max_entries(1e6); o varredor de inicialização/diário compacta com uma entrada âncora para queVerifyainda valide a cauda retida.
Configuração de runtime
A seção runtime de config.json define padrões por execução (timeout_sec, memory_mb, pids_limit, nano_cpus, max_output_bytes). Valores por chamada podem reduzir esses padrões, mas nunca elevá-los além dos limites rígidos, que são constantes em internal/runtime (não config): timeout ≤ 10 min, memória ≤ 4 GiB, saída capturada/transmitida ≤ 4 MiB. Imagens são fixadas por digest (docker_image) e verificadas após cada pull; proveniência vive na tabela runtime_images (matapan runtime images).
Precedência de configuração e overrides de env
Precedência, sempre: env > arquivo > padrões. Cada variável MATAPAN_* é aplicada após o carregamento do arquivo de configuração, antes da validação; valores inválidos falham fechados com um erro nomeando a variável.
| Variável | Significado | Padrão |
|---|---|---|
MATAPAN_LISTEN_ADDR | Endereço de bind HTTP | 127.0.0.1:18777 |
MATAPAN_DB_PATH | Banco de controle SQLite | ~/.matapan/matapan.db |
MATAPAN_WORKSPACE_ROOT | Diretório raiz do workspace | ~/.matapan/workspaces |
MATAPAN_DOCKER_IMAGE | Imagem de execução fixada por digest | alpine:3.23 fixada |
MATAPAN_OBOL_KEY_PATH | Chave HMAC obol (0600) | ~/.matapan/obol.key |
MATAPAN_SECRET_KEY_PATH | Chave AES de segredos (0600) | ~/.matapan/secret.key |
MATAPAN_ALLOW_LAN | Bind não-loopback true/false | false |
MATAPAN_TOOL_PROFILE | minimal/full | minimal |
MATAPAN_AUTH_MODE | local/charon | local |
MATAPAN_CHARON_URL | Endpoint de validação Charon | — |
MATAPAN_GC_IDLE_HOURS | Expiração de workspace ocioso (int) | 72 |
MATAPAN_LEDGER_RETENTION_DAYS | Retenção de auditoria (int) | 90 |
MATAPAN_LEDGER_MAX_ENTRIES | Limite de auditoria (int) | 1000000 |
MATAPAN_RUNTIME_ISOLATION | docker/gvisor | docker |
MATAPAN_OAUTH_CLIENT_ID | client_id público OAuth (modo oauth) | chatgpt-mcp |
Contêiner
scripts/docker-build.sh matapan:local # builds + version-stamps the image
docker run -d --name matapand \
-p 127.0.0.1:18777:18777 \
-v /etc/matapan/config.json:/etc/matapan/config.json:ro \
-v ~/.matapan:/data \
-v /var/run/docker.sock:/var/run/docker.sock \
-v "$HOME/src:$HOME/src" \
matapan:local
Paridade de caminho é obrigatória: a raiz do workspace e quaisquer repositórios de origem devem ser montados no mesmo caminho absoluto dentro e fora do contêiner — o matapand faz bind-mount dos diretórios do workspace em contêineres de execução e executa operações de worktree git contra caminhos do host. Consulte docs/operations.md para o guia completo de implantação de contêiner (incluindo o layout compose por modelo) e a nota de confiança do docker.sock. A imagem roda como root (documentado no Dockerfile): o grupo do socket Docker varia por host; cargas de trabalho de agentes ainda rodam sob o perfil endurecido completo.
Resumo de segurança
- Sem shell em lugar nenhum. Todos os subprocessos são arrays argv
os/exec; não há caminhosh -cno código. - Defesa de caminho do workspace. Toda chamada de ferramenta de arquivo re-canonicaliza com
filepath.EvalSymlinkse rejeita escapes..e escapes de symlink da raiz do workspace, com re-verificação TOCTOU na abertura. - Runtime de contêiner endurecido. Usuário não-root,
CapDrop: ALL, no-new-privileges, seccomp padrão, limites de memória/CPU/PID, rootfs somente leitura,NetworkMode: nonepor padrão (concessão de egresso explícita necessária), imagens fixadas por digest com verificação de digest pós-pull, allowlist de env explícita (sem env do host ambiente) e recusa rígida de modo privilegiado, PID/IPC do host e qualquer montagem/var/run/docker.sock. Contêineres são nomeadosmatapan-<workspace>-<seq>e rotulados para que destruição e reconciliação possam encontrá-los; a limpeza é verificada, não confiada. Evidência de comando inclui código de saída, flag de kill por OOM, digest de imagem verificado, motivo de término e saída limitada (marcada por truncamento). - Propostas imutáveis + aplicação CAS. Uma proposta sela o diff, commits base/head e um digest de conteúdo. A aplicação verifica se o head da branch alvo é igual à base da proposta e ao seu
expected_base, mescla em um worktree temporário primeiro e é idempotente na repetição. Base desatualizada retorna um erro tipado carregando o head atual. - Ledger de auditoria. Somente anexação, encadeado por hash, redigido antes da persistência — valores de segredo nunca são armazenados (
ledger.Redact). - Autenticação Obol. Tokens bearer HMAC-SHA256 (
obol_<id>_<secret_hex>), revogáveis, audience fixado emmatapan. - Defesa de importação de snapshot. Fontes não-Git são copiadas, nunca referenciadas: raiz da fonte canonicalizada, symlinks de escape ignorados e registrados, FIFOs/dispositivos rejeitados, limites de byte/arquivo, aberturas de fonte defendidas por TOCTOU.
- Segurança do ciclo de vida. Bloqueio por workspace (mutex em processo + flock, seguro contra falhas), destruição permitida de qualquer estado com verificação pós-exclusão, reconciliação de inicialização para workspaces travados/órfãos e contêineres rotulados Matapan mortos na destruição.
Linguagem honesta de isolamento: isso é isolamento de contêiner endurecido, não "execução segura". Perfis gVisor/Kata/microVM são o caminho de maior garantia (gVisor é experimental a partir da Sprint 8). Detalhe honesto completo: docs/docker-limitations.md.
Layout
cmd/matapand daemon (MCP over stdio or authenticated HTTP)
cmd/matapan CLI (workspace/proposal/policy/secret/gc/runtime/doctor/config)
internal/config daemon config + obol signing key load/generate
internal/obol HMAC-SHA256 token service (audience "matapan")
internal/auth identity adapter (local obols / Charon validate endpoint)
internal/policy principals, scopes, workspace grants, named policy profiles
internal/ledger hash-chained append-only audit + retention sweeps
internal/idempotency key-based dedup
internal/store SQLite schema, migrations, typed store
internal/workspace lifecycle, worktrees, snapshots, locking, leases + GC,
canonical path defense
internal/reconcile startup crash recovery + orphan reconciliation
internal/runtime hardened Docker exec, verified images, egress proxy wiring
internal/egressproxy allowlisting CONNECT/HTTP egress proxy
internal/secrets AES-256-GCM secret registry + grant lifecycle
internal/proposal seal, CAS apply strategies, conflict handling, revise
internal/testparse JUnit/TAP evidence parsing (matapan-observed)
internal/mcpserver workspace-scoped MCP tools (mcp-go v0.56.0)
internal/httpserver daemon HTTP (/api/health, /mcp)
scripts/ install.sh + release.sh packaging
docs/ threat model, ADRs, quickstarts, operations, acceptance
Licença
MIT — Copyright (c) 2026 OpenLethe. Consulte LICENSE.