Prejsť na obsah

Supabase 30. októbra: zmena grantov a čo prestane fungovať

Zobraziť ako MarkdownOtvoriť v ClaudeOtvoriť v ChatGPTOtvoriť v Perplexity

Otázka sa tiež skopíruje. Ak sa chat otvorí prázdny, vložte ju.

TL;DR

Supabase 30. októbra 2026 prestane na každom existujúcom projekte dávať novým tabuľkám v public automatické granty pre anon, authenticated a service_role. Tabuľky, ktoré už máte, fungujú ďalej. Každá tabuľka vytvorená po tomto dátume odpovie supabase-js aj vášmu secret key chybou 42501 permission denied, kým jej migrácia nedá grant. Prepnutie som reprodukoval lokálne: nové tabuľky, nové views aj staré tabuľky, ktoré migrácia zmaže a vytvorí znova, zlyhajú; existujúce tabuľky, RPC funkcie a inserty do serial fungujú ďalej. Skontrolujte to dvomi SQL dotazmi a jedným grepom nižšie a opravte grantom, RLS a politikou v tej istej migrácii, nikdy nie cez grant all on all tables.

Prevádzkujem bezplatný bezpečnostný checker pre Supabase, ktorý číta granty na každej sprístupnenej tabuľke, a chcel som presne vidieť, čo táto zmena robí, skôr než na ňu ľudia narazia. Postavil som lokálny stack Supabase, dal mu staré defaulty, prepnutie som aplikoval tak, ako ho opisuje Supabase, a poslal som požiadavku na každý druh objektu, ktorý ma napadol. Tento článok je to, čo prišlo späť, a ako skontrolovať vlastný projekt pred 30.

Čo sa mení 30. októbra 2026?

Doteraz dostala každá tabuľka vytvorená v schéme public cez default privileges Postgresu select, insert, update a delete pre anon, authenticated a service_role. Preto bola nová tabuľka dostupná z prehliadača hneď, ako vznikla, chránená RLS alebo nie. Oznámenie o breaking change od Supabase tieto defaulty odoberá v troch krokoch:

Dátum Čo sa stane
28. apríla 2026 Nové projekty môžu pri vytvorení vypnúť “Automatically expose new tables”
30. mája 2026 Nové správanie sa stane predvoleným pre nové projekty, nasadzuje sa niekoľko týždňov
30. októbra 2026 Nové správanie sa uplatní na všetky existujúce projekty

Na vašom projekte je prepnutie dvojica príkazov, tých istých, ktoré Supabase uvádza pre skoršie prijatie:

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 platia len pre objekty vytvorené neskôr. Existujúce granty sa nedotknú, preto vaše súčasné tabuľky fungujú ďalej. Čo sa podľa oznámenia nemení: iné schémy (auth, storage, realtime, vaše vlastné), aplikácie komunikujúce s Postgresom priamym pripojením (psql, ORM, server s connection stringom) a samotné RLS. Zmena sa týka Data API: REST, GraphQL a každej klientskej knižnice nad nimi.

Čo sa pokazí a čo funguje ďalej?

Moje prostredie: Supabase CLI 2.109.1, Postgres 17.6, PostgREST 14.14, 26. októbra 2026. V config.toml som nastavil auto_expose_new_tables = true, aby som dostal staré defaulty, vytvoril jednu tabuľku s dvoma riadkami, zapnutým RLS a čítacou politikou a potom spustil dva príkazy vyššie. Potom som vytvoril nové objekty a každý som zavolal lokálnym verejným (anon) kľúčom a secret (service_role) kľúčom, po jednej požiadavke.

