---
title: "How to enable RLS in Supabase: ką grąžina API"
description: "How to enable RLS in Supabase iš dashboard ar SQL, išbandyta lokaliai: ką po kiekvieno žingsnio gauna viešasis raktas, du vartotojai ir slaptasis raktas."
url: "https://madsalt.tech/lt/blog/how-to-enable-rls-in-supabase/"
author: "Denys Zaichenko"
author_url: "https://madsalt.tech/lt/about/"
language: "lt"
published: 2026-11-04
---

# How to enable RLS in Supabase: ką grąžina API

Trumpai

RLS Supabase įjungiate vienu sakiniu kiekvienai lentelei, `alter table public.todos enable row level security;`, arba dashboard pasirinkimu „Enable RLS“. Lentelės, sukurtos SQL redaktoriuje ar migracija, jo pagal nutylėjimą neturi. Iškart po įjungimo lentelė greičiau nutyla, nei pradeda šaukti. Mano vietiniame teste viešasis raktas ir du prisijungę vartotojai select, update ir delete gavo `200 []`, o nepavyko tik insert, su `42501`. Slaptasis raktas vis dar matė visas 3 eilutes. Paprastas vaizdas (view) virš lentelės viešajam raktui vis dar atiduodavo visas 3 eilutes. Nuo 2026 m. spalio 30 d. nauja lentelė taip pat reikalauja teisės (grant), kad kas nors ją pasiektų, todėl įjunkite RLS ir parašykite politikas toje pačioje migracijoje kaip ir grant.

