Files
av-planner/supabase/migrations/20260927000000_grant_table_privileges.sql
aarbitandClaude Sonnet 5 00777077c2 Grant table privileges to anon/authenticated/service_role
RLS policies alone don't grant table-level access in Postgres — missing
GRANTs caused "permission denied for table profiles" in production even
though the RLS policies were correct.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017DUU6CnxECCDeqDNYJgr5x
2026-09-28 09:42:36 -05:00

32 lines
1.8 KiB
SQL

-- Fixes a production-only bug: every table in this schema was created with
-- RLS policies but no Postgres-level GRANTs, which local self-hosted
-- Supabase's Docker bootstrap happens to pre-grant broadly on the `public`
-- schema — masking the gap in every local dev/test session so far — but a
-- fresh Supabase Cloud project does not. Confirmed against Supabase's own
-- docs (supabase.com/docs/guides/auth/managing-user-data): RLS policies
-- only ever narrow access an underlying GRANT already allows; with no
-- GRANT, every request from the `anon`/`authenticated` roles fails at the
-- Postgres level before RLS is even evaluated ("permission denied for
-- table ..."), regardless of how permissive the policy is. First surfaced
-- as CompleteProfileScreen's username-save failing after Google sign-in on
-- app.diagrav.com.
--
-- `authenticated`/`service_role` get full CRUD per table — RLS (already
-- written and unchanged by this migration) is what actually narrows each
-- operation to the right rows. `anon` gets SELECT only, matching Supabase's
-- own least-privilege example; nothing in this app reads `public` schema
-- tables before sign-in today, but it's a harmless, RLS-gated default to
-- have in place rather than an under-grant that surfaces as another opaque
-- "permission denied" later.
--
-- The `alter default privileges` statements make this automatic for tables
-- any future migration creates, so this class of bug can't recur.
grant usage on schema public to anon, authenticated, service_role;
grant select on all tables in schema public to anon;
grant select, insert, update, delete on all tables in schema public to authenticated, service_role;
alter default privileges in schema public grant select on tables to anon;
alter default privileges in schema public grant select, insert, update, delete on tables to authenticated, service_role;