ADR 0018. URL-Isolated Portals, No In-Product Role Picker
Status
Accepted.
Context
A single back office with a role dropdown implies the user chooses their security domain. That is the wrong boundary: authentication and authorization should determine what a principal may do inside a portal they were sent to. Mixing player, partner and staff sessions in one origin also collides cookies and OAuth clients.
Decision
Each audience is a separate URL (or path that is treated as a separate security audience), with its own OAuth client, redirect URIs, session cookie and permission policy:
| Audience | Example |
|---|---|
| Player | my.playerpal.io |
| PlayerPal staff | admin.playerpal.io |
| Operator | partners.playerpal.io/operator |
| Provider | partners.playerpal.io/provider |
| Affiliate | partners.playerpal.io/affiliate |
There is no role selector inside the product. The wrong portal returns an access error, not a switcher. One person with several roles uses several URLs.
UI visibility is not authorization. APIs enforce tenant, audience and permission (spec §17).
Consequences
- Demo apps under
demos/apps/portalsfix audience by path. - Shared UI packages are allowed; shared session cookies across player/staff/ partner origins are not.
- See docs/portals.md.