ZKshare

Servidor MCP Stdio que expone herramientas de zkShare a clientes de IA: almacenar contexto cifrado, pruebas, búsqueda semántica, uso compartido y llamadas sandbox mediante POST /api/v1/context con ZKSHARE_API_KEY.

Documentación

zkShare

API de contexto orientada a la privacidad para usuarios, agentes de IA y sistemas de back-office. Un único punto de entrada HTTP (POST /api/v1/context) gestiona el almacenamiento de hechos cifrados, envoltorios de prueba basados en compromisos, búsqueda semántica sobre datos cifrados, hechos cifrados de extremo a extremo (sellados por el cliente) y una ejecución aislada en sandbox para cálculos sensibles. La implementación es una aplicación Next.js (App Router) respaldada por PostgreSQL con pgvector.

Este documento está dirigido a desarrolladores que se integran con la API y a operadores que autoalojan el servicio. No es un folleto de marketing: los niveles de precios, los paneles de control y la facturación son capas opcionales definidas por separado en el código de la aplicación.


Modelo de privacidad y seguridad

La plataforma está diseñada en torno a tres límites de confianza:

LímiteLo que el operador puede verLo que permanece privado
Almacén sellado por el servidorTexto cifrado, IV, etiqueta de autenticación, compromiso, vector de incrustación. El servidor posee la clave AES-256-GCM (ZKSHARE_ENCRYPTION_SECRET) y descifra en memoria solo cuando el llamador invoca los resúmenes prove, share o search.Los operadores de base de datos (sin el secreto de cifrado) y los lectores directos de tablas (RLS deniega anon y authenticated) no pueden leer el texto plano.
Almacén sellado por el cliente (E2EE)Blobs de texto cifrado opacos, IV, etiqueta de autenticación, compromiso y un vector de incrustación proporcionado por el llamador. El servidor nunca recibe ni deriva texto plano, y nunca invoca un modelo de incrustación sobre el hecho.El operador de la plataforma. El descifrado requiere la propia clave del llamador, que nunca sale del llamador.
Envoltorios de pruebaUn envoltorio JSON versionado y firmado con HMAC (compromiso + consulta + respuesta sí/no + nonce). Verificable por cualquiera que posea ZKSHARE_PROOF_SECRET.El texto plano del hecho utilizado para derivar la respuesta nunca se incluye en el envoltorio.

Qué significa esto en la práctica

  • Los usuarios pueden probar una propiedad de un hecho personal (por ejemplo, "el usuario prefiere viajes a la playa") ante un tercero sin exponer el valor subyacente. El tercero verifica el envoltorio mediante verify_proof.
  • Los agentes pueden mantener e intercambiar contexto entre sesiones o límites de herramientas sin exponer los valores brutos a los sistemas posteriores. El intercambio produce un share_token de un solo uso y con límite de tiempo vinculado a un identificador de agente destinatario.
  • Las empresas que integran la API pueden ofrecer garantías de privacidad que son técnicas, no contractuales: RLS deniega el acceso directo a las tablas, la clave de cifrado es exclusiva del servidor, el secreto HMAC de prueba es exclusivo del servidor, y la ruta sellada por el cliente permite que los datos sensibles permanezcan completamente fuera del alcance del operador.

SECURITY.md es la referencia canónica para el modelo de amenazas, el resumen del modelo de confianza, la divulgación de vulnerabilidades, la lista de verificación del operador y los controles de exposición a LLM de terceros.


Contrato de API

