Arquitectura de Cosigner

Qué se ejecuta dónde, cómo se comunican las partes y cómo se coordina una sesión.

Vista general de la arquitectura de Cosigner
Click to open the full-size diagram

Componentes

Runtime de Cosigner

Un único binario de Go, distribuido como ghcr.io/fystack/cosigner para linux/amd64 y linux/arm64. Se une a las sesiones, pero no las coordina.

  • Motor MPC: el fork de Fystack de tss-lib, igual que MPCium. ECDSA usa GG18 sobre secp256k1. EdDSA usa Ed25519 de umbral de tss-lib.
  • Clave de identidad: Ed25519, creada durante el emparejamiento. Autentica al Cosigner y firma sus mensajes.
  • Almacén de claves: filas cifradas con AES-256-GCM en SQLite (predeterminado), Badger o DynamoDB.
  • Relay del Gateway: un único stream gRPC saliente. Envía señales de presencia cada 5 segundos.
  • Cliente de aprobación: llama a tu callback de aprobación antes de cada sesión.
  • Registro de auditoría: JSONL firmado y encadenado por hash.

Tus servicios

  • cosigner-cli: instala, verifica, empareja, inicia y respalda el runtime.
  • Callback de aprobación: tu servidor HTTPS. Devuelve approve o reject.
  • Origen de la clave de almacenamiento: una contraseña (perfil manual) o AWS KMS (perfil unattended).

Servicios de Fystack

  • Apex: emite tokens de emparejamiento, registra las claves de los Cosigners, gestiona la revocación y envía solicitudes MPC.
  • Gateway: acepta los streams de los Cosigners, verifica la identidad y la revocación, y enruta el tráfico hacia NATS. Un único stream activo por Cosigner entre todas las réplicas.
  • Orchestrator: ejecuta la máquina de estados de las sesiones y firma cada mensaje de control. Nunca toca los fragmentos de clave.
  • MPCium: los nodos MPC de Fystack. Consulta MPCium.

Canales

Origen → destino Transporte Autenticación Contenido
Cosigner → Apex HTTPS Token de emparejamiento de un solo uso Registro de identidad
Cosigner ↔ Gateway gRPC stream, TLS JWT EdDSA, vigencia de 60 s Todo el tráfico de la sesión
Gateway ↔ Orchestrator ↔ MPCium NATS Ed25519 por mensaje Coordinación dentro de Fystack
Participante ↔ participante Retransmitido X25519 + ChaCha20-Poly1305 Rondas MPC, cifradas de extremo a extremo
Cosigner → Callback HTTPS JWT RS256 en ambos sentidos Aprobar o rechazar

Sobres del stream

Cada trama lleva los valores autenticados de workspace_id, cosigner_id y participant_id. El Gateway descarta las tramas que no coinciden con la identidad del stream.

Tipo Dirección Subject
CONTROL Orchestrator → cosigner mpc.v1.peer.<participant_id>.control
SESSION_EVENT Cosigner → orchestrator mpc.v1.session.<session_id>.event
P2P Participante ↔ participante mpc.v1.peer.<to>.session.<session_id>.p2p
PRESENCE Cosigner → orchestrator mpc.v1.peer.<participant_id>.presence

Límites de confianza

  • Gateway: retransmite texto cifrado. Puede descartar o retrasar tráfico, pero no puede leer ni falsificar mensajes MPC.
  • Orchestrator: firma cada mensaje de control con una clave que el Cosigner fijó durante el emparejamiento. Los mensajes sin firma o mal firmados se descartan.
  • Apex: no puede omitir tu callback. Cada sesión pasa primero por tu callback.
  • Tu Cosigner: no puede firmar solo. El comité queda fijado en la generación de claves.

Más detalles en Modelo de seguridad.

Sesiones

Cada generación de claves, firma o recompartición es una sesión del orchestrator con un TTL de 120 segundos.

Estados de la sesión: created, waiting, key_exchange, active_mpc, completed, además de failed y expired
Click to open the full-size diagram
  1. Admisión: el Orchestrator verifica la firma de Apex, comprueba el comité y confirma que todos los participantes estén en línea. Solo una sesión por billetera y protocolo a la vez.
  2. waiting: los participantes reciben un session_start firmado, ejecutan comprobaciones locales (el Cosigner llama a tu callback) y responden peer_joined, peer_ready.
  3. key_exchange: los participantes intercambian claves X25519 firmadas. Las billeteras con un aprobador también necesitan aquí su aprobación firmada.
  4. active_mpc: el Orchestrator envía mpc_begin. Los participantes ejecutan directamente las rondas de tss-lib.
  5. completed: todos los participantes informan el mismo hash de resultado. El Orchestrator firma y publica el resultado.

Una sesión falla ante un error de un participante, una desconexión o resultados que no coinciden, y expira después de 120 segundos. En ambos casos, el orchestrator difunde un session_abort firmado.

Comités

Un umbral t significa t + 1 firmantes (semántica de tss-lib). El comité de nodos MPCium y Cosigners queda fijado en la generación de claves. Toda sesión posterior debe usar las mismas claves de las partes, claves de identidad y roles de aprobador.

Conexiones

  • Un único stream activo por identidad de Cosigner. Una segunda instancia con la misma identidad se rechaza.
  • Cada sesión queda vinculada al stream que estaba activo cuando se inició. Si ese stream se cae, la sesión falla con PARTICIPANT_DISCONNECTED.
  • Un Cosigner revocado recibe PermissionDenied y se detiene.