Hosted PG15→17 upgrade: how should existing custom SECURITY DEFINER owner roles regain administration-only membership? #50609
Replies: 3 comments 1 reply
|
Here are the direct answers to your five questions regarding PostgreSQL 15 to 17 role grant transitions and 1. Does Supabase Automatically Normalize Custom Roles During Upgrade?No. 2. Supported Self-Service Procedure (Pre- and Post-Upgrade)You can achieve the desired steady-state ( Step A: Before Upgrade (on PG15)Grant the owner role to GRANT owner_role TO postgres WITH ADMIN OPTION;(In PG15, this creates the membership with Step B: During PG17 UpgradePostgreSQL 17
Step C: Immediately Post-Upgrade (on PG17)Because GRANT owner_role TO postgres WITH INHERIT FALSE, SET FALSE;This strips both Verify via: SELECT
r.rolname AS role_name,
m.rolname AS member_name,
a.admin_option,
a.inherit_option,
a.set_option
FROM pg_auth_members a
JOIN pg_roles r ON a.roleid = r.oid
JOIN pg_roles m ON a.member = m.oid
WHERE r.rolname = 'owner_role' AND m.rolname = 'postgres';Result: 3. Support-Assisted NormalizationIf you prefer not to grant GRANT owner_role TO postgres WITH ADMIN TRUE, INHERIT FALSE, SET FALSE;This directly injects the required row into 4. Updating SECURITY DEFINER Functions Post-UpgradeOnce in the Pattern A: Scoped Transactional SET Permission (Recommended for CI/CD)Because BEGIN;
GRANT owner_role TO postgres WITH SET TRUE;
SET LOCAL ROLE owner_role;
CREATE OR REPLACE FUNCTION public.my_secure_function()
RETURNS void
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = public, pg_temp
AS $$
BEGIN
-- function body
END;
$$;
RESET ROLE;
GRANT owner_role TO postgres WITH SET FALSE;
COMMIT;Pattern B: Direct Ownership ReassignmentUnder PostgreSQL rules, a role can transfer ownership of an object to a target role if the current user is a member of that target role (even if CREATE OR REPLACE FUNCTION public.my_secure_function()
RETURNS void
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = public, pg_temp
AS $$
BEGIN
-- function body
END;
$$;
ALTER FUNCTION public.my_secure_function() OWNER TO owner_role;5. Is Pre-Granting on PG15 Recommended?Yes, pre-granting |
|
Your read of the mechanics looks right to me, so I will not repeat it. But there is a self-service path that I think gets you the exact steady state you want without needing platform staff, and it hinges on two details that are easy to miss. 1. In PG16+ the role-membership options are independently settable, and re-issuing the grant updates them rather than erroring or duplicating (GRANT docs, Role Membership). So a membership that arrives from PG15 as the effectively- grant owner_role to postgres with admin true, inherit false, set false;That is precisely the 2. The thing you cannot manufacture after the fact is admin rights on a role you no longer administer. But you can grant them before the upgrade, while you still can: -- on PG15, in the maintenance window immediately before the upgrade
grant owner_role to postgres with admin option;On PG15 that unavoidably also carries runtime inheritance and grant owner_role to postgres with admin true, inherit false, set false;and you are back to the shape you want, self-service, with no ticket. The ordering matters: 3. On your questions 1–3, I would not trust anyone who answers confidently. Whether the hosted upgrade path normalises pre-existing custom role memberships is a property of Supabase's migration tooling, not of PostgreSQL, and it is not something you can infer from the docs or from a local One aside on the functions themselves, since the point of the owner role is to keep the definer functions from running as something over-privileged: whatever role ends up owning them, make sure each one carries |
Uh oh!
There was an error while loading. Please reload this page.
We are using Hosted Supabase and have several custom
NOLOGINroles that ownSECURITY DEFINERfunctions.On PostgreSQL 15, our migration pattern was:
NOLOGIN,NOINHERIT,NOBYPASSRLS, etc.)GRANT owner_role TO postgresREVOKE owner_role FROM postgrespostgreshas zero membership in the owner roleWe are now preparing for PostgreSQL 17.
On fresh PG17, PostgreSQL automatically gives the non-superuser role creator an administration-only membership:
ADMIN TRUEINHERIT FALSESET FALSEThat shape works for us.
The upgrade-existing case is the blocker.
Our local tests show:
postgresmembership remains zero-membership when carried into PG17postgresthen cannot grant itself that owner role because it lacksADMIN OPTIONpostgreson PG15 is not acceptable, because PG15 membership gives runtime inheritance /SET ROLEcapabilityADMIN TRUE / INHERIT TRUE / SET TRUE, which is not an acceptable steady stateADMIN TRUEINHERIT FALSESET FALSEbut project
postgrescannot perform that normalization itselfQuestions:
ADMIN TRUE / INHERIT FALSE / SET FALSEfor projectpostgres?SECURITY DEFINERfunctions owned by customNOLOGINroles after the upgrade?postgresbefore upgrade recommended or discouraged?Required steady-state properties:
NOLOGIN / NOINHERIT / NOBYPASSRLS / NOSUPERUSER / NOCREATEDB / NOCREATEROLEanon,authenticated,service_roleare not membersSET TRUEINHERIT TRUESECURITY DEFINER, function ownership,search_path, ACLs and RLS behavior remain unchangedRelated discussion:
https://github.com/orgs/supabase/discussions/48783
Support ticket already submitted:
SU-473628If there is any Hosted-specific documentation covering this transition, a link would be very helpful.
All reactions