OperaciónComportamiento
storeSellado por el servidor: el llamador envía value. El servidor cifra con AES-256-GCM, calcula un compromiso con sal, genera una incrustación (o acepta un embedding de 1536 dimensiones) y persiste con client_encrypted = false. Sellado por el cliente: el llamador envía ciphertext, iv, auth_tag, commitment y el obligatorio embedding. El servidor almacena los blobs y el vector, establece client_encrypted = true y nunca deriva nada del texto plano o la etiqueta.
proveCarga un hecho sellado por el servidor, lo descifra en memoria, deriva una respuesta sí/no para la consulta proporcionada (LLM con temperature: 0, o una heurística cuando los LLM externos están deshabilitados) y devuelve un envoltorio de prueba firmado con HMAC. Devuelve 422 / CLIENT_ENCRYPTED si el hecho está sellado por el cliente.
shareIgual que prove, más la inserción de una fila en share_tokens (recipient_agent_id, expiry, proof) y devuelve un share_token. El token es una cadena base64url de 24 bytes, válida durante siete días.
searchIncrusta la consulta, llama a match_facts (una función SQL de security definer con distancia coseno sobre pgvector) y devuelve resúmenes clasificados solo para filas selladas por el servidor. Las filas selladas por el cliente se excluyen a nivel de SQL y a nivel de aplicación.
verify_proofValida un envoltorio sin cargar ningún hecho. Un envoltorio malformado devuelve 400 / VALIDATION_ERROR; un envoltorio bien formado con un HMAC incorrecto devuelve 200 con data.valid: false.
sandboxEjecuta una pequeña función de lista permitida dentro de un sandbox aislado node:vm (sin E/S de host, tiempo de espera de 50 ms) y devuelve el resultado con metadatos de atestación y un JWT HS256 de corta duración (proof_of_execution). Cada respuesta anuncia provider: "vm-sandbox": esto es aislamiento de software, no atestación de hardware.

Las formas autoritativas de solicitud y respuesta se encuentran en types/index.ts y openapi.json.

Protocolo de Contexto de Modelo (MCP)

El paquete npm zkshare-mcp (npm, fuente packages/zkshare-mcp/) es un servidor MCP stdio que expone herramientas (zkshare_store, zkshare_prove, …) que llaman a POST https://zkshare.io/api/v1/context (o a tu ZKSHARE_API_URL) con ZKSHARE_API_KEY.

Nombre canónico del Registro MCP oficial: io.github.sp0oby/zkshare — consulta de registro · Acerca del Registro MCP (metadatos de descubrimiento; el paquete ejecutable permanece en npm).

Usuarios finales: Node.js ≥ 18, luego npx -y zkshare-mcp — sin clonación. Configura tu host (ejemplo a continuación).

Colaboradores: desde la raíz del repositorio pnpm install, luego pnpm mcp para ejecutar el paquete local; la fuente está en packages/zkshare-mcp/.

Los cuerpos avanzados de store sellados por el cliente permanecen en HTTPS/OpenAPI — no a través de herramientas 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 error

CódigoHTTPSignificado
INVALID_API_KEY401Clave faltante, malformada o revocada.
RATE_LIMITED429Límite de ventana deslizante por clave superado. Se incluye el encabezado Retry-After.
VALIDATION_ERROR400El cuerpo falla el esquema Zod o se pasó una prueba malformada a verify_proof.
FACT_NOT_FOUND404Ninguna fila coincide con (api_key_id, logical_user_id, fact_key).
PROOF_FAILED400El descifrado falló o no se pudo derivar una respuesta sí/no definitiva.
CLIENT_ENCRYPTED422Se llamó a prove o share contra un hecho sellado por el cliente.
INTERNAL_ERROR500Excepción capturada. El mensaje original se registra mediante lib/logger.ts; los clientes ven un mensaje genérico.

Arquitectura

  • Tiempo de ejecución: /api/v1/context es un manejador de rutas de Node.js (no Edge) para que AES-256-GCM, la derivación de claves scrypt y el cliente de rol de servicio de Supabase se comporten de manera determinista.
  • Persistencia: PostgreSQL con extensiones y tablas gestionadas por migraciones versionadas en supabase/migrations/. Tablas: api_keys, facts, audit_logs, share_tokens. La tabla facts almacena texto cifrado, IV, etiqueta de autenticación, compromiso, una incrustación de vector(1536) y un indicador de client_encrypted.
  • Búsqueda: match_facts(api_key_id, logical_user_id, query_embedding, match_count) es una función de security definer con un índice IVFFlat. Devuelve solo filas selladas por el servidor. Actualizar el tipo de fila de la función requiere un reemplazo de estilo DROP FUNCTION ... CASCADE (una restricción de PostgreSQL): las migraciones lo manejan explícitamente.
  • Autenticación y autorización:
    • Panel de usuario final: inicio de sesión con enlace mágico de Supabase Auth. middleware.ts redirige a los visitantes no autenticados fuera de /dashboard.
    • API HTTP: encabezado x-api-key. Las claves se almacenan como hashes SHA-256; solo se muestra el prefijo en el panel. Rotar una clave requiere generar una nueva: el texto plano nunca se persiste.
    • Acceso a la base de datos: RLS deniega todo acceso directo desde los roles anon y authenticated. La aplicación usa el rol de servicio de Supabase solo en el lado del servidor.
  • Limitación de velocidad: Upstash Redis (ventana deslizante) cuando está configurado; se usa un respaldo en proceso en el desarrollo local.
  • Claves de cifrado:
    • ZKSHARE_ENCRYPTION_SECRET — secreto maestro AES-256-GCM del lado del servidor (derivado de scrypt; mínimo 32 caracteres).
    • ZKSHARE_PROOF_SECRET — secreto HMAC para compromisos y envoltorios de prueba (mínimo 16 caracteres).
    • ZKSHARE_ENCLAVE_JWT_SECRET — secreto HS256 para atestaciones de sandbox (mínimo 32 caracteres).
    • Los tres son obligatorios para las rutas de código relevantes. La aplicación lanza una excepción al inicio si alguno falta o es demasiado corto.

