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:

LimiteO que o operador pode verO que permanece privado
Armazenamento selado pelo servidorTexto 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 provaUm 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_token de 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çãoComportamento
storeSelado 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.
proveCarrega 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.
shareIgual 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.
searchIncorpora 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_proofValida 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.
sandboxExecuta 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ódigoHTTPSignificado
INVALID_API_KEY401Chave ausente, malformada ou revogada.
RATE_LIMITED429Limite de janela deslizante por chave excedido. Cabeçalho Retry-After incluído.
VALIDATION_ERROR400O corpo falha no esquema Zod ou uma prova malformada foi passada para verify_proof.
FACT_NOT_FOUND404Nenhuma linha corresponde a (api_key_id, logical_user_id, fact_key).
PROOF_FAILED400Falha na descriptografia ou nenhuma resposta sim/não definitiva pôde ser derivada.
CLIENT_ENCRYPTED422prove ou share foi chamado contra um fato selado pelo cliente.
INTERNAL_ERROR500Exceçã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 tabela facts armazena texto cifrado, IV, tag de autenticação, compromisso, uma incorporação vector(1536) e um sinalizador client_encrypted.
  • Busca: match_facts(api_key_id, logical_user_id, query_embedding, match_count) é uma função security definer com um índice IVFFlat. Retorna apenas linhas seladas pelo servidor. Atualizar o tipo de linha da função requer substituição no estilo DROP 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.ts redireciona 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 anon e authenticated. O aplicativo usa a função de serviço do Supabase somente no lado do servidor.
  • 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

CaminhoPropó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.tsEsquema 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.jsonDescrição OpenAPI 3.1 da superfície pública.
SECURITY.mdModelo 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/ready retorna 200 sem entradas missing e reconhece warnings.

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.