Heimdall/docs/app-profiles/streampixels.md
Meta Vens 79ea0007d3 OAuth callback: mode and provider role decide what a completion mints
The start gate only refused early. The callback ignored the signed state's
mode, so a Joystick connect for StreamPixels redeemed into a viewer_access
session. callbackMint(profile, provider, mode) now decides at the callback:
identity providers keep a viewer session (Bifrost discord connect unchanged);
a connect for a managed-connection-only provider stores custody and mints a
claim with no facts, no capabilities and no refresh token (the refresh route
would recompute viewer_access from the account); anything else is refused.
StreamPixels' redeem reads only account, provider, mode, connection and
claimSet.identities, so it accepts the capability-free claim unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 13:23:53 +02:00

3.3 KiB

StreamPixels Access Profile

What this file is

This file records how StreamPixels should fit onto Heimdall in docs/architecture.md without turning streamer-audience data into shared auth sludge.

It is a boundary note, not a command to rewrite StreamPixels around Repixelizer.

Public origin

https://streampixels.gamecult.org — this is the allowedReturnOrigins entry Heimdall's built-in streampixels profile carries (src/app-profiles.ts). Corroborated by gamecult-ops/nginx/streampixels.gamecult.org.conf:14 (server_name streampixels.gamecult.org) and StreamPixels' own .env example.

Current repo boundary

The current StreamPixels architecture already makes useful splits:

  • the web app owns the remembered viewer session
  • Heimdall owns provider OAuth exchange, identity resolution and refresh-token custody for Twitch, YouTube and Joystick; StreamPixels never calls a provider token endpoint and holds no provider refresh token. It asks Heimdall for a short-lived access token (managed-credentials/resolve) and treats 410 managed_credential_revoked as "the creator must reconnect"
  • the overlay remains auth-free
  • creator memberships and operator roles are separate from general viewer state

That is already compatible with the shared backbone idea.

What StreamPixels can reuse

  • signed local session mechanics
  • linked-identity and signed OAuth-state patterns
  • provider adapter structure
  • creator/operator capability evaluation
  • grant/invite primitives where they fit

In the service-first Heimdall version, the most likely reusable slice is:

  • provider OAuth authority
  • identity-linking authority
  • managed Twitch/YouTube/Joystick credential custody for creator connections (Joystick is a managed connection only, not a viewer sign-in provider: startOAuthFlow admits sign_in and link only for identityProviders and connect only for managedConnectionProviders or identityProviders, and refuses anything else before any redirect. The callback decides again from the signed state's mode: a connect for a managed-connection-only provider stores the credential and mints a claim with no facts, no capabilities and no refresh token, so it can never be a viewer session)
  • entitlement refresh
  • shared claim semantics

What StreamPixels should keep separate

  • viewer audience profiles
  • creator memberships tied to streamer spaces
  • creator connector bindings and feature semantics
  • overlay/runtime state
  • audience-facing app data in general

In plain language:

  • Heimdall can authenticate and authorize the control plane
  • Heimdall can also own OAuth flow and token custody for creator-side provider connections when that reduces auth duplication
  • StreamPixels still owns which creator a connection belongs to, what subscriptions or sync flows it drives, and how failures are surfaced
  • StreamPixels audience data stays StreamPixels data

Capability direction

Likely capability families:

  • viewer_access
  • creator_access
  • creator_admin
  • operator_access

These should bind onto the existing StreamPixels creator/operator separation instead of flattening it into one GameCult-member gate.

Invariant

If a future shared access store exists, it must not become the canonical home for streamer-audience identity and product data. That stays with StreamPixels.