Estructura del repositorio

RutaPropósito
app/Rutas de Next.js App Router: sitio público, panel, endpoints de API (api/v1/context, api/keys, api/billing, api/webhooks/stripe, api/health, api/health/ready, api/audit/export, auth/callback).
lib/Módulos solo de 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 interfaz construidos sobre primitivas shadcn/ui.
types/index.tsEsquema de solicitud Zod, enumeración de operaciones, códigos de error y tipos de fila compartidos.
supabase/migrations/Migraciones SQL ordenadas.
circuits/Notas y marcadores de posición para el futuro cableado de Groth16. snarkjs es una dependencia de tiempo de ejecución pero no está en la ruta de confianza predeterminada.
packages/zkshare-mcp/Paquete npm publicable zkshare-mcp — servidor MCP stdio que hace proxy a /api/v1/context.
openapi.jsonDescripción OpenAPI 3.1 de la superficie pública.
SECURITY.mdModelo de amenazas, lista de verificación operativa y la matriz de cifrado / LLM.

Desarrollo 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

Aplica las migraciones contra tu base de datos de Supabase antes de ejercitar la API. Consulta supabase/README.md.

Pruebas de humo

Almacén sellado por el servidor seguido de una prueba:

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?"}'

Verificación de una cadena de prueba:

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 salud:

  • Liveness: GET /api/health
  • Readiness (base de datos): GET /api/health/ready

Autoauditoría (rutas críticas de privacidad)

pnpm run verify:crypto

Esto ejecuta scripts/verify-crypto.ts directamente con el soporte integrado de TypeScript de Node y verifica el viaje de ida y vuelta del cifrado, la detección de manipulación, los compromisos deterministas y los tres resultados de verify_proof (valid, invalid, malformed).


Preparación para producción

La lista de verificación completa del operador se encuentra en SECURITY.md → Operator checklist. Como mínimo, antes de exponer la API a la internet pública:

  • Los tres secretos de ZKSHARE_* están configurados con valores de alta entropía; la aplicación lanza una excepción al inicio de lo contrario.
  • ZKSHARE_CORS_ORIGIN es una lista de permitidos explícita de orígenes separados por comas. * es solo para demostraciones no autenticadas.
  • Las migraciones en supabase/migrations/ se han aplicado en orden de marca de tiempo en el entorno de destino.
  • Upstash Redis está configurado (UPSTASH_REDIS_REST_URL + UPSTASH_REDIS_REST_TOKEN); el respaldo de limitación de velocidad en proceso es solo para desarrollo local.
  • GET /api/health/ready devuelve 200 sin entradas de missing y con warnings reconocido.

Estado de la afirmación de "conocimiento cero"

El campo proof devuelto hoy es un envoltorio JSON versionado firmado con HMAC-SHA256 que vincula el compromiso, la consulta y la respuesta sí/no. snarkjs se incluye como dependencia, y circuits/ documenta la ruta Groth16 prevista para trabajo futuro. La verificación Groth16 no está en la ruta de respuesta predeterminada. Trata cualquier afirmación externa de SNARK completo en cada llamada como aspiracional a menos que el verificador y los artefactos de circuito se hayan publicado y auditado.


Contribuciones

Consulta CONTRIBUTING.md para la lista de verificación de desarrollo local, los comandos de verificación requeridos antes de abrir una solicitud de extracción y cómo marcar cambios que afecten al plano de datos o a las rutas criptográficas.

Informar de una vulnerabilidad

Por favor, no abras un issue público para vulnerabilidades de seguridad. El proceso de divulgación y los canales de contacto están documentados en SECURITY.md.

Licencia

Publicado bajo la Licencia MIT.