Pereiti prie turinio

Supabase spalio 30 d. pokytis: kas sulūš ir kaip patikrinti

Žiūrėti kaip MarkdownAtidaryti per ClaudeAtidaryti per ChatGPTAtidaryti per Perplexity

Klausimas taip pat nukopijuojamas. Jei pokalbis atsidaro tuščias, įklijuokite jį.

Trumpai

2026 m. spalio 30 d. Supabase kiekviename esamame projekte nustoja automatiškai suteikti rolėms anon, authenticated ir service_role teises naujoms public lentelėms. Jau esančios lentelės veikia toliau. Kiekviena vėliau sukurta lentelė supabase-js ir jūsų secret key atsako 42501 permission denied, kol migracija nesuteikia teisių. Perjungimą atkartojau vietoje: naujos lentelės, naujos view ir senos lentelės, kurias migracija ištrina ir sukuria iš naujo, neveikia; esamos lentelės, RPC funkcijos ir serial įrašymai veikia. Žemiau pateikti du SQL užklausimai ir vienas grep patikrinimui, o taisoma teise, RLS ir politika toje pačioje migracijoje, niekada ne grant all on all tables.

Turiu nemokamą Supabase saugos tikrintuvą, kuris skaito teises kiekvienoje atskleistoje lentelėje, todėl norėjau tiksliai pamatyti, ką šis pokytis daro, kol žmonės dar nepradėjo su juo susidurti. Pasiėmiau vietinį Supabase stack, daviau jam senus numatytuosius nustatymus, pritaikiau perjungimą taip, kaip jį aprašo Supabase, ir išsiunčiau užklausą į kiekvieną objekto tipą, kurį sugalvojau. Šis įrašas apie tai, ką gavau, ir kaip patikrinti savo projektą iki 30-osios.

Kas keičiasi 2026 m. spalio 30 d.?

Iki šiol kiekviena public schemoje sukurta lentelė per Postgres numatytąsias teises (default privileges) gaudavo select, insert, update ir delete rolėms anon, authenticated ir service_role. Todėl nauja lentelė iš naršyklės būdavo pasiekiama vos sukūrus, su RLS ar be jo. Supabase pranešimas apie lūžtantį pokytį šiuos numatytuosius nustatymus pašalina trimis etapais:

Data Kas vyksta
2026 m. balandžio 28 d. Nauji projektai kūrimo metu gali atsisakyti „Automatically expose new tables“
2026 m. gegužės 30 d. Naujas elgesys tampa numatytuoju naujiems projektams, diegiamas kelias savaites
2026 m. spalio 30 d. Naujas elgesys taikomas visiems esamiems projektams

Jūsų projekte perjungimas yra dvi komandos, tos pačios, kurias Supabase pateikia tiems, kas nori pereiti anksčiau:

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;

Numatytosios teisės galioja tik vėliau sukurtiems objektams. Jau suteiktos teisės nekeičiamos, todėl dabartinės lentelės veikia toliau. Pagal pranešimą pokytis neliečia: kitų schemų (auth, storage, realtime, jūsų pačių), programų, kurios su Postgres jungiasi tiesiogiai (psql, ORM, serveris su connection string), ir paties RLS. Pokytis susijęs su Data API: REST, GraphQL ir visomis jų pagrindu veikiančiomis klientų bibliotekomis.

Kas sulūš ir kas veikia toliau?

Mano aplinka: Supabase CLI 2.109.1, Postgres 17.6, PostgREST 14.14, 2026 m. spalio 26 d. config.toml įjungiau auto_expose_new_tables = true, kad gaučiau senus numatytuosius nustatymus, sukūriau vieną lentelę su dviem eilutėmis, įjungtu RLS ir skaitymo politika, tada paleidau aukščiau pateiktas dvi komandas. Po to sukūriau naujų objektų ir kiekvieną iškviečiau vietiniu viešuoju (anon) raktu ir secret (service_role) raktu, po vieną užklausą.

