ZKshare
Servidor MCP Stdio que expõe ferramentas zkShare para clientes de IA: armazenar contexto criptografado, provas, busca semântica, compartilhamento e chamadas sandbox via POST /api/v1/context com ZKSHARE_API_KEY.
Documentação
zkShare
API de contexto orientada à privacidade para usuários, agentes de IA e sistemas de back-office. Um único ponto de entrada HTTP
(POST /api/v1/context) lida com armazenamento de fatos criptografados, envelopes de prova baseados em compromisso,
busca semântica sobre dados criptografados, fatos criptografados de ponta a ponta (selados pelo cliente) e uma
execução isolada em sandbox para computações sensíveis. A implementação é um aplicativo Next.js
(App Router) apoiado por PostgreSQL com pgvector.
Este documento é para desenvolvedores que integram a API e operadores que hospedam o serviço por conta própria. Não é um folheto de marketing — níveis de preço, painéis e cobrança são camadas opcionais definidas separadamente no código do aplicativo.
Modelo de privacidade e segurança
A plataforma é projetada em torno de três limites de confiança:
| Limite | O que o operador pode ver | O que permanece privado |
|---|---|---|
| Armazenamento selado pelo servidor | Texto cifrado, IV, tag de autenticação, compromisso, vetor de incorporação. O servidor detém a chave AES-256-GCM (ZKSHARE_ENCRYPTION_SECRET) e descriptografa em memória somente quando o chamador invoca prove, share ou search resumos. | Operadores de banco de dados (sem o segredo de criptografia) e leitores diretos de tabela (RLS nega anon e authenticated) não podem ler texto simples. |
| Armazenamento selado pelo cliente (E2EE) | Blobs de texto cifrado opacos, IV, tag de autenticação, compromisso e um vetor de incorporação fornecido pelo chamador. O servidor nunca recebe ou deriva texto simples e nunca chama um modelo de incorporação sobre o fato. | O operador da plataforma. A descriptografia requer a própria chave do chamador, que nunca sai do chamador. |
| Envelopes de prova | Um envelope JSON versionado e assinado com HMAC (compromisso + consulta + resposta sim/não + nonce). Verificável por qualquer pessoa que detenha ZKSHARE_PROOF_SECRET. | O texto simples do fato usado para derivar a resposta nunca é incluído no envelope. |
O que isso significa na prática
- Usuários podem provar uma propriedade de um fato pessoal (por exemplo, "o usuário prefere viagens de praia") a
um terceiro sem expor o valor subjacente. O terceiro verifica o envelope
por meio de
verify_proof. - Agentes podem manter e trocar contexto entre sessões ou limites de ferramentas sem expor os
valores brutos a sistemas downstream. O compartilhamento produz um
share_tokende uso único e com prazo vinculado a um identificador de agente destinatário. - Empresas que integram a API podem oferecer garantias de privacidade que são técnicas, não contratuais — RLS nega acesso direto à tabela, a chave de criptografia é somente do servidor, o segredo HMAC de prova é somente do servidor, e o caminho selado pelo cliente permite que dados sensíveis permaneçam fora do alcance do operador inteiramente.
SECURITY.md é a referência canônica para o modelo de ameaça, o resumo do modelo de
confiança, divulgação de vulnerabilidades, a lista de verificação do operador e controles de exposição a LLMs de terceiros.
Contrato da API
| Operação | Comportamento |
|---|---|
store | Selado pelo servidor: o chamador envia value. O servidor criptografa com AES-256-GCM, calcula um compromisso com sal, gera uma incorporação (ou aceita um embedding de 1536 dimensões) e persiste com client_encrypted = false. Selado pelo cliente: o chamador envia ciphertext, iv, auth_tag, commitment e o obrigatório embedding. O servidor armazena blobs e o vetor, define client_encrypted = true e nunca deriva nada do texto simples ou do rótulo. |
prove | Carrega um fato selado pelo servidor, descriptografa em memória, deriva uma resposta sim/não para a consulta fornecida (LLM com temperature: 0, ou uma heurística quando LLMs externos estão desabilitados) e retorna um envelope de prova assinado com HMAC. Retorna 422 / CLIENT_ENCRYPTED se o fato for selado pelo cliente. |
share | Igual a prove, além de inserir uma linha em share_tokens (recipient_agent_id, expiração, prova) e retornar um share_token. O token é uma string base64url de 24 bytes, válida por sete dias. |
search | Incorpora a consulta, chama match_facts (uma função SQL security definer com distância de cosseno sobre pgvector) e retorna resumos classificados somente para linhas seladas pelo servidor. Linhas seladas pelo cliente são excluídas no nível SQL e no nível do aplicativo. |
verify_proof | Valida um envelope sem carregar nenhum fato. Envelope malformado retorna 400 / VALIDATION_ERROR; envelope bem formado com HMAC inválido retorna 200 com data.valid: false. |
sandbox | Executa uma pequena função de lista permitida dentro de uma sandbox isolada node:vm (sem I/O de host, timeout de 50 ms) e retorna o resultado com metadados de atestação e um JWT HS256 de curta duração (proof_of_execution). Cada resposta anuncia provider: "vm-sandbox" — isso é isolamento de software, não atestação de hardware. |
Formas autoritativas de requisição e resposta estão em types/index.ts e
openapi.json.
Protocolo de Contexto de Modelo (MCP)
O pacote npm zkshare-mcp (npm, fonte packages/zkshare-mcp/) é um servidor MCP stdio expondo ferramentas (zkshare_store, zkshare_prove, …) que chamam POST https://zkshare.io/api/v1/context (ou seu ZKSHARE_API_URL) com ZKSHARE_API_KEY.
Nome canônico do Registro MCP Oficial: io.github.sp0oby/zkshare — consulta de registro · Sobre o Registro MCP (metadados de descoberta; o pacote executável permanece no npm).
Usuários finais: Node.js ≥ 18, então npx -y zkshare-mcp — sem clone. Configure seu host (exemplo abaixo).
Colaboradores: a partir da raiz do repositório pnpm install, depois pnpm mcp para executar o pacote local; a fonte é packages/zkshare-mcp/.
Corpos selados pelo cliente avançados de store permanecem em HTTPS/OpenAPI — não via ferramentas MCP.
// ~/.cursor/mcp.json
{
"mcpServers": {
"zkshare": {
"command": "npx",
"args": ["-y", "zkshare-mcp"],
"env": {
"ZKSHARE_API_KEY": "zk_live_…",
"ZKSHARE_API_URL": "https://zkshare.io"
}
}
}
}
Códigos de erro
| Código | HTTP | Significado |
|---|---|---|
INVALID_API_KEY | 401 | Chave ausente, malformada ou revogada. |
RATE_LIMITED | 429 | Limite de janela deslizante por chave excedido. Cabeçalho Retry-After incluído. |
VALIDATION_ERROR | 400 | O corpo falha no esquema Zod ou uma prova malformada foi passada para verify_proof. |
FACT_NOT_FOUND | 404 | Nenhuma linha corresponde a (api_key_id, logical_user_id, fact_key). |
PROOF_FAILED | 400 | Falha na descriptografia ou nenhuma resposta sim/não definitiva pôde ser derivada. |
CLIENT_ENCRYPTED | 422 | prove ou share foi chamado contra um fato selado pelo cliente. |
INTERNAL_ERROR | 500 | Exceção capturada. A mensagem original é registrada via lib/logger.ts; os clientes veem uma mensagem genérica. |
Arquitetura
- Runtime:
/api/v1/contexté um manipulador de rota Node.js (não Edge) para que AES-256-GCM, derivação de chave scrypt e o cliente de função de serviço do Supabase se comportem deterministicamente. - Persistência: PostgreSQL com extensões e tabelas gerenciadas por migrações versionadas sob
supabase/migrations/. Tabelas:api_keys,facts,audit_logs,share_tokens. A tabelafactsarmazena texto cifrado, IV, tag de autenticação, compromisso, uma incorporaçãovector(1536)e um sinalizadorclient_encrypted. - Busca:
match_facts(api_key_id, logical_user_id, query_embedding, match_count)é uma funçãosecurity definercom um índice IVFFlat. Retorna apenas linhas seladas pelo servidor. Atualizar o tipo de linha da função requer substituição no estiloDROP FUNCTION ... CASCADE(uma restrição do PostgreSQL) — as migrações lidam com isso explicitamente. - Autenticação e autorização:
- Painel do usuário final: login com magic-link do Supabase Auth.
middleware.tsredireciona visitantes não autenticados para longe de/dashboard. - API HTTP: cabeçalho
x-api-key. As chaves são armazenadas como hashes SHA-256; apenas o prefixo é mostrado no painel. Rotacionar uma chave requer gerar uma nova — o texto simples nunca é persistido. - Acesso ao banco de dados: RLS nega todo acesso direto das funções
anoneauthenticated. O aplicativo usa a função de serviço do Supabase somente no lado do servidor.
- Painel do usuário final: login com magic-link do Supabase Auth.
- Limitação de taxa: Upstash Redis (janela deslizante) quando configurado; um fallback em processo é usado no desenvolvimento local.
- Chaves de criptografia:
ZKSHARE_ENCRYPTION_SECRET— segredo mestre AES-256-GCM do lado do servidor (derivado de scrypt; mínimo 32 caracteres).ZKSHARE_PROOF_SECRET— segredo HMAC para compromissos e envelopes de prova (mínimo 16 caracteres).ZKSHARE_ENCLAVE_JWT_SECRET— segredo HS256 para atestações de sandbox (mínimo 32 caracteres).- Todos os três são necessários para os caminhos de código relevantes. O aplicativo lança erro na inicialização se algum estiver ausente ou muito curto.
Layout do repositório
| Caminho | Propósito |
|---|---|
app/ | Rotas do Next.js App Router — site público, painel, endpoints da API (api/v1/context, api/keys, api/billing, api/webhooks/stripe, api/health, api/health/ready, api/audit/export, auth/callback). |
lib/ | Módulos somente do servidor: encryption.ts, zk.ts, embeddings.ts, search.ts, sandbox.ts, api-key.ts, rate-limit.ts, audit.ts, llm-client.ts, supabase-server.ts, supabase-browser.ts. |
components/ | Componentes de UI construídos sobre primitivas shadcn/ui. |
types/index.ts | Esquema de requisição Zod, enum de operação, códigos de erro e tipos de linha compartilhados. |
supabase/migrations/ | Migrações SQL ordenadas. |
circuits/ | Notas e espaços reservados para futura integração Groth16. snarkjs é uma dependência de runtime, mas não está no caminho de confiança padrão. |
packages/zkshare-mcp/ | Pacote npm publicável zkshare-mcp — servidor MCP stdio que faz proxy para /api/v1/context. |
openapi.json | Descrição OpenAPI 3.1 da superfície pública. |
SECURITY.md | Modelo de ameaça, lista de verificação operacional e a matriz de criptografia / LLM. |
Desenvolvimento local
pnpm install
cp .env.local.example .env.local
# Fill the Supabase, ZKSHARE_*, and (optionally) LLM, Upstash, and Stripe values.
# Defaults for LLM model slugs live in lib/llm-client.ts.
pnpm dev
Aplique migrações contra seu banco de dados Supabase antes de exercitar a API. Veja
supabase/README.md.
Testes de fumaça
Armazenamento selado pelo servidor seguido de uma prova:
curl -sS -X POST http://localhost:3000/api/v1/context \
-H "x-api-key: zk_live_..." \
-H "Content-Type: application/json" \
-d '{"operation":"store","user_id":"user_123","fact_key":"example","value":"hello"}'
curl -sS -X POST http://localhost:3000/api/v1/context \
-H "x-api-key: zk_live_..." \
-H "Content-Type: application/json" \
-d '{"operation":"prove","user_id":"user_123","fact_key":"example","query":"does the fact say hello?"}'
Verificando uma string de prova:
curl -sS -X POST http://localhost:3000/api/v1/context \
-H "x-api-key: zk_live_..." \
-H "Content-Type: application/json" \
-d '{"operation":"verify_proof","proof":"<base64url envelope from the prove response>"}'
Sondas de saúde:
- Liveness:
GET /api/health - Readiness (banco de dados):
GET /api/health/ready
Auto-auditoria (caminhos críticos de privacidade)
pnpm run verify:crypto
Isso executa scripts/verify-crypto.ts diretamente sob o suporte TypeScript embutido do Node e
verifica round-trip de criptografia, detecção de adulteração, compromissos determinísticos e todos os três
resultados de verify_proof (valid, invalid, malformed).
Prontidão para produção
A lista de verificação completa do operador está em SECURITY.md → Operator checklist.
No mínimo, antes de expor a API à internet pública:
- Todos os três segredos
ZKSHARE_*estão definidos com valores de alta entropia; o aplicativo lança erro na inicialização caso contrário. ZKSHARE_CORS_ORIGINé uma lista de permissões explícita separada por vírgulas de origens.*é apenas para demonstrações não autenticadas.- Migrações sob
supabase/migrations/foram aplicadas em ordem de timestamp no ambiente de destino. - Upstash Redis está configurado (
UPSTASH_REDIS_REST_URL+UPSTASH_REDIS_REST_TOKEN); o fallback de limitação de taxa em processo é apenas para desenvolvimento local. GET /api/health/readyretorna200sem entradasmissinge reconhecewarnings.
Status da alegação de "conhecimento zero"
O campo proof retornado hoje é um envelope JSON versionado assinado com HMAC-SHA256, vinculando
o compromisso, a consulta e a resposta sim/não. snarkjs é incluído como dependência, e
circuits/ documenta o caminho Groth16 pretendido para trabalho futuro. A verificação Groth16 não está no
caminho de resposta padrão. Trate qualquer alegação externa de SNARK completo em cada chamada como aspiracional
a menos que o verificador e os artefatos de circuito tenham sido enviados e auditados.
Contribuindo
Veja CONTRIBUTING.md para a lista de verificação de desenvolvimento local, os
comandos de verificação necessários antes de abrir um pull request e como sinalizar mudanças que
afetam o plano de dados ou caminhos criptográficos.
Reportando uma vulnerabilidade
Por favor, não abra uma issue pública para vulnerabilidades de segurança. O processo de divulgação
e os canais de contato estão documentados em SECURITY.md.
Licença
Lançado sob a Licença MIT.