Authentication
No Passwords, Ever
Relay does not use passwords. There is no password field, no password database, no password hash on the server, and no password reset flow.
Instead, authentication is a cryptographic challenge-response. The server sends a random challenge. Your device signs it with its Ed25519 auth private key. The server verifies the signature against the auth public key it has on file. If the math checks out, you are in.
This eliminates entire categories of attack: no passwords to phish, no password databases to breach, no credential stuffing, no brute-force attacks against password hashes.
In plain English: Instead of proving who you are with a password (something you know), you prove it with a cryptographic key (something your device has). It is like using a physical key to open a lock, except the lock changes every time and the key generates a unique proof for each challenge.
The Auth Flow
Registration
Login
Challenge Format
The server generates challenges in the format:
relay-auth:<32 random bytes as hex>:<timestamp>Challenges are:
- Single-use (consumed on successful verification)
- Time-limited (5-minute expiry)
- Bound to a specific auth public key
Signature Verification
The server uses Ed25519 signature verification via tweetnacl:
- The challenge string is encoded to UTF-8 bytes.
- The signature (base58-encoded) and public key (base58-encoded) are decoded.
nacl.sign.detached.verify(message, signature, publicKey)returns true or false.
No timing oracles. No partial verification. It either verifies or it does not.
Token Management
After successful authentication:
| Token | Lifetime | Purpose |
|---|---|---|
| Access token (JWT) | Short-lived | Authorizes API requests |
| Refresh token | 90 days | Exchanges for a new access + refresh token pair |
Refresh tokens are:
- Stored in the database (hashed)
- Single-use (rotated on every refresh)
- Revoked on logout
Silent Re-authentication
When the app launches, it attempts authentication in this order:
- Refresh token — fastest, no biometric prompt needed.
- Full signature auth — fallback if refresh token is expired or unavailable. Requires biometric prompt to access the auth private key.
This means you rarely have to explicitly "log in" — the app silently refreshes your session in the background.
Seed Phrase Recovery
Recovery follows the same flow as registration, but instead of generating a new mnemonic, you provide an existing one:
- Import the 12-word seed phrase.
- Derive the auth keypair at
m/44'/501'/1'/0'. - Attempt to log in with the derived auth public key.
- If a matching account exists, authentication succeeds.
- If no account exists, the user can register a new username with the same key.
The wallet keypair is also re-derived, restoring access to all on-chain funds.
In plain English: If you lose your phone, you install Relay on a new one, type in your 12 words, and you are back. The app re-derives your keys, proves to the server that it is you (because only someone with those 12 words could produce the right signature), and gives you back your account. Your crypto balance was never at risk — it lives on the blockchain, not on the old phone.