Kas nustoja atsakyti po spalio 30 d. perjungimo. Vietinis Supabase, objektai sukurti po changelog revoke, viešasis raktas, jei nenurodyta kitaip. Nauja lentelė su RLS ir politika: create table → politika, be grant → 42501, HTTP 401; Ta pati lentelė su secret key: create table → politika, be grant → 42501, HTTP 403; Nauja view virš veikiančios lentelės: create view → 42501, HTTP 401, be užuominos; Sena lentelė, migracijos ištrinta ir sukurta iš naujo: drop + create table → teisės dingo → 42501, HTTP 401.
Mano atkartojimas vietiniame Supabase stack (CLI 2.109.1, Postgres 17.6, PostgREST 14.14), 2026 m. spalio 26 d.
Kas veikia toliau po spalio 30 d. perjungimo. Tas pats vietinis stack, tas pats revoke, viešasis raktas. Lentelė, sukurta prieš perjungimą: esama lentelė → teisės išliko → 2 eilutės, HTTP 200; Nauja funkcija, kviečiama per RPC: create function → execute per PUBLIC → HTTP 200; Nauja serial lentelė, suteikta tik select ir insert: id serial → sekos UPDATE liko → insert, HTTP 201.
Mano atkartojimas vietiniame Supabase stack (CLI 2.109.1, Postgres 17.6, PostgREST 14.14), 2026 m. spalio 26 d.
Objektas, sukurtas po perjungimo, jei nenurodyta kitaip Raktas Rezultatas
Lentelė, sukurta prieš perjungimą public HTTP 200, 2 eilutės
Nauja lentelė su RLS ir to anon, authenticated politika public HTTP 401, 42501, užuomina GRANT SELECT ON public.new_orders TO anon;
Ta pati nauja lentelė secret HTTP 403, 42501, užuomina … TO service_role;
Nauja view (security_invoker) virš senos lentelės public HTTP 401, 42501, permission denied for view, užuomina null
Kopija, padaryta per create table … (like old_orders including all) public HTTP 401, 42501
Sena lentelė po drop table ir pakartotinio create table public HTTP 401, 42501
Nauja funkcija public.ping() per /rest/v1/rpc public HTTP 200
Nauja lentelė su id serial, rolei anon suteikta tik select, insert public insert HTTP 201

Penkis dalykus iš šios lentelės verta žinoti prieš perjungimą.

„Esamos lentelės išsaugo savo teises“ galioja tik tol, kol lentelė egzistuoja. Migracija, kuri ištrina ir sukuria lentelę iš naujo, create table … (like …) kopija arba atkūrimas iš dump sukuria naują lentelę, o nauja lentelė negauna nieko. Politika grįžo su mano create policy, teisės negrįžo. Viskas, kas jūsų pipeline kuria lenteles iš naujo, užuot jas keitę, sulūš pirmą kartą paleidus po perjungimo.

Secret key irgi sulūžta. service_role apeina RLS, bet teisės vis tiek reikia. Taigi Edge Function, cron užduotis ar webhook tvarkyklė, rašanti į naują lentelę, gauna 403, ne tik naršyklė. Užuomina nurodo service_role, pagal tai ir atskirsite.

View užuominos neduoda. Lentelėms PostgREST grąžina tikslią reikalingą GRANT komandą. Mano naujai view užuomina buvo null, o žinutė skambėjo permission denied for view v_old_orders. DI įrankis, taisantis 42501 pagal užuominą, čia neturi ką nukopijuoti; teisė yra grant select on public.v_old_orders to authenticated;, o view turi likti su security_invoker = true, kad lentelės RLS ir toliau galiotų.

Funkcijos į šį pokytį nepatenka. Dvi komandos liečia lenteles ir sekas. Mano nauja funkcija liko pasiekiama anon, authenticated ir service_role, nes Postgres suteikia execute kiekvienai naujai funkcijai rolei PUBLIC, o schemos lygio revoke jo nepašalina, kaip paaiškina Supabase API saugos vadovas. RPC iškvietimai po spalio 30 d. veikia toliau; tai taip pat reiškia, kad nauja security definer funkcija jūsų viešuoju raktu pasiekiama vos sukūrus.

serial įrašymai veikė be sekos teisės. Daug patarimų sako, kad serial id po perjungimo reikia grant usage on sequence … to authenticated. Mano bandyme įrašymas pavyko ir be jo: revoke atima usage ir select naujoms sekoms, bet update lieka, o nextval užtenka update. Jei atšaukiate visas numatytąsias teises sekoms, kaip daro pilnas revoke API saugos vadove, usage teisė jau reikalinga. Identity stulpeliui (generated by default as identity) nieko nereikia bet kuriuo atveju.

Dar vienas dalykas, kurį revoke palieka: nauja lentelė vis tiek gavo TRUNCATE, REFERENCES ir TRIGGER visoms trims rolėms, o Postgres 17 numatytosios teisės taip pat apima MAINTAIN. Joks RLS politikos filtras netaikomas TRUNCATE. Apie tai rašiau 42501 pastaboje.

Kur su tuo susiduriate prieš spalio 30 d.

Perjungimas jūsų hostinamame projekte įvyks 30-ąją, bet trys vietos jau elgiasi taip, lyg tai jau būtų įvykę.

