service_role treated as anon, by GraphiQL

Aperta
#642 0 commenti 0 reazioni 1 assegnatario Vedi su GitHub

@olirice ci sta già lavorando.

Dal 16/5/2026.

  • #1 di @jeremybradbury — aperta

Valutazione

Questa issue non è ancora stata valutata.

Descrizione

triage-required

Describe the bug

If you try to run queries as the service_role, it ends up mapping to anon, because the query only checks for explicit SELECT allows, and doesn't also check if it's the service user, which only has BYPASSRLS, and no specific table grants.

I'm surprised this hasn't been reported or fixed, in the right repo yet (prob in studio or main, even if the issue is here). I'll try to follow this quickly with a PR, but it's gonna take some testing. Below is a breakdown of what's wrong and how.

To Reproduce
Steps to reproduce the behavior:

  1. ensure analytics is true on first run or the settings tab breaks (this grabs logflare and vector images, that the maintainers probably always have on).
  2. run supabase@latest locally
  3. add some data to a table
  4. query it as the service_user and it's identical to anon
  5. same query but impersonated (and proper RLS for SELECT setup), will work.

Expected behavior
GraphiQL should return data from any and all tables, show full public schema introspection.

Screenshots
I'll try to come back with these, along with the solution.

Versions:

Additional Info
The pg_graphql extension generates the entire GraphiQL schema view by executing an internal SQL function that scans Postgres catalogs. By default, the code inside the extension determines whether a table should be exposed to the GraphiQL panel by checking if the active role has explicit table-level SELECT grants. This is how the pg_graphql C/SQL compiler filters table visibility:
WHERE has_table_privilege(current_setting('role'), table_id, 'SELECT')

Why service_role Treats You as Unauthenticated
  • When you Impersonate a User the GraphiQL panel sets current_setting('role') to 'authenticated'. In Supabase's default template, the authenticated role possesses explicit SELECT privileges on the public schema. Therefore, the function returns true, and pg_graphql compiles the schema docs cleanly.
  • When you switch to service_role, current_setting('role') switches to 'service_role'.
  • Because the service_role is a specialized system token built to bypass Row Level Security (RLS), it doesn't have standard, explicit relational table SELECT grants applied to individual tables by default. It reads data during runtime purely because its BYPASSRLS superuser attribute overrides access limits during raw execution.

Because has_table_privilege('service_role', table_id, 'SELECT') checks for explicit relational grants rather than bypass attributes, it evaluates to false. The extension concludes that the service_role string has no visible entities, returns an entirely empty schema map, and causes GraphiQL to drop you into an unauthenticated fallback state.

Lingua principale
Rust
Stelle
3.4k
Fork
142
Merge medio
5h 26m
PR unite (30g)
3

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di supabase/pg_graphql

Tutte le issue di supabase/pg_graphql

Issue simili

Altre issue su Rust

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.