Skip to content

Missing grants in generated migration generated with version 2.33.0 and above (db pull --linked) #4068

Description

@ex0ns

Describe the bug

When generating database migrations, Supabase CLI 2.33.0 output's is very different from previous version:

  • does not include GRANT on the newly created table
  • revoke existing privilege (this is probably wrong and dangerous !)
  • re-create all functions in our database

To Reproduce

supabase db pull -s public,private --linked

Expected behavior
As of 2.32.0, the generated migration was:

createtable "public"."sample_table" (
"id"bigint generated by default as identity not null,
"company_id"bigintnot null,
"name"textnot null,
"created_at"timestamp with time zonenot null default now()
);
altertable"public"."sample_table" enable row level security;
-- INDEX CREATIONCREATEUNIQUE INDEXsample_table_pkeyONpublic.sample_table USING btree (id);
-- CONSTRAINTSaltertable"public"."sample_table" add constraint"sample_table_pkey"PRIMARY KEY using index "sample_table_pkey";
altertable"public"."sample_table" add constraint"sample_table_company_id_fkey"FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE not valid;
altertable"public"."sample_table" validate constraint"sample_table_company_id_fkey";
-- PERMISSION GRANTS (✅ Present in 2.32.0)grantdeleteon table "public"."sample_table" to "anon";
grant insert on table "public"."sample_table" to "anon";
grantreferenceson table "public"."sample_table" to "anon";
grantselecton table "public"."sample_table" to "anon";
grant trigger on table "public"."sample_table" to "anon";
grant truncate on table "public"."sample_table" to "anon";
grantupdateon table "public"."sample_table" to "anon";
grantdeleteon table "public"."sample_table" to "authenticated";
grant insert on table "public"."sample_table" to "authenticated";
grantreferenceson table "public"."sample_table" to "authenticated";
grantselecton table "public"."sample_table" to "authenticated";
grant trigger on table "public"."sample_table" to "authenticated";
grant truncate on table "public"."sample_table" to "authenticated";
grantupdateon table "public"."sample_table" to "authenticated";
grantdeleteon table "public"."sample_table" to "service_role";
grant insert on table "public"."sample_table" to "service_role";
grantreferenceson table "public"."sample_table" to "service_role";
grantselecton table "public"."sample_table" to "service_role";
grant trigger on table "public"."sample_table" to "service_role";
grant truncate on table "public"."sample_table" to "service_role";
grantupdateon table "public"."sample_table" to "service_role";
-- RLS POLICIES
create policy "Users can access sample table"on"public"."sample_table"as permissive
for all
to authenticated
using ((( SELECT (((auth.jwt() ->'app_metadata'::text) ->>'user_role'::text) ='admin'::text)) AND (( SELECTprivate.get_company_for_user() AS get_company_for_user) = company_id)))
with check ((( SELECT (((auth.jwt() ->'app_metadata'::text) ->>'user_role'::text) ='admin'::text)) AND (( SELECTprivate.get_company_for_user() AS get_company_for_user) = company_id)));
-- TRIGGERSCREATETRIGGERhandle_updated_at BEFORE UPDATEONpublic.sample_table FOR EACH ROW EXECUTE FUNCTION moddatetime('updated_at');

Current results

-- ❌ REVOKES existing permissions (this part is unexpected)revokedeleteon table "public"."existing_table_1"from"anon";
revoke insert on table "public"."existing_table_1"from"anon";
-- ... (many more revoke statements for existing tables)revokedeleteon table "public"."existing_table_2"from"authenticated";
revoke insert on table "public"."existing_table_2"from"authenticated";
-- ... (many more revoke statements for existing tables)-- NEW TABLE CREATION (same as 2.32.0)createtable "public"."sample_table" (
"id"bigint generated by default as identity not null,
"company_id"bigintnot null,
"name"textnot null,
"created_at"timestamp with time zonenot null default now()
);
altertable"public"."sample_table" enable row level security;
CREATEUNIQUE INDEXsample_table_pkeyONpublic.sample_table USING btree (id);
altertable"public"."sample_table" add constraint"sample_table_pkey"PRIMARY KEY using index "sample_table_pkey";
altertable"public"."sample_table" add constraint"sample_table_company_id_fkey"FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE not valid;
altertable"public"."sample_table" validate constraint"sample_table_company_id_fkey";
-- ❌ MISSING: No GRANT statements for the new table-- RLS POLICIES (present)
create policy "Users can access sample table"on"public"."sample_table"as permissive
for all
to authenticated
using ((( SELECT (((auth.jwt() ->'app_metadata'::text) ->>'user_role'::text) ='admin'::text)) AND (( SELECTprivate.get_company_for_user() AS get_company_for_user) = company_id)))
with check ((( SELECT (((auth.jwt() ->'app_metadata'::text) ->>'user_role'::text) ='admin'::text)) AND (( SELECTprivate.get_company_for_user() AS get_company_for_user) = company_id)));
-- TRIGGERS (present)CREATETRIGGERhandle_updated_at BEFORE UPDATEONpublic.sample_table FOR EACH ROW EXECUTE FUNCTION moddatetime('updated_at');
-- ALL FUNCTIONS RECREATED-- Note: 2.33.0 recreates all existing functions, which seems unnecessary-- CREATE OR REPLACE FUNCTION ... (many functions recreated)

System information

  • Version of OS: OSX 15.6
  • Version of CLI: 2.33.0
  • Versions of services:
 SERVICE IMAGE | LOCAL | LINKED ------------------------|------------------------|-----------
supabase/postgres | 15.1.1.25 | 15.1.1.25 supabase/gotrue | v2.178.0 | v2.178.0 postgrest/postgrest | v12.0.2 | v12.0.2 supabase/realtime | v2.41.3 | - supabase/storage-api | v1.25.9 | - supabase/edge-runtime | v1.68.0 | - supabase/studio | 2025.07.21-sha-88dca02 | - supabase/postgres-meta | v0.91.1 | - supabase/logflare | 1.14.2 | - supabase/supavisor | 2.5.7 | - 

Additional context
I also tried with the latest version of the CLI and it's the same as with 2.33.0. I used this version to narrow down the problem but I can't find anything in v2.32.0...v2.33.0 that could explain that difference.

I also tested on 2.38.2 and it's the same

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions