Heimdall/docs/app-profiles/streampixels.md

81 lines
3.7 KiB
Markdown
Raw Normal View History

2026-04-26 05:18:35 +01:00
# StreamPixels Access Profile
## What this file is
2026-04-26 11:41:27 +01:00
This file records how StreamPixels should fit onto Heimdall in
2026-04-26 05:18:35 +01:00
`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.
2026-04-26 05:18:35 +01:00
## 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"
2026-04-26 05:18:35 +01:00
- 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
2026-04-26 11:41:27 +01:00
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)
2026-04-26 11:41:27 +01:00
- entitlement refresh
- shared claim semantics
2026-04-26 05:18:35 +01:00
## What StreamPixels should keep separate
- viewer audience profiles
- creator memberships tied to streamer spaces
- creator connector bindings and feature semantics
2026-04-26 05:18:35 +01:00
- overlay/runtime state
- audience-facing app data in general
In plain language:
2026-04-26 11:41:27 +01:00
- 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
2026-04-26 05:18:35 +01:00
- 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.