TL;DR
42501 permission denied for table … znamená, že rola nemá na tabuľku grant, takže Postgres zastaví požiadavku skôr, než sa spustí akákoľvek politika RLS. Od 30. októbra 2026 Supabase na existujúcich projektoch prestáva tabuľky v public automaticky sprístupňovať, takže tabuľky vytvorené neskôr odpovedajú 42501, kým im nedáte grant. Oprava sú tri príkazy dokopy: grant pre operácie, ktoré rola potrebuje, enable row level security a politika. Samotný grant bez RLS otvorí tabuľku všetkým.
Postavil som bezplatný bezpečnostný checker pre Supabase, ktorý číta granty na každej sprístupnenej tabuľke, a 42501 je chyba, na ktorú ľudia narazia, keď sú granty zle na opačnú stranu: príliš málo namiesto príliš veľa. Tu je, čo znamená a čo som videl, keď som ju reprodukoval.
Čo znamená chyba 42501 v Supabase?
42501 je kód Postgresu pre nedostatočné oprávnenie. Postgres kontroluje dve vrstvy, než sa klient dotkne tabuľky: granty rozhodujú, či rola smie operáciu vôbec vykonať, a politiky RLS rozhodujú o riadkoch. Chýbajúci grant zlyhá prvý, ako chyba. Politika, ktorá nič nezodpovedá, zlyhá ticho, ako prázdny zoznam. Keď teda vidíte 42501, pozerajte sa na granty, nie na politiky.
PostgREST, Data API za supabase-js, chybu odovzdá ďalej s nápovedou. Na mojom lokálnom stacku (Supabase CLI 2.109.1, Postgres 17.6, PostgREST 14.14) vrátila požiadavka s publishable key na tabuľku bez grantu pre anon HTTP 401 a:
{
"code": "42501",
"details": null,
"hint": "Grant the required privileges to the current role with: GRANT SELECT ON public.orders TO anon;",
"message": "permission denied for table orders"
}
Prečo nové tabuľky dostávajú 42501 po 30. októbri 2026?
Doteraz dostala nová tabuľka v public cez predvolené oprávnenia select, insert, update a delete pre anon, authenticated a service_role, takže bola dosiahnuteľná cez Data API hneď po vytvorení, chránená či nie. Changelog Supabase tieto predvolené nastavenia odstraňuje: voliteľne od 28. apríla 2026, ako predvolené pre nové projekty od 30. mája 2026 a na všetky existujúce projekty sa použije 30. októbra 2026. Existujúce tabuľky si granty ponechajú.
Čo ďalšie prepnutie pokazí a ako projekt skontrolovať vopred: Supabase 30. októbra: zmena grantov a čo prestane fungovať.
Rovnakú zmenu som aplikoval na svoj lokálny projekt pomocou dvoch príkazov alter default privileges … revoke z changelogu a potom vytvoril novú tabuľku invoices:
| Požiadavka na novú tabuľku | Výsledok |
|---|---|
| Publishable key, bez grantu | HTTP 401, 42501, nápoveda GRANT SELECT ON public.invoices TO anon; |
| Secret key, bez grantu | HTTP 403, 42501, nápoveda … TO service_role; |
Publishable key, po grant select a enable row level security |
HTTP 200, [], kým politika nepovolí riadky |
Dve veci ma prekvapili. Secret key je odmietnutý tiež: service_role obchádza RLS, ale grant aj tak potrebuje, takže Edge Function alebo serverová úloha, ktorá zapisuje do novej tabuľky, sa pokazí rovnako. A revoke berie späť len tie štyri operácie: nová tabuľka aj tak prišla s REFERENCES, TRIGGER a TRUNCATE pre anon, authenticated a service_role. Na TRUNCATE sa žiadna politika nevzťahuje.
Ako opraviť 42501, bez toho aby ste otvorili tabuľku?
Berte grant, RLS a politiku ako jednu zmenu v jednej migrácii a každej role dajte len to, čo potrebuje:
revoke all on table public.invoices from anon, authenticated;
grant select, insert, update 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);
Úvodný revoke all zmaže TRUNCATE, TRIGGER a REFERENCES, ktoré prišli s tabuľkou. Na 42501 neodpovedajte príkazom grant all on all tables in schema public to anon: to je starý predvolený stav späť, pre všetky tabuľky naraz, a každá tabuľka bez RLS sa stane čitateľnou pre kohokoľvek s vaším verejným kľúčom.
Ak vaše tabuľky vytvára AI nástroj, povedzte mu, nech granty, RLS a politiky vydáva v rovnakej migrácii. Nápoveda v chybe je napísaná tak, aby agent mohol grant opraviť sám, ale menuje len grant, nie RLS, ktoré by k nemu malo prísť.
Ako to vidí checker?
Štyri jeho pravidlá čítajú vrstvu grantov: „Predvolené oprávnenia, ktoré otvárajú nové objekty pre API“ označí projekty, ktoré stále automaticky sprístupňujú nové tabuľky, „Nepoužívané oprávnenia na zápis pre anonymných návštevníkov“ nájde zápisové granty pre anon, ktoré nepoužíva žiadna politika, a „Zbytočné oprávnenia na tabuľky pre prihlásených používateľov“ nájde TRUNCATE, TRIGGER a REFERENCES ako tie vyššie. „Politiky, ktoré nikdy nebežia: rola nemá grant“ vypíše tabuľky, kde politika uvádza rolu bez grantu na daný príkaz, a presne tak vyzerá nová tabuľka po 30. októbri. Prečo RLS záleží aj po grante, je v článku ako testovať Supabase RLS a ako vyzerajú granty a politiky naprieč celou aplikáciou, je v mojom checkliste bezpečnosti aplikácie z Lovable.