The base credential
Every account begins with an email address and a passphrase. The passphrase is never stored: the server keeps only an Argon2 hash, which can confirm a passphrase but cannot reproduce it. A successful sign-in issues a session cookie — HttpOnly and same-site, so scripts cannot read it and foreign sites cannot ride it. Sign-in attempts are rate-limited and locked out on abuse.
Wallet-QR sign-in
A citizen at a desktop can sign in without typing anything. The screen shows a QR code carrying a public envelope — a challenge identifier, a one-time nonce, a short match code, and the site's domain. The citizen scans it with the wallet on their phone, checks that the match code on both screens agrees, and the wallet signs the challenge. The server recovers the signing address from the signature, matches it to the citizen, and opens the session. The envelope contains no secret at all; an intercepted QR is just a puzzle with no prize.
Challenges are short-lived and consumed exactly once — a replayed signature meets a spent challenge and fails.
Passkeys
For a second factor, or a passwordless first one, the Republic issues passkeys (WebAuthn). Your device's authenticator — fingerprint reader, face unlock, or hardware key — generates a key pair; the server stores only the public half and a signature counter. Phishing sites fail structurally: a passkey is bound to the Republic's domain and will not answer to an imitation. This is why the Republic chose passkeys over authenticator-app codes, which can be phished in real time.
