Liigu sisu juurde

Supabase 30. oktoobri grantide muudatus: mis läheb katki

Vaata MarkdowninaAva rakenduses ClaudeAva rakenduses ChatGPTAva rakenduses Perplexity

Küsimus kopeeritakse ka. Kui vestlus avaneb tühjana, kleepige see sisse.

Lühidalt

  1. oktoobril 2026 lõpetab Supabase kõigis olemasolevates projektides public-skeemi uutele tabelitele automaatsete grantide andmise rollidele anon, authenticated ja service_role. Tabelid, mis teil juba on, jäävad tööle. Iga pärast seda loodud tabel vastab supabase-js-ile ja teie secret key’le 42501 permission denied, kuni migratsioon annab sellele granti. Reprodutseerisin ümberlülituse kohalikult: uued tabelid, uued vaated ja vanad tabelid, mille migratsioon kustutab ja uuesti loob, kukuvad läbi; olemasolevad tabelid, RPC-funktsioonid ja serial-insertid töötavad edasi. Kontrollige kahe SQL-päringu ja ühe grep’iga allpool ning parandage grant’i, RLS-i ja policy’ga samas migratsioonis, mitte kunagi käsuga grant all on all tables.

Pean tasuta Supabase security checkerit, mis loeb iga avatud tabeli grante, ja tahtsin täpselt näha, mida see muudatus teeb, enne kui inimesed selle otsa komistavad. Panin püsti kohaliku Supabase’i pinu, andsin sellele vanad vaikeseaded, rakendasin ümberlülituse nii, nagu Supabase seda kirjeldab, ja saatsin päringu igale objektitüübile, mis pähe tuli. See postitus on see, mis vastuseks tuli, ja kuidas oma projekti enne 30. kuupäeva kontrollida.

Mis muutub 30. oktoobril 2026?

Seni sai iga public-skeemis loodud tabel Postgresi default privileges kaudu rollidele anon, authenticated ja service_role õigused select, insert, update ja delete. Seepärast oli uus tabel brauserist kättesaadav kohe, kui see tekkis, olenemata sellest, kas RLS oli sees või mitte. Supabase’i breaking change’i teade eemaldab need vaikeseaded kolmes etapis:

Kuupäev Mis juhtub
28. aprill 2026 Uued projektid saavad loomisel valiku “Automatically expose new tables” välja lülitada
30. mai 2026 Uus käitumine muutub uute projektide vaikeseadeks, mitme nädala jooksul järk-järgult
30. oktoober 2026 Uus käitumine rakendatakse kõigile olemasolevatele projektidele

Teie projektis on ümberlülitus kaks lauset, samad, mida Supabase annab varasemaks üleminekuks:

alter default privileges for role postgres in schema public
  revoke select, insert, update, delete on tables from anon, authenticated, service_role;

alter default privileges for role postgres in schema public
  revoke usage, select on sequences from anon, authenticated, service_role;

Default privileges kehtivad ainult hiljem loodud objektidele. Olemasolevaid grante ei puudutata, mistõttu teie praegused tabelid jäävad tööle. Mida teate järgi ei mõjuta: teised skeemid (auth, storage, realtime, teie enda), rakendused, mis räägivad Postgresiga otseühenduse kaudu (psql, ORM, server connection string’iga), ja RLS ise. Muudatus puudutab Data API-t: REST-i, GraphQL-i ja kõiki selle peal olevaid klienditeeke.

Mis läheb katki ja mis jääb tööle?

Minu seadistus: Supabase CLI 2.109.1, Postgres 17.6, PostgREST 14.14, 26. oktoobril 2026. Panin config.toml-i auto_expose_new_tables = true, et saada vanad vaikeseaded, lõin ühe tabeli kahe reaga, RLS-iga ja lugemispolicy’ga ning jooksutasin ülaltoodud kaks lauset. Seejärel lõin uusi objekte ja kutsusin igaüht kohaliku avaliku (anon) võtmega ja secret (service_role) võtmega, üks päring kummagi kohta.