supabase db reset naujame CLI. CLI v2.102.0 į config.toml pridėjo [api] auto_expose_new_tables. Versijoje 2.109.1, kai rakto nėra, mano švarus stack jau turėjo naujus numatytuosius nustatymus: lentelės gaudavo tik MAINTAIN, REFERENCES, TRIGGER ir TRUNCATE, sekos tik UPDATE. Nustačius true, senos teisės grįžta ir išspausdinama api.auto_expose_new_tables is deprecated and will be removed on 2026-10-30. Taigi jei jūsų vietinės lentelės po reset vis dar veikia, pirmiausia patikrinkite tą raktą. Tai taip pat pigiausia vieta išbandyti: pašalinkite jį, paleiskite reset, paleiskite programą.

Preview šakos ir projektai, sukurti nuo gegužės 30 d. Jie paleidžia jūsų migracijas su naujais numatytaisiais nustatymais. Kiekviena lentelė, kurios migracijoje nėra grant, ten jau nepasiekiama. GitHub diskusijoje žmonės, turintys po projektą kiekvienam klientui, praneša būtent apie tai: veikiantys projektai tvarkoje, o kiekvienas naujas diegimas iš tų pačių migracijų sugadintas.

Bazinė migracija, kuri grąžina seną numatytąjį nustatymą. Komentatorius toje pačioje diskusijoje pastebi, kad pirmoje migracijoje, sukurtoje per supabase db pull, gali būti alter default privileges … grant all on tables to anon, authenticated, service_role. Šią komandą paleidau po perjungimo: kita sukurta lentelė vėl buvo pasiekiama, HTTP 200. Vietoje tai paslepia problemą. Pritaikius hostinamame projekte, pokytis tyliai atšaukiamas ir kiekviena būsima lentelė vėl atvira viešajam raktui, su RLS ar be jo. Paieškokite savo migracijose alter default privileges ir perskaitykite kiekvieną rezultatą.

Kaip patikrinti projektą iki spalio 30 d.

Keturi patikrinimai, nuo greičiausio iki kruopščiausio. Pirmi du vykdomi hostinamo projekto SQL Editor.

1. Ar jūsų projektas jau perjungtas?

Tai užklausa iš Supabase API saugos vadovo. Ji parodo, ką gaus nauji objektai, kuriuos public schemoje sukuria postgres:

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;

Jei tables eilutėse yra SELECT, INSERT, UPDATE, DELETE, projektas dar su senu numatytuoju nustatymu ir persijungs 30-ąją. Jei rodoma tik MAINTAIN, REFERENCES, TRIGGER, TRUNCATE (arba eilučių nėra), naujos lentelės jau uždarytos. Tai matyti ir Dashboard, Data API nustatymuose, „Automatically expose new tables“.

2. Kurios lentelės turi politiką, bet neturi teisės?

Politika rolei, neturinčiai teisės tai komandai, niekada neįvykdoma: užklausa nutrūksta prieš RLS. Ši užklausa išvardija tokias poras. Mano laboratorijoje ji rado naują lentelę ir iš naujo sukurtą seną, daugiau nieko:

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;

Vykdykite po kiekvienos migracijos, CI su švaria db reset arba staging aplinkoje. Sveikame projekte ji nieko negrąžina; po 30-osios bet kuri eilutė yra lentelė, kurios jūsų programa nepasiekia. Ji tikrina lentelės lygio teises, todėl lentelė, atverta tik stulpelių teisėmis (grant select (id, name) on …), čia atsiras, nors tie stulpeliai skaitomi.

3. Kurios migracijos sukuria lentelę be teisės?

Duomenų bazė rodo tik esamas lenteles. Dar nepritaikyta migracija matoma tik jūsų repozitorijoje. Šis apytikris grep išvardija kiekvieną create table aplanke supabase/migrations be grant … on tam pačiam pavadinimui:

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

Tai teksto atitikimas, o ne SQL analizė: teisė, išvardijanti kelias lenteles vienoje komandoje, arba lentelė, kuri vienoje vietoje pavadinta be schemos, o kitoje su ja, duos klaidingą rezultatą. Perskaitykite kiekvieną išspausdintą eilutę. Lentelėms, kurias pasiekia tik serverio kodas tiesioginiu ryšiu, teisių nereikia visai.

4. Paleiskite viską iš naujo su naujais numatytaisiais nustatymais

Pašalinkite auto_expose_new_tables iš config.toml, paleiskite supabase db reset ir paleiskite programą ar jos testus. Tai jūsų projektas po 30-osios, plius švari kiekvienos lentelės kopija, o tai sunkesnis atvejis. Supabase taip pat išvardija paveiktas lenteles Security Advisor ir pažymi Data API atvėrimą Table Editor.

Kaip ištaisyti neatveriant kiekvienos lentelės