Čo prestane odpovedať po prepnutí 30. októbra. Lokálny Supabase, objekty vytvorené po revoke z changelogu, verejný kľúč, ak nie je uvedené inak. Nová tabuľka s RLS a politikou: create table → politika, bez grantu → 42501, HTTP 401; Tá istá tabuľka so secret key: create table → politika, bez grantu → 42501, HTTP 403; Nový view nad tabuľkou, ktorá ešte funguje: create view → 42501, HTTP 401, bez hintu; Stará tabuľka zmazaná a znova vytvorená migráciou: drop + create table → granty preč → 42501, HTTP 401.
Moja reprodukcia na lokálnom stacku Supabase (CLI 2.109.1, Postgres 17.6, PostgREST 14.14), 26. októbra 2026.
Čo funguje ďalej po prepnutí 30. októbra. Ten istý lokálny stack, ten istý revoke, verejný kľúč. Tabuľka vytvorená pred prepnutím: existujúca tabuľka → granty ostali → 2 riadky, HTTP 200; Nová funkcia volaná cez RPC: create function → execute cez PUBLIC → HTTP 200; Nová serial tabuľka, grant len na select a insert: id serial → sequence má UPDATE → insert, HTTP 201.
Moja reprodukcia na lokálnom stacku Supabase (CLI 2.109.1, Postgres 17.6, PostgREST 14.14), 26. októbra 2026.
Objekt, vytvorený po prepnutí, ak nie je uvedené inak Kľúč Výsledok
Tabuľka vytvorená pred prepnutím verejný HTTP 200, 2 riadky
Nová tabuľka s RLS a politikou to anon, authenticated verejný HTTP 401, 42501, hint GRANT SELECT ON public.new_orders TO anon;
Tá istá nová tabuľka secret HTTP 403, 42501, hint … TO service_role;
Nový view (security_invoker) nad starou tabuľkou verejný HTTP 401, 42501, permission denied for view, hint null
Kópia vytvorená cez create table … (like old_orders including all) verejný HTTP 401, 42501
Stará tabuľka po drop table a opätovnom create table verejný HTTP 401, 42501
Nová funkcia public.ping() cez /rest/v1/rpc verejný HTTP 200
Nová tabuľka s id serial, pre anon len select, insert verejný insert HTTP 201

V tejto tabuľke je päť vecí, ktoré stojí za to vedieť pred prepnutím.

“Existujúce tabuľky si udržia granty” platí, len kým tabuľka existuje. Migrácia, ktorá tabuľku zmaže a vytvorí znova, kópia cez create table … (like …) alebo obnova z dumpu vytvoria novú tabuľku a nová tabuľka nedostane nič. Politika sa vrátila s mojím create policy, granty nie. Čokoľvek vo vašom pipeline, čo tabuľky prestavuje namiesto úpravy, zlyhá pri prvom behu po prepnutí.

Zlyhá aj secret key. service_role obchádza RLS, ale grant stále potrebuje. Takže Edge Function, cron úloha alebo webhook handler, ktorý zapisuje do novej tabuľky, zlyhá s 403, nielen prehliadač. Hint uvádza service_role, podľa čoho to rozoznáte.

Views nedajú hint. Pri tabuľkách PostgREST vráti presný GRANT, ktorý potrebujete. Pri mojom novom view bol hint null a správa znela permission denied for view v_old_orders. AI nástroj, ktorý opravuje 42501 podľa hintu, tu nemá čo skopírovať; grant je grant select on public.v_old_orders to authenticated; a view si má ponechať security_invoker = true, aby sa RLS tabuľky ďalej uplatňovalo.

Funkcie nie sú súčasťou tejto zmeny. Dva príkazy sa týkajú tabuliek a sekvencií. Moja nová funkcia ostala volateľná pre anon, authenticated aj service_role, lebo Postgres dáva execute na každú novú funkciu role PUBLIC a revoke na úrovni schémy ho nedokáže odobrať, ako vysvetľuje príručka Supabase o zabezpečení API. RPC volania fungujú aj po 30. októbri; zároveň to znamená, že nová funkcia security definer je volateľná vaším verejným kľúčom hneď, ako vznikne.

Inserty do serial fungovali aj bez grantu na sekvenciu. Veľa rád hovorí, že serial id po prepnutí potrebuje grant usage on sequence … to authenticated. V mojom behu insert prešiel bez neho: revoke odoberá usage a select na nových sekvenciách, ale update ostáva a update na nextval stačí. Ak odoberiete všetky default privileges na sekvenciách, ako robí úplný revoke v príručke o zabezpečení API, grant na usage potrebujete. Identity stĺpec (generated by default as identity) nepotrebuje nič v oboch prípadoch.

Ešte jedna vec, ktorú revoke necháva: nová tabuľka stále prišla s TRUNCATE, REFERENCES a TRIGGER pre všetky tri roly a na Postgrese 17 defaulty obsahujú aj MAINTAIN. Na TRUNCATE sa nevzťahuje žiadna politika RLS. Písal som o tom v poznámke o 42501.

Kde na to narazíte pred 30. októbrom

Prepnutie na vašom hostovanom projekte je 30., ale tri miesta sa už správajú ako po ňom.