Mis lakkab vastamast pärast 30. oktoobri ümberlülitust. Kohalik Supabase, objektid loodud pärast changelogi revoke'i, avalik võti, kui pole märgitud teisiti. Uus tabel RLS-i ja policy'ga: create table → policy, grant puudub → 42501, HTTP 401; Sama tabel secret key'ga: create table → policy, grant puudub → 42501, HTTP 403; Uus vaade tabeli peal, mis veel töötab: create view → 42501, HTTP 401, hinti pole; Vana tabel, mille migratsioon kustutas ja lõi uuesti: drop + create table → grandid kadunud → 42501, HTTP 401.
Minu reprodutseerimine kohalikul Supabase'i pinul (CLI 2.109.1, Postgres 17.6, PostgREST 14.14), 26. oktoober 2026.
Mis jääb tööle pärast 30. oktoobri ümberlülitust. Sama kohalik pinu, sama revoke, avalik võti. Enne ümberlülitust loodud tabel: olemasolev tabel → grandid alles → 2 rida, HTTP 200; Uus funktsioon, kutsutud RPC kaudu: create function → execute PUBLIC kaudu → HTTP 200; Uus serial-tabel, antud ainult select ja insert: id serial → sekventsil jäi UPDATE → insert, HTTP 201.
Minu reprodutseerimine kohalikul Supabase'i pinul (CLI 2.109.1, Postgres 17.6, PostgREST 14.14), 26. oktoober 2026.
Objekt, loodud pärast ümberlülitust, kui pole teisiti märgitud Võti Tulemus
Enne ümberlülitust loodud tabel avalik HTTP 200, 2 rida
Uus tabel RLS-i ja policy’ga to anon, authenticated avalik HTTP 401, 42501, hint GRANT SELECT ON public.new_orders TO anon;
Sama uus tabel secret HTTP 403, 42501, hint … TO service_role;
Uus vaade (security_invoker) vana tabeli peal avalik HTTP 401, 42501, permission denied for view, hint null
Koopia, tehtud käsuga create table … (like old_orders including all) avalik HTTP 401, 42501
Vana tabel pärast drop table ja uuesti create table avalik HTTP 401, 42501
Uus funktsioon public.ping() aadressil /rest/v1/rpc avalik HTTP 200
Uus tabel id serial-iga, anon-ile antud ainult select, insert avalik insert HTTP 201

Selles tabelis on viis asja, mida enne ümberlülitust tasub teada.

“Olemasolevad tabelid säilitavad oma grandid” kehtib ainult seni, kuni tabel eksisteerib. Migratsioon, mis tabeli kustutab ja uuesti loob, create table … (like …) koopia või taastamine dumpist teeb uue tabeli ning uus tabel ei saa midagi. Policy tuli tagasi minu create policy abil, grandid mitte. Kõik, mis teie pipeline’is tabeleid ümber ehitab selle asemel, et neid muuta, läheb katki esimesel käivitusel pärast ümberlülitust.

Secret key läheb samuti katki. service_role jätab RLS-i vahele, kuid vajab siiski granti. Seega Edge Function, cron-töö või webhook’i käsitleja, mis kirjutab uude tabelisse, kukub läbi 403-ga, mitte ainult brauser. Hint nimetab service_role’i, selle järgi need eristabki.

Vaated ei anna hinti. Tabelite puhul tagastab PostgREST täpse vajaliku GRANT-i. Minu uue vaate hint oli null ja teade ütles permission denied for view v_old_orders. AI-tööriistal, mis parandab 42501 hinti põhjal, pole siin midagi kopeerida; grant on grant select on public.v_old_orders to authenticated; ja vaade peab säilitama security_invoker = true, et tabeli RLS jätkuks kehtida.

Funktsioonid ei kuulu sellesse muudatusse. Need kaks lauset puudutavad tabeleid ja sekventse. Minu uus funktsioon jäi kutsutavaks rollidele anon, authenticated ja service_role, sest Postgres annab igale uuele funktsioonile execute rollile PUBLIC ja skeemitaseme revoke ei suuda seda eemaldada, nagu Supabase’i API turvajuhend selgitab. RPC-kutsed töötavad pärast 30. oktoobrit edasi; see tähendab ka, et uus security definer funktsioon on teie avaliku võtmega kutsutav hetkest, kui see tekib.

