Reported live by Joey (Seq, 2026-07-11 ~20:5x): every game WebSocket connection logs Rejected invalid GameServer JWT (treating connection as unauthenticated) followed by ListShips/CreateShip/JoinZone failed: No user ID for connection ... - authentication required — for players with valid Keycloak sessions. Complete game-auth outage.
Root cause: the #407 hardening (backend PR #158) correctly replaced trust-the-sub-claim with real JWKS validation, but shipped Authentication:Audience = "spikersoft-api". This realm's Keycloak access tokens carry aud: "account" (Keycloak default — the same value the API validates via Keycloak:audience). Audience validation rejected every legitimate token. The validator's unit tests covered the mechanics with a synthetic audience; the config value was never tested against reality.
Fix: backend PR #214 — GameServer Authentication:Audience → "account" + regression test GameServerAudience_MatchesApiKeycloakAudience asserting the GameServer and API configs agree on the audience (they validate the same tokens).
Verify: after merge/deploy, the Rejected invalid GameServer JWT stream in Seq stops and in-game ListShips/CreateShip/JoinZone succeed for a logged-in player.
Follow-up option (separate scope): add a Keycloak audience mapper so tokens carry a real API audience, then tighten both services in lockstep.
Reported live by Joey (Seq, 2026-07-11 ~20:5x): every game WebSocket connection logs `Rejected invalid GameServer JWT (treating connection as unauthenticated)` followed by `ListShips/CreateShip/JoinZone failed: No user ID for connection ... - authentication required` — for players with valid Keycloak sessions. Complete game-auth outage.
**Root cause:** the #407 hardening (backend PR #158) correctly replaced trust-the-sub-claim with real JWKS validation, but shipped `Authentication:Audience = "spikersoft-api"`. This realm's Keycloak access tokens carry `aud: "account"` (Keycloak default — the same value the API validates via `Keycloak:audience`). Audience validation rejected every legitimate token. The validator's unit tests covered the mechanics with a synthetic audience; the config *value* was never tested against reality.
**Fix:** backend PR #214 — GameServer `Authentication:Audience` → `"account"` + regression test `GameServerAudience_MatchesApiKeycloakAudience` asserting the GameServer and API configs agree on the audience (they validate the same tokens).
**Verify:** after merge/deploy, the `Rejected invalid GameServer JWT` stream in Seq stops and in-game ListShips/CreateShip/JoinZone succeed for a logged-in player.
Follow-up option (separate scope): add a Keycloak audience mapper so tokens carry a real API audience, then tighten both services in lockstep.
Resolved in spikersoft-backend PR #214 (merged to master; CI auto-deploys the gameserver). GameServer Authentication:Audience corrected from 'spikersoft-api' to 'account' — the value this realm's Keycloak access tokens actually carry and the same one the API validates. Regression test GameServerAudience_MatchesApiKeycloakAudience now pins the two services' configs together so they can never disagree on the audience again. Verify as the deploy lands: the 'Rejected invalid GameServer JWT' stream in Seq stops, and ListShips/CreateShip/JoinZone succeed in-game for a logged-in player. If anything still rejects after the rollout, reopen — the next suspect would be issuer mismatch, and the Seq event's exception detail (IDX code) will say which. Closing.
Resolved in spikersoft-backend PR #214 (merged to master; CI auto-deploys the gameserver). GameServer Authentication:Audience corrected from 'spikersoft-api' to 'account' — the value this realm's Keycloak access tokens actually carry and the same one the API validates. Regression test GameServerAudience_MatchesApiKeycloakAudience now pins the two services' configs together so they can never disagree on the audience again. Verify as the deploy lands: the 'Rejected invalid GameServer JWT' stream in Seq stops, and ListShips/CreateShip/JoinZone succeed in-game for a logged-in player. If anything still rejects after the rollout, reopen — the next suspect would be issuer mismatch, and the Seq event's exception detail (IDX code) will say which. Closing.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Reported live by Joey (Seq, 2026-07-11 ~20:5x): every game WebSocket connection logs
Rejected invalid GameServer JWT (treating connection as unauthenticated)followed byListShips/CreateShip/JoinZone failed: No user ID for connection ... - authentication required— for players with valid Keycloak sessions. Complete game-auth outage.Root cause: the #407 hardening (backend PR #158) correctly replaced trust-the-sub-claim with real JWKS validation, but shipped
Authentication:Audience = "spikersoft-api". This realm's Keycloak access tokens carryaud: "account"(Keycloak default — the same value the API validates viaKeycloak:audience). Audience validation rejected every legitimate token. The validator's unit tests covered the mechanics with a synthetic audience; the config value was never tested against reality.Fix: backend PR #214 — GameServer
Authentication:Audience→"account"+ regression testGameServerAudience_MatchesApiKeycloakAudienceasserting the GameServer and API configs agree on the audience (they validate the same tokens).Verify: after merge/deploy, the
Rejected invalid GameServer JWTstream in Seq stops and in-game ListShips/CreateShip/JoinZone succeed for a logged-in player.Follow-up option (separate scope): add a Keycloak audience mapper so tokens carry a real API audience, then tighten both services in lockstep.
Resolved in spikersoft-backend PR #214 (merged to master; CI auto-deploys the gameserver). GameServer Authentication:Audience corrected from 'spikersoft-api' to 'account' — the value this realm's Keycloak access tokens actually carry and the same one the API validates. Regression test GameServerAudience_MatchesApiKeycloakAudience now pins the two services' configs together so they can never disagree on the audience again. Verify as the deploy lands: the 'Rejected invalid GameServer JWT' stream in Seq stops, and ListShips/CreateShip/JoinZone succeed in-game for a logged-in player. If anything still rejects after the rollout, reopen — the next suspect would be issuer mismatch, and the Seq event's exception detail (IDX code) will say which. Closing.