Ticketing
Documentación

Protocolo de autenticación

Un paso compartido, usado de forma idéntica byte a byte por el puerto de cliente y el puerto Raft del clúster. En cuanto se establece la conexión (tras completarse el handshake TLS, si se usa TLS), el servidor habla primero y envía un desafío (challenge). Es un intercambio de texto de dos líneas delimitadas por salto de línea (\n), realizado una vez por conexión.

Lo único que varía según el puerto es qué conjunto de tokens se usa para verificar — el puerto de cliente verifica contra client_tokens, el puerto Raft contra cluster_tokens. Consulta Conexión y autenticación (clúster) para las reglas de tokens específicas del puerto Raft (qué token se envía, y cómo rotar tokens sin tiempo de inactividad).

Flujo

Conector (cliente · par)
Servidor
conexión TCP · (handshake TLS)
challenge: SHA-256 ␣ nonce
digest = SHA-256(token ∥ nonce) · 43 caracteres
comparación en tiempo constante contra toda la lista de tokens
éxito → sin respuesta, el protocolo empieza de inmediato
primera solicitud enviada de inmediato (p. ej. A · adquirir)
si falló
E · auth_failed → conexión cerrada
solicitudrespuesta

1. Challenge (servidor → conector)

Estructurarefresh
<hash> <nonce>\n            p. ej. SHA-256 aB3dEf_g\n
CampoContenido
hashNombre del algoritmo de digest. Actualmente siempre SHA-256, y el servidor no acepta ningún otro
nonceUn valor aleatorio base64url de 8 caracteres. El framing está delimitado por salto de línea, así que su longitud podría crecer más adelante — el conector debe tratar todo lo que sigue al primer espacio como el nonce

2. Respuesta (conector → servidor)

Estructurarefresh
<digest>\n

digest = base64url_nopad( SHA-256( token_bytes ∥ nonce_bytes ) )

( es concatenación de bytes — los bytes ASCII de la cadena del nonce se añaden directamente tras los bytes crudos del token)

  • base64url es el alfabeto sin relleno y seguro para URL (A–Z a–z 0–9 - _). Un digest SHA-256 siempre tiene 43 caracteres.
  • El servidor verifica con una comparación en tiempo constante contra toda la lista de tokens configurados — qué token coincidió, o hasta dónde llegó una comparación, nunca se filtra por la temporización.
  • Un servidor sin tokens configurados acepta un único token vacío "". En ese caso, enviar digest = base64url(SHA-256(nonce)) pasa la verificación. El propio paso del handshake nunca puede omitirse.
  • La línea de respuesta que lee el servidor tiene un límite de 256 bytes.

3. Resultado

  • Éxito: el servidor no envía nada y pasa directamente al protocolo principal — el protocolo binario de tramas de bloqueo en el puerto de cliente, o el RPC con prefijo de longitud en el puerto Raft. Puedes enviar la primera solicitud de inmediato.
  • Fallo: el servidor envía E auth_failed y cierra la conexión. Si la conexión se cae o una línea está malformada a mitad del handshake, también puede cerrarse silenciosamente sin una trama de error.

Terminología

  • Desafío-respuesta (challenge-response) — un esquema de autenticación en el que, en lugar de enviar el secreto (token) directamente, el servidor plantea un desafío de un solo uso y el conector demuestra que conoce el secreto enviando solo la respuesta.
  • Nonce — un número usado una sola vez. Cambia en cada conexión, así que una respuesta robada no puede reutilizarse en un ataque de repetición (replay).
  • Comparación en tiempo constante (constant-time compare) — una comparación que siempre tarda el mismo tiempo sin importar hasta dónde coincidió, cerrando la puerta a los ataques de temporización que de otro modo filtrarían el secreto.
  • base64url — una variante de base64 que usa solo un alfabeto seguro para URL (A–Z a–z 0–9 - _). Aquí se usa sin relleno (=).