serial-insertid töötasid ilma sekventsi grandita edasi. Paljud nõuanded ütlevad, et serial id vajab pärast ümberlülitust grant usage on sequence … to authenticated. Minu katsel läks insert ilma selleta läbi: revoke võtab uutelt sekventsidelt usage ja select, kuid update jääb ning update piisab nextval-ile. Kui tühistate sekventside kõik default privileges, nagu API turvajuhendi täielik revoke teeb, on usage grant vajalik. Identity-veerg (generated by default as identity) ei vaja kummalgi juhul midagi.

Veel üks asi, mille revoke maha jätab: uus tabel tuli ikka kaasa TRUNCATE, REFERENCES ja TRIGGER kõigile kolmele rollile ning Postgres 17-s sisaldavad vaikeseaded ka MAINTAIN. Ükski RLS-poliitika ei kehti TRUNCATE-ile. Kirjutasin sellest 42501 märkmes.

Kus te sellega enne 30. oktoobrit kokku puutute

Teie hostitud projektis toimub ümberlülitus 30. kuupäeval, aga kolm kohta käituvad juba nagu pärast seda.

supabase db reset värske CLI-ga. CLI v2.102.0 lisas config.toml-i võtme [api] auto_expose_new_tables. Versioonil 2.109.1 oli minu värskel pinul ilma selle võtmeta juba uued vaikeseaded: tabelid said ainult MAINTAIN, REFERENCES, TRIGGER ja TRUNCATE, sekventsid ainult UPDATE. Väärtus true toob vanad grandid tagasi ja prindib api.auto_expose_new_tables is deprecated and will be removed on 2026-10-30. Kui teie kohalikud tabelid töötavad pärast reset’i endiselt, vaadake kõigepealt seda võtit. See on ka odavaim koht testimiseks: eemaldage see, tehke reset ja käivitage oma rakendus.

Preview branch’id ja projektid, mis on loodud alates 30. maist. Need mängivad teie migratsioonid läbi uute vaikeseadetega. Iga tabel, mille migratsioonis pole grant-i, on seal juba kättesaamatu. GitHubi arutelus kirjeldavad just seda inimesed, kellel on klienti kohta üks projekt: töötavad projektid on korras, iga uus deploy samadest migratsioonidest on katki.

Baseline-migratsioon, mis toob vana vaikeseade tagasi. Sama arutelu kommenteerija märgib, et esimene migratsioon, mis on tehtud käsuga supabase db pull, võib sisaldada alter default privileges … grant all on tables to anon, authenticated, service_role. Jooksutasin selle lause pärast ümberlülitust: järgmine loodud tabel oli taas kättesaadav, HTTP 200. Kohalikult peidab see probleemi. Hostitud projektile rakendatuna võtab see muudatuse vaikselt tagasi ja iga tulevane tabel on jälle avaliku võtme jaoks lahti, olenemata sellest, kas sellel on RLS või mitte. Otsige oma migratsioonidest alter default privileges ja lugege iga leid läbi.

Kuidas oma projekti enne 30. oktoobrit kontrollida

Neli kontrolli, kiiremast põhjalikumani. Esimesed kaks jooksevad hostitud projekti SQL Editoris.

1. Kas teie projekt on juba ümber lülitunud?

See on päring Supabase’i API turvajuhendist. See loetleb, mida saavad uued objektid, mille postgres loob skeemis public:

select
  case d.defaclobjtype
    when 'r' then 'tables'
    when 'S' then 'sequences'
    when 'f' then 'functions'
  end as object_type,
  a.grantee::regrole as role,
  string_agg(a.privilege_type, ', ' order by a.privilege_type) as privileges
from pg_default_acl d
cross join lateral aclexplode(d.defaclacl) a
where d.defaclrole = 'postgres'::regrole
  and d.defaclnamespace = 'public'::regnamespace
  and a.grantee in ('anon'::regrole, 'authenticated'::regrole, 'service_role'::regrole)
group by 1, 2
order by 1, 2;

