diff --git a/docs/design/0002-game-account-management.md b/docs/design/0002-game-account-management.md index 12c49782..73d05e79 100644 --- a/docs/design/0002-game-account-management.md +++ b/docs/design/0002-game-account-management.md @@ -8,6 +8,30 @@ admin, for every live server. Drop becomes the single account surface; the `mmo.quasarke.net` portal keeps its archive/catalog job and stops being an identity tool. +## What this actually is: an identity bridge + +**None of these emulators support OIDC, and none of them are going to.** Every +one ships its own login solution against its own auth database — EQEmu's +loginserver tables, TrinityCore's SRP6 verifiers, OpenDAoC's own scheme. That +is not a gap to be closed; it is the permanent shape of the problem. + +So this feature is not SSO for the game servers. It is a **bridge**: one Drop +(SSO) identity, tied to one native game account per server, so a player has a +single place to create, find and reset credentials they will then type into a +game client that has never heard of Authentik. + +Two things follow directly, and they are the answers to what would otherwise +be open design questions: + +- **One account per user per server.** Not a limitation imposed for tidiness — + it is what "tie my SSO identity to my account on that server" means. The + unique constraint on `(userId, serverSlug)` is the feature. +- **No separate authorization gate.** If a user can reach Drop and reach the + game, they may create an account. Drop membership already implies the former + and the `game-access` group already implies the latter, so a third check + would only add a way for the two to disagree. Provisioning is gated on an + authenticated Drop session and nothing else. + ## Why move it rather than link to it mmo-portal already solves this properly. It has a real cross-game abstraction @@ -71,15 +95,18 @@ Five live servers, from the probe registry: |---|---|---|---| | EQEmu (EverQuest) | `eqemu` | `peq.account` + loginserver, MariaDB | ✅ `eqemu.py` | | TrinityCore WotLK | `wow` | SRP6 auth DB, MySQL | ✅ `trinitycore.py` | -| TrinityCore retail | (tbd) | separate auth DB, same schema family | ✅ reuse `trinitycore.py`, second config | | OpenDAoC | `daoc` | own auth DB | ✅ `opendaoc.py` | | Impostor (Among Us) | — | **no accounts at all** | n/a — status only | +| TrinityCore retail | — | **ON HOLD** (owner, 2026-08-07) | deferred | -So: four of five need account management and all four already have a working +So: three servers need account management and all three already have a working provider. Impostor is a lobby server with no identity; it gets status and join instructions only, and the UI must not render an account panel for it. That is exactly what `is_configured()` returning False already expresses. +Retail TrinityCore is deferred, not designed out — when it lands it is a +`GameServer` row plus a second `trinitycore.py` config, no new code. + ## Design ### Port the layer, don't rewrite it @@ -191,12 +218,17 @@ pipeline. See [[drop-launcher-button-patch]]. Phase 1 is independently useful: it makes the provider layer callable from anything, including scripts. -## Open questions for the owner +## Decisions (owner, 2026-08-07) -- **Retail TrinityCore slug** — it needs its own `GameServer` row and provider - config; is it in the registry yet? -- **Who may create a game account?** Any Drop user, or gated on the - `game-access` / `mmo_user` groups? Drop membership is currently the implicit - answer; worth being explicit. -- **One game account per user per server**, or several? The unique constraint - above assumes one. +- **Retail TrinityCore is on hold.** Not in scope; costs nothing to add later. +- **Authorization: none beyond a Drop session.** If a user can access Drop and + access the game, they can make an account. No `game-access` / `mmo_user` + check in this code path — see "identity bridge" above for why a third gate + would only create disagreement between two existing ones. +- **One account per user per server.** Unique on `(userId, serverSlug)`. + +## Open + +- **Does `LinkedAuthMec.credentials` carry the Authentik `sub`?** Determines + whether the existing mmo-portal links migrate by join or by one-time + re-confirmation. Verify before building phase 2; do not assume.