supabase db reset na aktuálnom CLI. CLI v2.102.0 pridalo do config.toml kľúč [api] auto_expose_new_tables. Na 2.109.1 s vynechaným kľúčom mal môj čerstvý stack už nové defaulty: tabuľky dostali len MAINTAIN, REFERENCES, TRIGGER a TRUNCATE, sekvencie len UPDATE. Nastavenie na true vráti staré granty a vypíše api.auto_expose_new_tables is deprecated and will be removed on 2026-10-30. Ak vám teda lokálne tabuľky po resete stále fungujú, skontrolujte najprv tento kľúč. Je to aj najlacnejšie miesto na test: odstráňte ho, urobte reset, spustite aplikáciu.

Preview branche a projekty vytvorené od 30. mája. Prehrávajú vaše migrácie na nových defaultoch. Každá tabuľka, ktorej migrácia nemá grant, je tam už nedostupná. V diskusii na GitHube ľudia s jedným projektom na zákazníka hlásia presne toto: bežiace projekty sú v poriadku, každé nové nasadenie z rovnakých migrácií je rozbité.

Baseline migrácia, ktorá vráti starý default. Komentujúci v tej istej diskusii upozorňuje, že prvá migrácia vytvorená cez supabase db pull môže obsahovať alter default privileges … grant all on tables to anon, authenticated, service_role. Spustil som ten príkaz po prepnutí: ďalšia tabuľka, ktorú som vytvoril, bola znova dostupná, HTTP 200. Lokálne to problém skryje. Na hostovanom projekte potichu zruší zmenu a každá budúca tabuľka je znova otvorená verejnému kľúču, s RLS či bez. Prehľadajte svoje migrácie na alter default privileges a prečítajte si každý nález.

Ako skontrolovať projekt pred 30. októbrom

Štyri kontroly, od najrýchlejšej po najdôkladnejšiu. Prvé dve bežia v SQL Editore hostovaného projektu.

1. Prepol sa už váš projekt?

Toto je dotaz z príručky Supabase o zabezpečení API. Vypíše, čo dostanú nové objekty vytvorené používateľom postgres v 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;

Ak riadky tables obsahujú SELECT, INSERT, UPDATE, DELETE, projekt je ešte na starom defaulte a prepne sa 30. Ak ukazujú len MAINTAIN, REFERENCES, TRIGGER, TRUNCATE (alebo žiadne riadky), nové tabuľky sú už zatvorené. Vidíte to aj v Dashboarde v nastaveniach Data API, “Automatically expose new tables”.

2. Ktoré tabuľky majú politiku, ale nemajú grant?

Politika pre rolu, ktorá nemá grant na daný príkaz, sa nikdy nespustí: požiadavka zlyhá pred RLS. Tento dotaz vypíše také dvojice. V mojom laboratóriu našiel novú tabuľku a znova vytvorenú starú a nič iné:

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;

Spúšťajte ho po každej migrácii, v CI proti čerstvému db reset alebo na stagingu. Na zdravom projekte nevráti nič; po 30. je každý riadok tabuľkou, ktorú vaša aplikácia nedosiahne. Kontroluje granty na úrovni tabuľky, takže tabuľka otvorená len grantmi na stĺpce (grant select (id, name) on …) sa tu objaví, aj keď sú tie stĺpce čitateľné.

3. Ktoré migrácie vytvárajú tabuľku bez grantu?

Databáza ukazuje len tabuľky, ktoré existujú. Migrácia, ktorú ste ešte neaplikovali, je vidieť len vo vašom repozitári. Tento hrubý grep vypíše každé create table v supabase/migrations bez grant … on pre rovnaké meno:

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

Je to porovnávanie textu, nie parsovanie SQL: grant, ktorý uvádza viac tabuliek v jednom príkaze, alebo tabuľka pomenovaná raz bez schémy a inde so schémou, dá falošný nález. Prečítajte si každý riadok, ktorý vypíše. Tabuľky, ku ktorým pristupuje len serverový kód priamym pripojením, grant vôbec nepotrebujú.

4. Prehrajte všetko na nových defaultoch

Odstráňte auto_expose_new_tables z config.toml, spustite supabase db reset a proti tomu spustite aplikáciu alebo jej testy. To je váš projekt po 30., plus čerstvá kópia každej tabuľky, čo je ťažší prípad. Supabase vypisuje dotknuté tabuľky aj v Security Advisor a v Table Editore označuje sprístupnenie cez Data API.