Kui tables-read sisaldavad SELECT, INSERT, UPDATE, DELETE, on projekt endiselt vanal vaikeseadel ja lülitub 30. kuupäeval ümber. Kui need näitavad ainult MAINTAIN, REFERENCES, TRIGGER, TRUNCATE (või ridu pole), on uued tabelid juba suletud. Seda näeb ka Dashboardis Data API seadetes, “Automatically expose new tables”.

2. Millistel tabelitel on policy, aga pole granti?

Policy rollile, kellel selle käsu jaoks granti pole, ei jookse kunagi: päring kukub läbi enne RLS-i. See päring loetleb sellised paarid. Minu laboris leidis see uue tabeli ja uuesti loodud vana tabeli, mitte midagi muud:

select p.schemaname || '.' || p.tablename as "table", r.role, p.cmd
from pg_policies p
cross join lateral unnest(case when 'public' = any(p.roles) then array['anon', 'authenticated']::name[] else p.roles end) as r(role)
join pg_class c on c.relname = p.tablename
join pg_namespace n on n.oid = c.relnamespace and n.nspname = p.schemaname
where p.schemaname = 'public'
  and r.role in ('anon', 'authenticated')
  and not has_table_privilege(r.role::text, c.oid,
        case p.cmd when 'ALL' then 'SELECT' else p.cmd end)
order by 1, 2, 3;

Jooksutage seda pärast iga migratsiooni, CI-s värske db reset-i vastu või stagingus. Terve projekti puhul ei tagasta see midagi; pärast 30. kuupäeva on iga rida tabel, millele teie rakendus ligi ei pääse. See kontrollib tabelitaseme granti, seega tabel, mis on avatud ainult veerugrantidega (grant select (id, name) on …), ilmub siia, kuigi need veerud on loetavad.

3. Millised migratsioonid loovad tabeli ilma grantita?

Andmebaas näitab ainult olemasolevaid tabeleid. Migratsioon, mida te pole veel rakendanud, on nähtav ainult teie repos. See jäme grep loetleb iga create table kaustas supabase/migrations, millel pole sama nime jaoks grant … on:

