mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 17:35:10 +03:00
Scoped PATs are enforced server-side as the intersection of the token's granted scopes and the owner's live role, re-checked on every request. The UI previously said nothing about this: any member could select any permission scope for any resource, get no warning at creation, and the token view kept rendering stored scopes as fact after the owner's access changed. This adds advisory (never blocking) feedback across the whole scoped-token flow so users learn at selection time -- not at their first 403 -- what a token can actually do. Core (AccessToken.roles.ts, all pure and unit-tested): - FGA_SCOPE_MINIMUM_ROLE: all 83 permission scopes transcribed from the OpenFGA model's role unions, mapped to the lowest base role that holds them. A drift-guard test pins the key set to the scope ids published in @supabase/shared-types, so upstream additions fail CI here with re-transcription instructions. - estimateRoleLevel: derives the user's base role per org (or per project for project-invited members) from the ungated /platform/profile/ permissions rows via four discriminating ABAC probes, verified against the platform's default_permissions seeds. Works for every member type with no permission-gated endpoint. - computeTokenRoleContext + applySelectionToRoleContext: role resolution (expensive, memoized) is split from selection evaluation (cheap, re-run per permission toggle). Results carry per-resource failing roles, including per-project detail for members invited to projects rather than the org. Creation form: - Orgs where the user only has project-level access are disabled in org-scope mode, with an inline explanation. - Permission rows and the review summary show a red "Exceeds your role" pill whose tooltip names the exact resources where requests would be denied, the required role, and the user's actual role there (spelling out per-project roles for project-invited members). - The review admonition breaks exceeded permissions down per resource, organizations first; the risk badge is computed on the role-capped effective scope set. - The immutability warning moved from a persistent admonition to micro-copy at the point of commitment; the permissions step links the access-control docs. Token view sheet: - Lost access is distinguished from deletion (deleting a project/org erases the token's FGA bindings; removal does not): bindings that vanished render a "resources no longer exist" state, while bindings the user can no longer reach show an anonymous count with a "No longer accessible" badge and a "removed from" admonition. - Accessible resources list name plus ref/slug; capabilities carry the same exceeds-role pills; risk reflects what the owner's current role allows. Header now has separate Access control and API docs buttons (DocsButton gained a label prop). All signals recompute from live org/project/permission queries, so the view tracks membership changes without stored state, and everything degrades to "no warnings" while data loads or on self-hosted.