mancala/docs/specs/keycloak-auth/requirements.md
Halit Aksoy ab2424b648 docs: add Keycloak login spec
Requirements, design decisions and tasks for the Keycloak login, written
after the implementation; mobile login and turning off legacy userKey
login remain open.
2026-10-16 00:40:57 +03:00

3.6 KiB

Login with Keycloak: requirements

Status: implemented for the backend and the web app on branch feature/keycloak-auth; the mobile app still uses the legacy userKey login (see tasks.md). Written after the implementation, from the decisions made while building it.

Goals

People can play without signing up, and can sign up or log in when they want to. Every player has an identity that cannot be taken over by someone else, and one system handles all of it.

Terms

  • Guest: a player who has not signed up. A guest is a Keycloak user with the guest role.
  • Account: a Keycloak user who signed up with a username and password.
  • Legacy client: an app version that identifies itself with a userKey from GET /register instead of a token (the mobile app released before this work).

Requirements

R1. Playing without signing up

  • R1.1 A first-time visitor of the web app is logged in as a new guest without seeing any form; the page briefly passes through Keycloak and comes back to where the visitor started.
  • R1.2 A returning guest keeps the same identity for 30 days after their last visit, also after closing the browser.
  • R1.3 Guests who have not been back for 30 days, and are at least a day old, are deleted from Keycloak.
  • R1.4 Starting guest logins is rate limited per IP address, since each one creates a user.

R2. Identities are secure

  • R2.1 The server, not the client, decides who a connection belongs to, based on a token signed by Keycloak.
  • R2.2 A token that is forged, expired, issued by another server, issued to another client, or is not an access token is rejected.
  • R2.3 Knowing another player's id (e.g. from a game) is not enough to act as that player.
  • R2.4 A connection that does not authenticate within 5 seconds is closed; messages sent before authentication are ignored.

R3. Accounts

  • R3.1 A guest can sign up or log in from the home page; afterwards they play as that account.
  • R3.2 A logged-in user can log out; they then continue as a new guest.
  • R3.3 Logging in and signing up are only offered on the home page, so nobody changes identity during a game.

R4. Several devices

  • R4.1 A user logged in on several devices or tabs is connected on all of them at once; all of them receive game updates.
  • R4.2 A user counts as offline only when their last connection closes.
  • R4.3 Reconnecting does not drop the user's new connection when the old one closes late.

R5. Names

  • R5.1 Players see each other's names during a game. Accounts show their username; guests show as "Guest" and four characters of their generated username (e.g. "Guest 4F2A", "Misafir 4F2A" in Turkish).
  • R5.2 The account menu on the home page shows the user's own name.

R6. Sessions stay valid

  • R6.1 Access tokens are renewed before they expire without interrupting the game connection.
  • R6.2 If the session can no longer be renewed, the user continues as a new guest.

R7. Old app versions keep working

  • R7.1 While LEGACY_USERKEY_AUTH is on (the default), legacy clients connect with ?userKey= and use /register as before.
  • R7.2 A legacy client cannot use the id of a Keycloak user.
  • R7.3 When the setting is off, userKey connections and /register are refused.

R8. One auth system

  • R8.1 Keycloak is the only place where users and sessions live; the backend only checks tokens and does not call Keycloak per request.
  • R8.2 Keycloak, its configuration and its extension are part of this repository and can be run locally with Docker Compose.

Out of scope (see TODO.md)

  • Login in the mobile app.
  • Turning a guest into an account without changing identity.
  • Social logins.
  • Deleting accounts.