BEGIN; -- profiles_update_own intentionally allows a user to edit their own profile -- row, but row-level security cannot distinguish user-editable columns from -- service-managed authorization and entitlement columns. Supabase grants table -- UPDATE to authenticated by default, so without a column ACL a user could -- promote their own role or change their tier through PostgREST. REVOKE UPDATE ON TABLE public.profiles FROM anon, authenticated; -- Keep only the public profile fields user-editable. Role changes go through -- the service-role admin RPC and tier changes go through verified billing. GRANT UPDATE (name, avatar_url, locale) ON TABLE public.profiles TO authenticated; COMMIT;