Heimdall/docs/app-profiles/streampixels.md
Meta Vens e1ac84fb70 Joystick custody needs a creator binding, at start and at the callback
callbackMint now takes the connection: custody_only is a connect for a
managed-connection-only provider bound to connection.kind creator with a
targetId. Anything else is refused at start with creator_connection_required
before any redirect, and at the callback from the signed state before the
code exchange. The streampixels profile note says what Heimdall guarantees
and records the S1 rule that SP's redeem treats a non-creator Joystick
completion as an error, never a sign-in.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 14:34:24 +02:00

3.7 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 is admitted only with connection.kind creator and a targetId, refused otherwise at start and again at the callback before the code exchange; an admitted one stores the credential and mints a claim with no facts, no capabilities and no refresh token. Heimdall's claim is therefore never a viewer session. Heimdall cannot stop an app from minting its own viewer from a completion, so StreamPixels' redeem must treat a non-creator Joystick completion as an error, never as a sign-in. This is an S1 rule, recorded for SP)
  • 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.