SupabaseSteve ChavezProblem & solution
Protecting reserved roles with PostgreSQL Hooks
Summary
Supabase required granting database customers the CREATEROLE privilege to manage custom roles while preventing them from dropping or altering backend service roles such as supabase_storage_admin. Because stock PostgreSQL lacks a native mechanism to define custom reserved roles, the team created the SupaUtils extension using PostgreSQL hooks. Loaded via shared_preload_libraries, SupaUtils intercepts utility statements by overriding the global ProcessUtility_hook function pointer. The extension inspects incoming statements like ALTER ROLE and DROP ROLE against a configurable list defined in postgresql.conf using DefineCustomStringVariable. If a targeted role matches the configured reserved roles, the hook raises an error, preserving backend infrastructure roles while permitting broader role administration.
Context
At Supabase, backend services rely on dedicated database roles like supabase_storage_admin, but giving customers the CREATEROLE privilege allows them to drop or modify any non-superuser role. PostgreSQL does not natively support defining custom reserved roles beyond its built-in pg_ roles.
Approach / What changed
Supabase built the SupaUtils extension, which hooks into ProcessUtility_hook via shared_preload_libraries and uses DefineCustomStringVariable to expose a supautils.reserved_roles parameter. The hook inspects ALTER ROLE and DROP ROLE statement nodes (T_AlterRoleStmt and T_DropRoleStmt) and throws an error if any affected role matches the reserved list before delegating unblocked statements to previous hooks or standard_ProcessUtility.
Takeaways
The PostgreSQL CREATEROLE privilege allows modifying or dropping any role except superusers, creating operational risks when shared with customers on managed platforms.
PostgreSQL hooks are global function pointers that extensions loaded in shared_preload_libraries can override during _PG_init while preserving previously assigned hooks.
Utility statements such as ALTER ROLE and DROP ROLE can be intercepted by overriding ProcessUtility_hook and inspecting their internal node structures.
Source and freshness
- Source
- supabase.com
- Published
- Added to Yomu
- Last updated
Summaries are generated from the original by a language model. Check the original before relying on it.
Keep reading
Related reading
The Good Stuff
Paid picks we use ourselves. Links carry a referral code — a subscription through one earns us a commission at no extra cost to you.
The best engineering reads, once a week
One useful email. Unsubscribe anytime.