service_role treated as anon, by GraphiQL
@olirice is already working on this.
Since May 16, 2026.
Assessment
This issue has not been assessed yet.
Description
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:
- 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).
- run supabase@latest locally
- add some data to a table
- query it as the service_user and it's identical to anon
- 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:
- PostgreSQL: 15.8
- pg_graphql: 1.5.11
- pg_graphql commit ref: ea2ab60
nodejs deps:
@supabase/supabase-js@2.105.4
@supabase/auth-js@2.105.4
@supabase/storage-js@2.105.4
@supabase/realtime-js@2.105.4
@supabase/functions-js@2.105.4
@supabase/postgrest-js@2.105.4
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
SELECTprivileges on the public schema. Therefore, the function returnstrue, andpg_graphqlcompiles the schema docs cleanly. - When you switch to
service_role,current_setting('role')switches to 'service_role'. - Because the
service_roleis a specialized system token built to bypass Row Level Security (RLS), it doesn't have standard, explicit relational tableSELECTgrants applied to individual tables by default. It reads data during runtime purely because itsBYPASSRLSsuperuser 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.
- Dominant language
- Rust
- Stars
- 3.4k
- Forks
- 141
- Avg merge
- 19m
- Merged PRs (30d)
- 2
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from supabase/pg_graphql
-
Difficulty 5/5 Over a week Newbie friendliness 25/100
supabase/pg_graphql#646 ·
-
triage-required
supabase/pg_graphql#641 · 1 comment · 1 assignee ·
-
triage-required
supabase/pg_graphql#629 · 1 assignee ·
-
triage-required
supabase/pg_graphql#617 · 1 comment · 1 assignee ·
-
question
supabase/pg_graphql#602 · 12 comments · 1 reaction · 1 assignee ·
All issues in supabase/pg_graphql
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
kwakseongjae/auto-hwp#319 ·
-
area:cli bug filter-quality good first issue priority:medium
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
Difficulty 1/5 Under an hour Newbie friendliness 72/100
bevyengine/bevy#25861 ·
-
comp-datalake
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
ClickHouse/ClickHouse#121222 ·
-
enhancement remote
Difficulty 2/5 1-3 hours Newbie friendliness 68/100