Skip to content

feat: rotating refresh tokens for player auth#145

Merged
Taure merged 1 commit into
mainfrom
feat/rotating-refresh-tokens
Jul 1, 2026
Merged

feat: rotating refresh tokens for player auth#145
Taure merged 1 commit into
mainfrom
feat/rotating-refresh-tokens

Conversation

@Taure

@Taure Taure commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Wires the published nova_auth 0.2.0 rotating-refresh-token model into asobi's player auth, replacing the single opaque session token.

What changes

  • Tokens: login/register/oauth now return a short-lived access_token (60 min) + a rotating refresh_token (30 days) instead of session_token. Refresh tokens are single-use; replaying a rotated one is treated as theft and burns the whole token family (reuse_detected).
  • POST /api/v1/auth/refresh now takes {"refresh_token": ...} and returns a fresh pair.
  • POST /api/v1/auth/logout (new): revokes the refresh family and deletes the presented access token.
  • Schema/DB: player_tokens gains family_id + used_at (+ index); migration m20260701130000_add_refresh_token_columns adds the columns (first alter_table migration in the repo).
  • Auth cache resolves via nova_auth_refresh:get_user_by_access_token/2; the existing ban gate (ensure_active/is_banned) is preserved.
  • Deps: nova_auth ~> 0.2 (0.2.0); nova_auth_oidc 0.1.3 (the version built against nova_auth 0.2.0; also carries the iss-claim validation fix).
  • Dialyzer: fixed a latent asobi_oidc_config spec (nova_auth_oidc:oidc_config/0 never existed → map()) and added nova_auth/nova_auth_oidc to plt_extra_apps.

⚠️ Breaking (SDK clients)

The auth response shape changes: session_tokenaccess_token + refresh_token. Clients must store the refresh token and call /auth/refresh (rotating it) on a 401, then /auth/logout to end a session. All game SDKs (dart/js/unity/unreal/godot/defold) need updating to match — tracked as the next step.

Tests

  • Migrated the ~18 CT suites to access_token.
  • Added refresh_reuse_detected and logout_revokes_family HTTP tests to asobi_api_SUITE.
  • Local green: compile / as test compile, xref, cache eunit 6/6, and dialyzer clean. CT suites run against Postgres in CI.

Replace the single opaque session token with a short-lived access token
(60m) paired with a rotating refresh token (30d), backed by
nova_auth_refresh (nova_auth 0.2.0). Refresh tokens are single-use with
reuse detection: replaying a rotated token burns the whole family.

- bump nova_auth ~> 0.2 (0.2.0); nova_auth_oidc 0.1.3 (pairs with 0.2.0,
  adds the iss-claim validation fix)
- player_tokens: add family_id + used_at (+ index); migration adds columns
- asobi_auth: token_schema now carries family_id/used_at (TTLs use
  nova_auth defaults: 60 min access / 30 day refresh)
- asobi_auth_tokens: shared issue/2,3 and revoke_access/1
- controllers: register/login/oauth issue access+refresh pairs; refresh
  rotates; new POST /api/v1/auth/logout revokes the family + access token
- auth cache resolves via get_user_by_access_token
- dialyzer: fix asobi_oidc_config spec (oidc_config/0 never existed ->
  map()) and add nova_auth/nova_auth_oidc to plt_extra_apps
- tests: migrate suites to access_token; add reuse-detection + logout tests

The client response shape changes from `session_token` to
`access_token` + `refresh_token`; SDKs must persist the refresh token and
rotate on 401.
@Taure Taure force-pushed the feat/rotating-refresh-tokens branch from 1cb607c to 69270af Compare July 1, 2026 20:37
@Taure Taure merged commit 052b5c9 into main Jul 1, 2026
15 checks passed
@Taure Taure deleted the feat/rotating-refresh-tokens branch July 1, 2026 20:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant