Auth Handshake
A shared step used byte-for-byte identically by the client port and the cluster's Raft port. Once the connection is established (after the TLS handshake completes, if TLS is in use), the server speaks first and sends a challenge. It's a two-line, newline (\n)-delimited text exchange, performed once per connection.
The only thing that differs by port is which token set is used to verify — the client port verifies against client_tokens, the Raft port against cluster_tokens. See Connection & Auth (Cluster) for the Raft-port-specific token rules (which token is sent, and how to rotate tokens with zero downtime).
Flow
Connector (client · peer)
Server
TCP connect · (TLS handshake)
challenge: SHA-256 ␣ nonce
digest = SHA-256(token ∥ nonce) · 43 chars
constant-time compare against the whole token list
success → no reply, protocol starts immediately
first request sent right away (e.g. A · acquire)
if it failed
E · auth_failed → connection closed
requestresponse
1. Challenge (server → connector)
Structurerefresh
<hash> <nonce>\n e.g. SHA-256 aB3dEf_g\n| Field | Content |
|---|---|
hash | Digest algorithm name. Currently always SHA-256, and the server accepts nothing else |
nonce | An 8-character base64url random value. Framing is newline-delimited, so its length may grow later — the connector must treat everything after the first space as the nonce |
2. Response (connector → server)
Structurerefresh
<digest>\n
digest = base64url_nopad( SHA-256( token_bytes ∥ nonce_bytes ) )(∥ is byte concatenation — the nonce string's ASCII bytes are appended directly after the token's raw bytes)
- base64url is the unpadded, url-safe alphabet (
A–Z a–z 0–9 - _). A SHA-256 digest is always 43 characters. - The server verifies with a constant-time compare against the entire configured token list — which token matched, or how far a comparison got, never leaks through timing.
- A server with no tokens configured accepts a single empty token
"". In that case, sendingdigest = base64url(SHA-256(nonce))passes. The handshake step itself can never be skipped. - The response line the server reads is capped at 256 bytes.
3. Outcome
- Success: the server sends nothing and switches straight into the main protocol — the binary frame lock protocol on the client port, or length-prefixed RPC on the Raft port. Send the first request right away.
- Failure: the server sends
E auth_failedand closes the connection. If the connection drops or a line is malformed mid-handshake, it may also just close quietly with no error frame.
Terminology
- challenge-response — an authentication scheme where, instead of sending the secret (token) directly, the server poses a one-time challenge and the connector proves it knows the secret by sending back only the answer.
- nonce — a number used once. It changes on every connection, so a stolen response can't be reused in a replay attack.
- constant-time compare — a comparison that always takes the same amount of time regardless of how far it matched, closing off timing attacks that would otherwise leak the secret.
- base64url — a base64 variant using only a URL-safe alphabet (
A–Z a–z 0–9 - _). Used here without padding (=).