Game guide · source of truth
Tech

Accounts and sign-in

One account for the website and the game — one-tap "Sign in with Google" on the web, the same Google account in the Windows, Android, iOS and Web clients (plus Sign in with Apple on iOS), server-side token verification, Zoen sessions, linking, recovery and the owner's setup steps.

Decision (owner, round 6): players sign in with one tap using their Google account, on the website and in the game. One Zoen account per Google account; the same account works on every platform. Status: proposed design, built in M6 (gateway) and M11 (site + store builds). Data: web-account.json → auth.

◆Flows per platform

WhereHow the player signs inTechnical flow
Website (apps/site)Google One Tap prompt on first visit + a "Sign in with Google" button in the headerGoogle Identity Services (GIS) for Web → ID token (JWT) → POST /v1/auth/google
Web build of the gamealready signed in on the site; the game page reuses the sessionsite session cookie → short-lived game ticket → zone admission
Android appone-tap bottom sheet ("Sign in with Google")Android Credential Manager with the Google ID option → ID token → gateway
iOS app"Sign in with Google" and "Sign in with Apple" buttonsGoogle Sign-In SDK / AuthenticationServices → ID token → gateway
Windows appbutton opens the system browser (never an embedded web view), the player taps their Google account, the browser returns to the launcherOAuth 2.0 authorization code + PKCE with a loopback redirect (RFC 8252) → gateway exchanges and verifies
  • iOS rule: Apple's App Review Guidelines require an equivalent privacy-focused login option when an app uses a third-party login such as Google; Sign in with Apple satisfies it. Re-check the current guideline wording at M11.
  • An Apple-only player gets a normal Zoen account; they can link Google later (and the other way round).

◆Server side (gateway)

  1. Verify every Google ID token on the server: signature against Google's published keys (cached), iss is Google, aud is one of our client IDs, exp not passed, and the nonce we issued. Never trust a token the client only decoded.
  2. Look up the account by the provider's stable subject id (sub), not by email. Store the email only for account recovery notices (never shown publicly, never in the public API).
  3. Issue Zoen's own session: a short-lived access token (15 min) and a rotating refresh token bound to the device; "Sign out everywhere" revokes every refresh token. Google tokens are not stored after verification.
  4. First sign-in creates the account and asks only for a display name (character names are separate).
  5. Rate-limit sign-in attempts per IP and per account; log every sign-in for the security system (Security & auto-ban).

◆Linking, recovery, deletion

  • Settings → Account: link/unlink Google and Apple (at least one must stay linked).
  • Lost Google access → support form on the site (not automated; identity checked by staff).
  • Account deletion from the site and in-game (store requirement), with a 14-day grace period; ranking entries are anonymised, receipts kept only as long as the law requires.

◆Website one-tap details

  • Use GIS One Tap (which uses the browser's FedCM support where available) plus the standard button. Show One Tap on the home page and on "Play in browser"; never on top of video or on checkout.
  • Redirect mode must check the g_csrf_token cookie/body pair; popup mode uses the nonce.
  • Signed-in pages: Caravan Ledger, Redeem key, Account, the inventory playground's "load my character".

◆Owner setup (agents never create accounts)

  1. A Google Cloud project for Zoen (free) → OAuth consent screen (app name, logo, privacy policy and terms URLs).
  2. OAuth client IDs: Web (site origins), Android (package name + signing-certificate SHA-1), iOS (bundle id), Desktop (Windows launcher, loopback).
  3. Apple Developer account (OPEN-5) for Sign in with Apple and the iOS build.
  4. Give the client IDs to the agent as configuration (they are not secrets); any client secret goes into the server's secret store, never into the repo.

◆Tests

  • Gateway: verification rejects wrong aud, expired, bad signature, missing nonce; a replayed token fails.
  • Site: Playwright with a mocked GIS script (no real Google login in CI).
  • Clients: PlayMode test with a stubbed provider returns a gateway session; the Windows flow is tested against a local fake authorization server.

Source: zoen/docs/tech/ACCOUNTS_AUTH.md · 768 words · edit the Markdown, not this page.