Palaikau nemokamą [Supabase saugumo patikrinimą](https://madsalt.tech/lt/tools/supabase-security-check/), o „RLS disabled“ yra radinys, kuris paaiškinamas prasčiausiai. Dauguma vadovų sako, kad įjungus RLS lentelė „tampa nepasiekiama“. Skaitymui tai tiesa, rašymui klaidina. Todėl sukūriau vieną lentelę vietiniame Supabase stack ir po kiekvieno žemiau pateikto žingsnio siunčiau jai visų rūšių užklausas: kaip viešasis raktas, kaip du prisijungę vartotojai ir kaip slaptasis raktas.

## Kas yra RLS Supabase?

RLS (row-level security) yra Postgres funkcija, filtruojanti eilutes kiekvienai užklausai. Supabase kiekvieną `supabase-js` užklausą paverčia duomenų bazės užklausa, vykdoma kaip rolė: `anon` viešajam raktui (anon, publishable), `authenticated` prisijungusiam vartotojui. Kai RLS įjungtas, Postgres kiekvienai eilutei tikrina jūsų politikas ir grąžina, keičia ar trina tik tas eilutes, kurias politika leidžia. Kai RLS išjungtas, bet kuri rolė, turinti teisę į lentelę, pasiekia kiekvieną eilutę.

Slaptasis raktas (service role) kitoks. Jo rolė turi `BYPASSRLS`, todėl RLS jam niekada netaikomas. Todėl jis priklauso tik serveriui. Skirtumas tarp abiejų raktų aprašytas straipsnyje [Supabase anon key vs service role key: ką jie atveria](https://madsalt.tech/lt/blog/supabase-anon-key-vs-service-role-key/).

## Kaip įjungti RLS Supabase?

Trimis būdais, priklausomai nuo to, kaip lentelė sukurta:

- **Kuriant lentelę Table Editor** palikite pažymėtą „Enable Row Level Security (RLS)“. Supabase [dashboard šaltinio kode](https://github.com/supabase/supabase/commit/33bd798d142183e162c25debcc50c8c711e68f66) tai pažymėta „Recommended“, o išjungus rodomas įspėjimas, kad lentelė bus viešai skaitoma ir rašoma.
- **Esamai lentelei** Supabase [API saugumo vadovas](https://supabase.com/docs/guides/api/securing-your-api) sako: eikite į Database, tada Policies ir prie lentelės pasirinkite „Enable RLS“.
- **SQL**, SQL redaktoriuje arba migracijoje:

```sql
alter table public.todos enable row level security;
```

Supabase vadove aiškiai sakoma, kad dashboard sukurtos lentelės turi RLS įjungtą pagal nutylėjimą, o SQL redaktoriuje ar kitu įrankiu sukurtos – ne. Jei schemą kuriate migracijomis ar AI įrankiu, patikrinkite kiekvieną lentelę.

## Kas nutinka iškart po RLS įjungimo?

Nieko neduoda klaidos, išskyrus insert. Sukūriau `public.todos` su savininko stulpeliu (`user_id uuid default auth.uid()`), suteikiau jai teises API rolėms taip, kaip senesni projektai, ir pridėjau tris eilutes: dvi, priklausančias vartotojui A, ir vieną vartotojui B. Tada įjungiau RLS be jokios politikos:

| Užklausa            | Viešasis raktas   | Vartotojas A      | Vartotojas B      | Slaptasis raktas    |
| ------------------- | ----------------- | ----------------- | ----------------- | ------------------- |
| Select              | 200, 0 eilučių    | 200, 0 eilučių    | 200, 0 eilučių    | 200, 3 eilutės      |
| Insert savo eilutės | 401, klaida 42501 | 403, klaida 42501 | 403, klaida 42501 | 201, eilutė įterpta |
| Update eilutės      | 200, 0 eilučių    | 200, 0 eilučių    | 200, 0 eilučių    | 200, 1 eilutė       |
| Delete eilutės      | 200, 0 eilučių    | 200, 0 eilučių    | 200, 0 eilučių    | 200, 1 eilutė       |

Insert klaida skamba `new row violates row-level security policy`. Update ir delete atsako `200` su tuščiu masyvu, todėl programa, netikrinanti grąžintų eilučių, praneša „išsaugota“, nors niekas neišsaugota. Įjungę RLS perskaitykite savo įrašus atgal arba paprašykite skaičiaus per `Prefer: count=exact`.

Prieš RLS, su tomis pačiomis teisėmis, viešasis raktas galėjo perskaityti visas 3 eilutes, įterpti ir keisti ar trinti bet kurią eilutę. Vartotojas A galėjo redaguoti ir ištrinti vartotojo B eilutę ir perduoti savo eilutes B.

## Kaip vėl padaryti lentelę naudojamą?

Parašykite politiką kiekvienai operacijai. Įprastas savų eilučių rinkinys:

```sql
create policy "own select" on public.todos for select to authenticated
  using ((select auth.uid()) = user_id);
create policy "own insert" on public.todos for insert to authenticated
  with check ((select auth.uid()) = user_id);
create policy "own update" on public.todos for update to authenticated
  using ((select auth.uid()) = user_id) with check ((select auth.uid()) = user_id);
create policy "own delete" on public.todos for delete to authenticated
  using ((select auth.uid()) = user_id);
```

Su jomis vartotojas A matė savo 2 eilutes, o vartotojas B savo 1. Viešasis raktas vis dar matė 0. Kai A bandė įterpti eilutę, priklausančią B, arba perkelti savo eilutę B, atsakymas buvo `403, 42501`. Šis atmetimas ateina iš `with check` ties update. Kai A bandė pakeisti ar ištrinti vartotojo B eilutę, atsakymas buvo `200, 0 rows`. Daugiau modelių (vieši profiliai, komandos, MFA) rasite straipsnyje [Supabase RLS policy: pavyzdžiai, išbandyti per API](https://madsalt.tech/lt/blog/supabase-rls-policy-examples/).

Viena detalė su slaptuoju raktu: jo įterpta eilutė gavo `user_id = null`, nes už šio rakto `auth.uid()` neturi vartotojo. RLS buvo praleistas, bet numatytoji reikšmė nepadarė to, ką sufleruoja stulpelio pavadinimas.

## Ką viešasis raktas skaitė kiekviename žingsnyje?

![Eilutės, kurias skaitė viešasis raktas, iš 3. Viena Supabase lentelė su 3 eilutėmis, po kiekvieno žingsnio. Nauja lentelė, be grant, RLS off (klaida 42501): 0; Pridėtas grant, RLS off: 3; RLS on, be politikos: 0; RLS on, savų eilučių politikos: 0; Paprastas view virš lentelės: 3; View su security_invoker: 0.](https://madsalt.tech/charts/lt/how-to-enable-rls-in-supabase.svg)

*1 pav. Vietinis Supabase stack (CLI 2.109.1, Postgres 17.6), 2026 m. spalio 28 d.*

Du žingsniai nutekina viską: teisė (grant) be RLS ir paprastas view virš lentelės su teisingomis politikomis. Kiti du skyriai paaiškina abu.

## Ar RLS vis dar reikalingas po spalio 30 d. grant pokyčio?

Taip. Nuo 2026 m. spalio 30 d. Supabase naujoms lentelėms `public` schemoje nebesuteikia automatinių teisių API rolėms, tiek naujuose, tiek esamuose projektuose. Mano vietinis stack jau taip elgiasi. Ką tik sukurta lentelė su išjungtu RLS visoms rolėms, įskaitant slaptąjį raktą, atsakė `42501`, taigi niekas nenutekėjo. Detalės straipsnyje [Supabase spalio 30 d. pokytis: kas sulūš ir kaip patikrinti](https://madsalt.tech/lt/blog/supabase-october-30-grant-change/).

Tačiau teisė sugrįžta, kai tik programai reikia lentelės, ir nuo tada RLS yra vienintelis dalykas tarp viešojo rakto ir visų eilučių. Todėl viską sudėkite į vieną migraciją, šia tvarka:

```sql
create table public.todos (...);
alter table public.todos enable row level security;
create policy "own select" on public.todos ...;
grant select, insert, update, delete on table public.todos to authenticated;
```

Suteikite teisę tik rolėms, kurioms lentelės reikia. Kai iš `anon` atėmiau viską, viešojo rakto select pasikeitė iš `200 []` į `401, 42501`. Teisė yra pirmas užraktas, RLS – antras.

## Kodėl view vis dar nuteka eilutės?

Nes view veikia su savo savininko teisėmis, o Supabase tai yra `postgres`, kuris apeina RLS. Esant savų eilučių politikoms `todos` lentelėje, paprastas `create view public.todos_view as select * from public.todos` grąžino visas 3 eilutes viešajam raktui ir vartotojui B.

Perkūrus `with (security_invoker = true)`, tas pats view viešajam raktui grąžino 0 eilučių, A – 2, B – 1, lygiai kaip lentelė:

```sql
create view public.todos_view with (security_invoker = true) as
  select * from public.todos;
```

Supabase Advisor paprastą rūšį pažymi kaip `security_definer_view`; ką tai reiškia ir kaip taisyti, rasite [Supabase security definer view pastaboje](https://madsalt.tech/lt/notes/supabase-security-definer-view/).

## Kaip automatiškai įjungti RLS kiekvienoje naujoje lentelėje?

Įvykio trigeriu (event trigger). Supabase [event triggers vadove](https://supabase.com/docs/guides/database/postgres/event-triggers) pateikta funkcija `rls_auto_enable()` ir trigeris `ensure_rls`, veikiantis po `create table`, `create table as` ir `select into` `public` schemoje. Įdiegiau jį tokį, koks paskelbtas, ir gavau:

- Vėliau su `create table` sukurta lentelė turėjo RLS įjungtą be jokio `alter`. Viešasis raktas gavo `200 []` per select ir `401` per insert.
- Su `create table as select` sukurta lentelė taip pat turėjo RLS įjungtą.
- Prieš trigerį sukurta lentelė liko išjungta. Trigeris neveikia atgaline data.

Be trigerio antra lentelė, sukurta šalia apsaugotos, turėjo RLS išjungtą, o gavus teisę viešasis raktas ją laisvai skaitė ir rašė. Jis taip pat apima tik `public`; kitoms atvertoms schemoms funkcijoje reikia atskiros eilutės.

## Ar padeda FORCE ROW LEVEL SECURITY?

Ne toms rolėms, dėl kurių nerimaujate. `alter table ... force row level security` priverčia RLS galioti ir lentelės savininkui. Supabase tiek `postgres`, tiek `service_role` turi `BYPASSRLS`, todėl po `force` savininkas vis tiek suskaičiavo 3 eilutes, slaptasis raktas vis tiek matė viską, o `postgres` valdomas view vis tiek nutekino. Tai pakeitė tik savininko rolę, kurią sukūriau be `BYPASSRLS`: 2 eilutės prieš, 0 po.

## Kaip patikrinti savo projektą?

- SQL redaktoriuje išvardykite `public` lenteles su išjungtu RLS:

```sql
select c.relname as table_name
from pg_class c
join pg_namespace n on n.oid = c.relnamespace
where n.nspname = 'public'
  and c.relkind in ('r', 'p')
  and not c.relrowsecurity
order by 1;
```

- Advisor dashboard pateikia tą patį kaip `rls_disabled_in_public`; ką ši klaida reiškia, rasite [RLS disabled in public pastaboje](https://madsalt.tech/lt/notes/supabase-rls-disabled-in-public/).
- Nemokamas [Supabase saugumo patikrinimas](https://madsalt.tech/lt/tools/supabase-security-check/) skaito jūsų projektą tik skaitymo režimu ir išvardija lenteles su išjungtu RLS, kurias API gali pasiekti, vaizdus (views), apeinančius RLS, ir politikas, leidžiančias visiems, kiekvienam su taisymo SQL.
- Skeneris negali žinoti, kurios eilutės kam priklauso. Tam įrodyti siųskite užklausas kaip du vartotojai, kaip aukščiau. Pilnas metodas programai su rolėmis aprašytas straipsnyje [Kaip testuoti Supabase RLS: 30 iš 87 leidimų nieko nedarė](https://madsalt.tech/lt/blog/how-to-test-supabase-rls/).

## Kaip testavau

- Supabase CLI 2.109.1 nešiojamajame kompiuteryje: Postgres 17.6, PostgREST 14.14, Auth 2.192.0. Du vartotojai, prisijungę slaptažodžiu, ir vietiniai publishable bei secret raktai.
- Viena lentelė, `public.todos`, prieš kiekvieną užklausą iš naujo užpildyta tomis pačiomis 3 eilutėmis. Kiekvienas žingsnis pritaikytas kaip SQL, kiekviena užklausa ėjo per REST API, užfiksuojant jos būsenos kodą ir turinį.
- Teisės 2–5 žingsniams pridėtos rankiniu būdu, kad atitiktų projektą, sukurtą prieš 2026 m. spalio 30 d.

**Apribojimai.** Vienas vietinis stack, išgalvoti duomenys, 2026 m. spalio 28 d. Dashboard žingsniai cituojami iš Supabase dokumentacijos, nepraklikinti. Lentelės, sukurtos paties dashboard rolės, gali turėti kitas numatytąsias teises. To netestavau, kaip ir Storage, Realtime ar GraphQL.

Nesate tikri, kad jūsų lentelės užrakintos?

Mielai kartu peržiūrėsiu schemą. Be pardavimo.

[Susisiekti](https://madsalt.tech/lt/#contact)
