Refresh Repixelizer app claims through Heimdall

This commit is contained in:
Meta Vens 2026-05-20 13:43:53 +01:00
commit ee8c012c85
15 changed files with 712 additions and 7 deletions

View file

@ -21,3 +21,4 @@
{"ts": "2026-04-29T15:25:08+00:00", "type": "verification", "status": "accepted", "note": "Live StreamPixels Twitch sign-in through Heimdall succeeded on Yggdrasil: Heimdall audit shows oauth_callback_succeeded, auth_completion_created, and auth_completion_redeemed for twitch after the scope normalization deploy."}
{"ts": "2026-04-29T16:17:34+00:00", "type": "design", "status": "accepted", "note": "Twitch EventSub subscription management must use the same Twitch application Client-ID as Heimdall creator OAuth, because Twitch authorizes EventSub creation against the app token Client-ID even when StreamPixels stores no creator refresh token."}
{"ts": "2026-04-29T16:24:26+00:00", "type": "implementation", "status": "accepted", "note": "Heimdall managed-credential resolution now refreshes Twitch and YouTube access tokens when they are expired or within the refresh window, preserving refresh-token custody in Heimdall while returning only access tokens to app runtimes."}
{"ts": "2026-05-20T12:43:02+00:00", "type": "implementation", "status": "accepted", "note": "Heimdall now issues signed app refresh tokens, exposes /v1/apps/{appSlug}/sessions/refresh, refreshes Discord/Patreon provider tokens before Repixelizer entitlement re-evaluation, and reissues short-lived app access claims without restarting provider OAuth."}

View file

@ -73,6 +73,8 @@ accepted_design:
- The first stateful slice adds durable auth/control-plane storage plus a real Discord callback path for Repixelizer.
- Repixelizer has consumed the Heimdall backend-callback flow in its hosted web layer; Heimdall no longer needs to wait on Repixelizer refactoring before live Discord launch work.
- Heimdall is deployed on Yggdrasil at `https://heimdall.gamecult.org` with nginx/TLS, Postgres storage, file-backed signing-key bootstrap, configured token custody, and passing public health/discovery/JWKS checks.
- Heimdall now issues signed app refresh tokens alongside short-lived access claims and exposes `/v1/apps/{appSlug}/sessions/refresh` so app backends can reissue local claims without restarting provider OAuth.
- Discord and Patreon provider access tokens can refresh inside Heimdall before Repixelizer entitlement re-evaluation.
- Repixelizer is deployed on Yggdrasil at `https://repixelizer.gamecult.org` with `GC_ACCESS_MODE=heimdall`, `GC_ACCESS_ALLOWED_PROVIDERS=discord,patreon`, required access, queue protection enabled, app-owned Discord guild/role policy, and app-owned Patreon tier-title policy sent to Heimdall during backend-callback OAuth start.
- StreamPixels viewer and creator provider OAuth should start through Heimdall; StreamPixels redeems one-time completion codes, owns local profile/connector binding, and resolves current provider access tokens from Heimdall by app-authenticated managed-credential calls.
@ -85,6 +87,7 @@ landed_baseline:
- The first real provider slice landed for Discord callback exchange, identity resolution, entitlement evaluation, and session/claim issuance for Repixelizer.
- Signing-key persistence/bootstrap, managed token encryption at rest, and a local verifier seam landed for the first real consumer integration pass.
- Direct backend callback handoff landed as the preferred same-host app-consumer path, with browser completion-code exchange retained as fallback.
- Signed session refresh landed for app-facing claims: refresh tokens remain Heimdall-issued, provider refresh tokens remain sealed in Heimdall, and callers can provide app-owned entitlement policies for re-evaluation.
- Repixelizer's hosted web layer now creates Heimdall auth attempts, receives direct backend callbacks, verifies Heimdall Ed25519 access tokens locally, and adopts httpOnly local sessions.
- Heimdall now has generic Twitch and YouTube OAuth callback runtimes plus an app-authenticated managed-credential resolve endpoint for app-owned connector runtimes.
- StreamPixels now starts viewer and creator Twitch/YouTube OAuth through Heimdall, redeems Heimdall completion codes server-side, writes its own viewer sessions and creator connector bindings, and leaves provider refresh-token custody in Heimdall.
@ -98,5 +101,5 @@ rejected_paths:
reason: reusing auth mechanics does not justify centralizing app-domain audience or product data
current_status:
summary: Heimdall and StreamPixels are deployed on Yggdrasil for the StreamPixels auth migration slice. Heimdall has Twitch/YouTube provider credentials, the shared StreamPixels app secret, generic Twitch/YouTube identity and managed-credential custody runtimes, and a live fix for Twitch token responses that return scopes as arrays. Live StreamPixels Twitch sign-in through Heimdall has succeeded and redeemed a completion code. StreamPixels delegates Twitch/YouTube OAuth to Heimdall, redeems one-time completion codes through its service, writes its own httpOnly viewer session, stores local profile/creator connector binding state, and asks Heimdall for current provider access tokens when runtime code needs them. The key boundary still holds: Heimdall owns provider OAuth and credential custody; StreamPixels owns viewer profiles, creator memberships, connector config, diagnostics, EventSub/live-chat runtime behavior, and audience data.
summary: Heimdall and StreamPixels are deployed on Yggdrasil for the StreamPixels auth migration slice. Heimdall has Twitch/YouTube provider credentials, the shared StreamPixels app secret, generic Twitch/YouTube identity and managed-credential custody runtimes, and a live fix for Twitch token responses that return scopes as arrays. Live StreamPixels Twitch sign-in through Heimdall has succeeded and redeemed a completion code. StreamPixels delegates Twitch/YouTube OAuth to Heimdall, redeems one-time completion codes through its service, writes its own httpOnly viewer session, stores local profile/creator connector binding state, and asks Heimdall for current provider access tokens when runtime code needs them. Repixelizer access now has a signed Heimdall refresh-token path: apps can exchange the refresh token for a fresh short-lived access claim, while Heimdall refreshes Discord/Patreon provider tokens and re-evaluates app-owned entitlement policies without restarting provider OAuth. The key boundary still holds: Heimdall owns provider OAuth and credential custody; host apps own local sessions, route/resource checks, and app-domain data.
next_action: Complete the remaining real browser verification for StreamPixels: YouTube sign-in/link, creator Twitch/YouTube connector attach from an admin creator session, and local StreamPixels persistence checks. If a provider callback fails, inspect Heimdall audit events and StreamPixels service logs first; do not move provider-specific app state into Heimdall while debugging.