for t in $(grep -hioE 'create table( if not exists)? +[a-z0-9_."]+' supabase/migrations/*.sql | awk '{print $NF}' | sort -u); do
  grep -qiF "on $t " supabase/migrations/*.sql || grep -qiF "on table $t " supabase/migrations/*.sql || echo "no grant: $t"
done

See on tekstivõrdlus, mitte SQL-i parsimine: grant, mis loetleb ühes lauses mitu tabelit, või tabel, mida ühes kohas nimetatakse skeemita ja teises skeemiga, annab valepositiivse. Lugege iga prinditud rida läbi. Tabelid, millele pääseb ligi ainult serverikood otseühenduse kaudu, ei vaja granti üldse.

4. Mängige kõik läbi uute vaikeseadetega

Eemaldage config.toml-ist auto_expose_new_tables, jooksutage supabase db reset ja käivitage oma rakendus või selle testid selle vastu. See on teie projekt pärast 30. kuupäeva pluss iga tabeli värske koopia, mis on raskem juhtum. Supabase loetleb mõjutatud tabelid ka Security Advisoris ja märgib Data API avatuse Table Editoris.

Kuidas parandada, avamata iga tabelit

Kirjutage grant, RLS ja policy’d samasse migratsiooni, mis tabeli loob, ning andke igale rollile ainult see, mida rakendus kasutab:

create table public.invoices (
  id bigint generated by default as identity primary key,
  user_id uuid not null default auth.uid(),
  total numeric not null
);

revoke all on table public.invoices from anon, authenticated, service_role;
grant select, insert on table public.invoices to authenticated;
grant select, insert, update, delete on table public.invoices to service_role;

alter table public.invoices enable row level security;

create policy "Owners read their invoices"
on public.invoices for select
to authenticated
using ((select auth.uid()) = user_id);

create policy "Owners add their invoices"
on public.invoices for insert
to authenticated
with check ((select auth.uid()) = user_id);

Jooksutasin selle ploki samal kohalikul pinul: sisselogitud testkasutaja lisas rea ja luges selle tagasi (HTTP 201, siis 200), sessioonita avalik võti sai 42501 ning ülaltoodud kontroll 2 ei loetlenud tabelit enam. Esimene revoke all puhastab TRUNCATE, TRIGGER ja REFERENCES, mis uue tabeliga kaasas käivad, ja annab sama tulemuse projektil, mis pole veel ümber lülitunud. Andke anon-ile õigused ainult andmetele, mis on mõeldud sisselogimata külastajatele, ja service_role-ile ainult siis, kui serverikood kasutab sellel tabelil secret key’d. Kuidas grandid ja policy’d kogu rakenduses kokku sobivad, on minu Lovable’i rakenduse turvakontrollnimekirjas.

Mida mitte teha, kui esimene 42501 saabub:

  • Ärge jooksutage grant all on all tables in schema public to anon, authenticated. See toob vana vaikeseade tagasi kõigile tabelitele korraga, sealhulgas igale tabelile, kus RLS-i pole kunagi sisse lülitatud, ja need muutuvad loetavaks igaühele, kellel on teie avalik võti. 42501 märge näitab, miks grant on esimene lukk ja RLS teine.
  • Ärge lisage uuesti alter default privileges … grant. See on kogu muudatuse tagasipööramine.
  • Ärge lülitage RLS-i “testimiseks” välja ja ärge pange secret key’d frontendi. Secret key jätab RLS-i vahele igaühe jaoks, kes teie bundle’i avab; võtmete erinevus on artiklis anon key vs service role key.

Kui teie migratsioone kirjutab AI-tööriist, lisage selle juhistesse üks rida: “every new table in public gets explicit grants per role, enable row level security and policies in the same migration; never grant on all tables in schema public”. Vea hint õpetab talle granti, kuid mitte RLS-i, mis sellega kokku kuulub.

Küsimused, mida inimesed muudatuse kohta esitavad

Kas mu olemasolevad tabelid lõpetavad 30. oktoobril töö? Ei. Default privileges kehtivad hiljem loodud objektidele ja minu katsel vastas vana tabel pärast ümberlülitust HTTP 200. Erand on tabel, mille teie migratsioonid kustutavad ja uuesti loovad.

Kas pean midagi tegema, kui ma kunagi tabeleid ei loo? Mitte 30. kuupäeval. Kontrollige järgmisel korral, kui teie, kolleeg või AI-tööriist ühe lisab, ja kontrollige iga pipeline’i, mis loob teie migratsioonidest projekte või branch’e.

Kas see mõjutab Edge Function’eid? Jah, kui need kasutavad supabase-js-i secret key’ga uuel tabelil: service_role vajab samuti granti. Funktsioone, mis ühendavad otse Postgresiga, see ei mõjuta.

Kas see mõjutab RPC-funktsioone, Storage’it või Auth’i? Selles muudatuses mitte. Uued funktsioonid jäävad kutsutavaks PUBLIC kaudu ning storage ja auth ei ole skeem public.

Kas ma saan varem ümber lülituda? Jah. Alguse kaks lauset ongi ümberlülitus; jooksutage need kõigepealt stagingus, siis tootmises. Olemasolevad tabelid säilitavad oma grandid, nii et töötav rakendus ei märka midagi, ja järgmine uus tabel ütleb kohe, kas teie migratsioonid on valmis.

Kuidas checker seda näeb

Checker ühendub kirjutuskaitstult ja loeb iga tabeli grante teie avatud skeemides: millistesse tabelitesse saab avalik võti ilma policy’ta kirjutada, millistel tabelitel on RLS väljas ja millised default privileges annavad iga uue tabeli kaasa TRUNCATE, REFERENCES või TRIGGER. Samuti loetleb see iga policy, mille rollil pole selle käsu jaoks granti, ehk tabelid, mille leiab kontroll 2, välja arvatud need, kus RLS on väljas või kus on veergude grandid. See ei näe migratsioonifaile, mida te pole rakendanud, seega jääb ülaltoodud kontroll 3 teie jooksutada. Kui RLS on osa, milles te pole kindel, käib kuidas Supabase RLS-i testida selle läbi ja avatud skeemide märge käsitleb muid skeeme peale public, mida see muudatus ei puuduta.

© 2026 Denys Zaichenko. Algne artikkel: https://madsalt.tech/et/blog/supabase-october-30-grant-change/