mirror of
https://github.com/supabase/supabase.git
synced 2026-10-07 10:25:06 +03:00
The permission scope map previously flattened every `x-fga-permissions` annotation into a single conjunctive scope list, turning OR-alternatives (e.g. development vs production branching on `GET /v1/.../branches`) into impossible AND requirements. EndpointMap and McpMap now store ScopeGroupAlternatives (string[][]) verbatim, and an item is enabled when ALL scopes of at least ONE group are granted — matching how the mgmt-api FGA guard actually evaluates the annotation. Edge cases follow plain DNF semantics: `[[]]` (one empty group) is ungated and callable by any token, `[]` (no groups) is satisfied by nobody, and endpoints with unusable annotations are dropped rather than recorded as ungated. The MCP tool map is rewritten as a direct audit of the Management API endpoint each tool's handler in @supabase/mcp-server-supabase actually calls, with the endpoint named above every entry for re-auditing. The old two-hop derivation (tool -> legacy OAuth scope bundle -> FGA permissions) expanded coarse bundles into conjunctions of permissions the tool never uses, hiding tools from tokens that could genuinely call them. The map now covers the full tool registry, including ungated tools (search_docs, get_project_url, get_cost, confirm_cost), and a new test diffs its keys against the installed package's tool schemas so a dependency bump that adds or drops a tool fails CI by name. buildAPIPermissionScopeMap now fetches the v1/v2 specs in parallel and indexes them in one pass (their path prefixes can't collide), replacing the lodash mergeWith custom-merger, and deep-clones the module-level tool mapping so callers can't mutate state that outlives the request.