Ako to opraviť bez otvorenia každej tabuľky

Grant, RLS a politiky napíšte do migrácie, ktorá tabuľku vytvára, a každej role dajte len to, čo aplikácia používa:

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

Tento blok som spustil na tom istom lokálnom stacku: prihlásený testovací používateľ vložil riadok a prečítal ho späť (HTTP 201, potom 200), verejný kľúč bez session dostal 42501 a kontrola 2 vyššie tabuľku už nevypísala. Úvodné revoke all odstráni TRUNCATE, TRIGGER a REFERENCES, ktoré prichádzajú s novou tabuľkou, a na projekte, ktorý sa ešte neprepol, dáva rovnaký výsledok. Roli anon dávajte grant len na dáta určené pre neprihlásených návštevníkov a service_role len ak serverový kód používa na tejto tabuľke secret key. Ako do seba zapadajú granty a politiky v celej aplikácii, je v mojom bezpečnostnom checkliste pre aplikácie z Lovable.

Čo nerobiť, keď príde prvé 42501:

  • Nespúšťajte grant all on all tables in schema public to anon, authenticated. Vráti starý default naraz na všetky tabuľky, aj na tie, kde sa RLS nikdy nezapol, a tie potom prečíta každý, kto má váš verejný kľúč. Poznámka o 42501 ukazuje, prečo je grant prvý zámok a RLS druhý.
  • Nepridávajte späť alter default privileges … grant. Je to rollback celej zmeny.
  • Nevypínajte RLS kvôli “testovaniu” a nedávajte secret key do frontendu. Secret key obchádza RLS pre každého, kto otvorí váš bundle; rozdiel medzi kľúčmi je v anon key vs service role key.

Ak vaše migrácie píše AI nástroj, pridajte do jeho pokynov jeden riadok: “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”. Hint v chybe ho naučí grant, nikdy nie RLS, ktoré k nemu patrí.

Otázky, ktoré ľudia kladú

Prestanú mi 30. októbra fungovať existujúce tabuľky? Nie. Default privileges platia pre objekty vytvorené neskôr a v mojom behu stará tabuľka po prepnutí odpovedala HTTP 200. Výnimkou je tabuľka, ktorú vaše migrácie zmažú a vytvoria znova.

Musím niečo robiť, ak tabuľky nikdy nevytváram? 30. nie. Skontrolujte to, až keď nejakú pridáte vy, kolega alebo AI nástroj, a skontrolujte každý pipeline, ktorý vytvára projekty alebo branche z vašich migrácií.

Týka sa to Edge Functions? Áno, ak používajú supabase-js so secret key na novej tabuľke: service_role tiež potrebuje grant. Funkcie, ktoré sa pripájajú k Postgresu priamo, to neovplyvní.

Týka sa to RPC funkcií, Storage alebo Auth? V tejto zmene nie. Nové funkcie ostávajú volateľné cez PUBLIC a storage a auth nie sú schéma public.

Môžem prepnúť skôr? Áno. Dva príkazy na začiatku sú prepnutie; spustite ich najprv na stagingu, potom na produkcii. Existujúce tabuľky si granty ponechajú, takže bežiaca aplikácia nič nezbadá a ďalšia nová tabuľka vám hneď povie, či sú vaše migrácie pripravené.

Ako to vidí checker

Checker sa pripája len na čítanie a číta granty na každej tabuľke vo vašich sprístupnených schémach: do ktorých tabuliek môže verejný kľúč zapisovať bez politiky, ktoré tabuľky majú vypnuté RLS a ktoré default privileges ešte dávajú každej novej tabuľke TRUNCATE, REFERENCES alebo TRIGGER. Vypíše aj každú politiku, ktorej rola nemá grant na daný príkaz, teda tabuľky, ktoré nájde kontrola 2, okrem tých s vypnutým RLS alebo so stĺpcovými grantmi. Nevidí súbory migrácií, ktoré ste ešte neaplikovali, takže kontrola 3 vyššie ostáva na vás. Ak si nie ste istí práve RLS, ako testovať Supabase RLS vás ňou prevedie a poznámka o sprístupnených schémach pokrýva schémy iné než public, ktoré táto zmena nechá na pokoji.

© 2026 Denys Zaichenko. Pôvodný článok: https://madsalt.tech/sk/blog/supabase-october-30-grant-change/