Supported way for custom NOLOGIN table owner to create FK referencing auth.users(id)? #51118
Replies: 2 comments
|
I can't give you the officially supported answer. I don't work at Supabase, and only a maintainer can say which role is allowed to touch auth on hosted. On plain Postgres the privilege check happens at DDL time. After SET ROLE edu_app_owner, running ALTER TABLE public.profiles ADD CONSTRAINT checks USAGE on schema auth and GRANT REFERENCES (id) ON auth.users once. After that the FK lives in the catalog and every insert enforces through the constraint itself. Revoking those temp grants does not drop it. The part people miss is DML. Keeping NOBYPASSRLS and avoiding broad SELECT on auth.users sounds clean until inserts into public.profiles need to look up auth.users and fail for lack of visibility. Postgres usually also needs SELECT (id) for the check and for ON DELETE and ON UPDATE handling. That column level grant is much narrower than table SELECT, something to check in your case. With the table left owned by the app owner and postgres only doing SET ROLE, the FK enforces normally for a NOBYPASSRLS role once that visibility is sorted. I still would not treat the temporary window as sanctioned until someone on their side says so. |
|
The officially supported, cleanest approach on hosted Supabase that satisfies all your security constraints without touching Architectural Reality of PostgreSQL Foreign Keys
Supported Migration ProcedureSince your migration runner connects as Option A: New Table Creation-- Run as postgres:
CREATE TABLE public.profiles (
user_id uuid PRIMARY KEY REFERENCES auth.users(id) ON DELETE CASCADE,
display_name text,
created_at timestamptz DEFAULT now() NOT NULL
);
-- Transfer table ownership to your custom role:
ALTER TABLE public.profiles OWNER TO edu_app_owner;
-- Enable RLS and configure policies as needed:
ALTER TABLE public.profiles ENABLE ROW LEVEL SECURITY;Option B: Existing Table Already Owned by
|
Uh oh!
There was an error while loading. Please reload this page.
We are using hosted Supabase with PostgreSQL 17 and want to follow the documented pattern of having a public profile table reference
auth.users(id).However, our setup has an additional ownership/security requirement:
public.profilesmust be created and owned by our custom roleedu_app_owner.edu_app_ownerisNOLOGINandNOBYPASSRLS.postgres, which canSET ROLE edu_app_owner.public.profiles(user_id) REFERENCES auth.users(id)The issue is that
postgrescurrently has the relevant access to the managed Auth objects, whileedu_app_ownerdoes not. AfterSET ROLE edu_app_owner, those privileges are not additive.We do not want to:
SELECTonauth.users;service_roleas a DDL workaround;supabase_adminorsupabase_auth_admin;BYPASSRLS;postgresthe permanent owner of our application tables;What is the officially supported approach on hosted Supabase for this case?
Would either of these approaches be supported?
USAGE ON SCHEMA auth TO edu_app_ownerand
REFERENCES(id) ON TABLE auth.users TO edu_app_ownerwith no grant option, followed by revocation after the validated FK has been created.
OR
public.profilestable, while leaving table ownership unchanged and granting no permanent Auth access toedu_app_owner.If option 1 is supported, which managed role/action is the supported grantor on hosted Supabase, and will the FK remain valid and enforced after the temporary
USAGE/REFERENCESprivileges are revoked?We are specifically looking for a supported hosted-Supabase procedure rather than a PostgreSQL workaround that might conflict with managed Auth ownership or future platform upgrades.
Thank you.
All reactions