Deployment topology already says same-host apps reach Heimdall over
localhost or private routing and verify claims locally. The vhost never
implemented it: heimdall.gamecult.org.conf is one
`location / { proxy_pass http://heimdall_app; }`, so every route Fastify
registers is on the open web. The boundary existed in this document and
nowhere in the running system.
Proposed: public is the browser-driven OAuth pair plus JWKS; discovery,
/v1/apps, claim issuance and /healthz go internal. The private command
plane is unaffected -- it is a CultNet operation server and never touches
nginx.
JWKS stays public deliberately rather than by omission. No provider
fetches it (every adapter in src/oauth.ts uses client_secret, not
private_key_jwt) and every relying party today is mesh-reachable, so
nothing external needs it. But publishing verification keys is harmless,
and hiding it fails asymmetrically: the first externally-hosted relying
party gets integrated with a standard OIDC library, and a jwks_uri that
resolves only on the mesh fails confusingly at integration time instead of
obviously at design time.
Discovery and /v1/apps move together, since trimming discovery alone
leaves /v1/apps serving the same catalog. That catalog is a product
inventory: per app it emits identityProviders, entitlementSources,
managedConnectionProviders and capabilities, and with the command plane's
discord_role_access and patreon_membership_access record kinds the
monetization model is legible to anyone who fetches it.
Separately recorded: the spotify provider outlived its consumer.
Spotiverse was lost with the E: drive, it is the only profile naming
spotify, and GC_ACCESS_PROVIDER_SPOTIFY_CLIENT_ID/_SECRET are still
configured in /srv/heimdall/env/service.env while /v1/oauth/spotify/start
stays publicly reachable. That path would run a real OAuth handshake with
a real secret and take custody of a user's refresh token for a consumer
that cannot use it. Not a compromise; a live credential and a
token-custody path kept alive for nothing. Retiring it is its own change
and should not ride along with the boundary work.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>