Teisę, RLS ir politikas rašykite toje migracijoje, kuri sukuria lentelę, ir kiekvienai rolei duokite tik tai, ką naudoja programa:

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);

Šį bloką paleidau tame pačiame vietiniame stack: prisijungęs testinis vartotojas įrašė eilutę ir ją perskaitė (HTTP 201, paskui 200), viešasis raktas be sesijos gavo 42501, o 2 patikrinimas aukščiau lentelės nebeišvardijo. Pirmas revoke all išvalo TRUNCATE, TRIGGER ir REFERENCES, kurie ateina su nauja lentele, ir duoda tą patį rezultatą projekte, kuris dar neperjungtas. anon teisę duokite tik duomenims, skirtiems neprisijungusiems lankytojams, o service_role tik jei serverio kodas šiai lentelei naudoja secret key. Kaip teisės ir politikos dera visoje programoje, aprašyta mano Lovable programos saugos kontrolinėje.

Ko nedaryti, kai ateina pirmoji 42501:

  • Nevykdykite grant all on all tables in schema public to anon, authenticated. Tai vienu metu grąžina seną numatytąjį nustatymą kiekvienai lentelei, įskaitant tas, kuriose RLS niekada neįjungtas, ir jas gali skaityti bet kas, turintis jūsų viešąjį raktą. 42501 pastaba parodo, kodėl teisė yra pirmas užraktas, o RLS antras.
  • Iš naujo nepridėkite alter default privileges … grant. Tai viso pokyčio atšaukimas.
  • Neišjunkite RLS „testavimui“ ir nedėkite secret key į frontend. Secret key apeina RLS kiekvienam, atidariusiam jūsų bundle; skirtumas tarp raktų aprašytas anon key vs service role key.

Jei jūsų migracijas rašo DI įrankis, pridėkite jam vieną eilutę instrukcijose: „kiekviena nauja lentelė public schemoje gauna aiškias teises kiekvienai rolei, tos pačios migracijos metu įjunk row level security ir politikas; niekada nesuteik teisių visoms lentelėms public schemoje“. Klaidos užuomina išmoko jį teisės, bet niekada RLS, kuris prie jos priklauso.

Klausimai, kuriuos žmonės užduoda apie pokytį

Ar mano esamos lentelės nustos veikti spalio 30 d.? Ne. Numatytosios teisės galioja vėliau sukurtiems objektams, o mano bandyme sena lentelė po perjungimo atsakė HTTP 200. Išimtis yra lentelė, kurią jūsų migracijos ištrina ir sukuria iš naujo.

Ar man reikia ką nors daryti, jei niekada nekuriu lentelių? 30-ąją ne. Patikrinkite kitą kartą, kai jūs, kolega ar DI įrankis ją pridės, ir patikrinkite kiekvieną pipeline, kuris kuria projektus ar šakas iš jūsų migracijų.

Ar tai veikia Edge Functions? Taip, jei jos su secret key naudoja supabase-js naujoje lentelėje: service_role irgi reikia teisės. Funkcijos, jungiančios prie Postgres tiesiogiai, nepaveikiamos.

Ar tai veikia RPC funkcijas, Storage ar Auth? Šiame pokytyje ne. Naujos funkcijos lieka pasiekiamos per PUBLIC, o storage ir auth nėra public schema.

Ar galiu pereiti anksčiau? Taip. Dvi komandos pačioje pradžioje ir yra perjungimas; pirmiausia paleiskite staging, paskui production. Esamos lentelės išsaugo teises, todėl veikianti programa to nepastebi, o kita nauja lentelė iškart parodo, ar jūsų migracijos paruoštos.

Kaip tai mato tikrintuvas

Tikrintuvas jungiasi tik skaitymo režimu ir skaito teises kiekvienoje lentelėje jūsų atskleistose schemose: į kurias lenteles viešasis raktas gali rašyti be politikos, kuriose lentelėse RLS išjungtas ir kurios numatytosios teisės dar duoda kiekvienai naujai lentelei TRUNCATE, REFERENCES ar TRIGGER. Jis taip pat išvardija kiekvieną politiką, kurios vaidmuo neturi teisės tai komandai: lentelės, kurias randa 2 patikrinimas aukščiau, išskyrus tas, kuriose RLS išjungtas arba suteiktos stulpelių teisės. Jis nemato migracijų failų, kurių nepritaikėte, todėl 3 patikrinimą aukščiau turite paleisti patys. Jei abejojate dėl RLS, kaip testuoti Supabase RLS paaiškina žingsnis po žingsnio, o atskleistų schemų pastaba aprašo kitas schemas nei public, kurių šis pokytis nelieka.

© 2026 Denys Zaichenko. Originalus straipsnis: https://madsalt.tech/lt/blog/supabase-october-30-grant-change/