Pereiti prie turinio

Supabase 42501 permission denied: teisė, ne RLS

Supabase

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

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

Trumpai

42501 permission denied for table … reiškia, kad rolė neturi teisės (grant) į lentelę, todėl Postgres sustabdo užklausą, kol nepaleista jokia RLS politika. Nuo 2026 m. spalio 30 d. Supabase esamuose projektuose nustoja automatiškai suteikti teises naujoms public schemos lentelėms, todėl po to sukurtos lentelės atsako 42501, kol joms nesuteikiate teisių. Taisymas yra trys komandos kartu: teisė operacijoms, kurių rolei reikia, enable row level security ir politika. Vien teisės suteikimas be RLS atveria lentelę visiems.

Sukūriau nemokamą Supabase saugos tikrintuvą, kuris skaito teises kiekvienoje atskleistoje lentelėje, o 42501 yra klaida, su kuria žmonės susiduria, kai teisės neteisingos kita kryptimi: per mažai, o ne per daug. Štai ką tai reiškia ir ką mačiau, kai tai atkartojau.

Ką reiškia klaida 42501 Supabase?

42501 yra Postgres kodas nepakankamoms teisėms (insufficient privilege). Postgres tikrina du sluoksnius, kol klientas neprisilietė prie lentelės: teisės (grants) nusprendžia, ar rolė apskritai gali atlikti operaciją, o RLS politikos nusprendžia, kurias eilutes. Trūkstama teisė suklysta pirmiausia, kaip klaida. Politika, nesutampanti su jokia eilute, suklysta tyliai, kaip tuščias sąrašas. Taigi pamatę 42501 žiūrėkite į teises, o ne į politikas.

PostgREST, Data API už supabase-js, klaidą perduoda toliau su užuomina. Mano vietinėje aplinkoje (Supabase CLI 2.109.1, Postgres 17.6, PostgREST 14.14) užklausa su publishable key į lentelę be teisės rolei anon grąžino HTTP 401 ir:

{
  "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"
}

Kodėl naujos lentelės po 2026 m. spalio 30 d. gauna 42501?

Iki šiol nauja lentelė schemoje public per numatytąsias teises (default privileges) gaudavo select, insert, update ir delete rolėms anon, authenticated ir service_role, todėl ji buvo pasiekiama per Data API nuo sukūrimo akimirkos, apsaugota ar ne. Supabase changelog šiuos numatytuosius nustatymus pašalina: pasirenkama nuo 2026 m. balandžio 28 d., numatytoji naujiems projektams nuo 2026 m. gegužės 30 d. ir taikoma visiems esamiems projektams 2026 m. spalio 30 d. Esamos lentelės teises išsaugo.

Ką dar sugadina perjungimas ir kaip patikrinti projektą iš anksto: Supabase spalio 30 d. pokytis: kas sulūš ir kaip patikrinti.

Tą patį pakeitimą pritaikiau savo vietiniam projektui dviem changelog pateiktomis alter default privileges … revoke komandomis ir sukūriau naują lentelę invoices:

Ką nauja lentelė atsako po 2026 m. spalio 30 d.. Vietinis Supabase su naujomis numatytosiomis teisėmis, po vieną užklausą. Publishable key, teisės nėra: create table → teisės nėra → 42501, HTTP 401; Secret key, teisės nėra: create table → teisės nėra → 42501, HTTP 403; Po grant select ir enable RLS: grant select → RLS įjungtas → 0 eilučių, HTTP 200.
Mano atkartojimas vietiniame Supabase su numatytosiomis teisėmis iš Supabase changelog, 2026 m. spalio 23 d.
Užklausa į naują lentelę Rezultatas
Publishable key, teisės nėra HTTP 401, 42501, užuomina GRANT SELECT ON public.invoices TO anon;
Secret key, teisės nėra HTTP 403, 42501, užuomina … TO service_role;
Publishable key, po grant select ir enable row level security HTTP 200, [], kol politika neleis eilučių

Mane nustebino du dalykai. Secret key taip pat atmetamas: service_role apeina RLS, bet jai vis tiek reikia teisės, todėl Edge Function ar serverio užduotis, rašanti į naują lentelę, genda taip pat. Ir revoke atima tik šias keturias operacijas: nauja lentelė vis tiek atėjo su REFERENCES, TRIGGER ir TRUNCATE teisėmis rolėms anon, authenticated ir service_role. Jokia politika TRUNCATE netaikoma.

Kaip ištaisyti 42501, neatveriant lentelės?

Laikykite teisę, RLS ir politiką vienu pakeitimu, vienoje migracijoje, ir kiekvienai rolei suteikite tik tai, ko jai reikia:

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

revoke all pirmiausia išvalo TRUNCATE, TRIGGER ir REFERENCES, kurie atėjo kartu su lentele. Neatsakykite į 42501 komanda grant all on all tables in schema public to anon: tai senas numatytasis nustatymas atgal, visoms lentelėms iš karto, ir bet kuri lentelė be RLS tampa skaitoma kiekvienam, turinčiam jūsų viešąjį raktą.

Jei jūsų lenteles kuria AI įrankis, liepkite jam išduoti teises, RLS ir politikas toje pačioje migracijoje. Klaidos užuomina parašyta taip, kad agentas pats galėtų ištaisyti teisę, tačiau užuomina nurodo tik teisę, o ne RLS, kuris turi eiti kartu.

Kaip tai mato tikrintuvas?

Keturios jo taisyklės skaito teisių sluoksnį: „Numatytosios teisės, kurios atveria naujus objektus API” pažymi projektus, kurie vis dar automatiškai suteikia teises naujoms lentelėms, „Nenaudojamos rašymo teisės anoniminiams lankytojams” randa anon rašymo teises, kurių nenaudoja jokia politika, o „Nereikalingos lentelių teisės prisijungusiems naudotojams” randa TRUNCATE, TRIGGER ir REFERENCES, kaip aukščiau. „Politikos, kurios niekada nevykdomos: vaidmuo neturi teisės” išvardija lenteles, kuriose politika nurodo vaidmenį be teisės tai komandai, būtent taip po spalio 30 d. atrodo nauja lentelė. Kodėl RLS svarbus ir suteikus teisę, aprašyta straipsnyje kaip testuoju Supabase RLS, o kaip teisės ir politikos atrodo visoje programoje, rasite mano Lovable programos saugos sąraše.

© 2026 Denys Zaichenko. Originalus straipsnis: https://madsalt.tech/lt/notes/supabase-42501-permission-denied/