---
title: "Enable RLS in Supabase: mida tabel pärast tagastab"
description: "Enable RLS in Supabase armatuurlaualt või SQL-iga, testitud kohalikul stackil: mida avalik võti, kaks kasutajat ja salajane võti iga sammu järel saavad."
url: "https://madsalt.tech/et/blog/how-to-enable-rls-in-supabase/"
author: "Denys Zaichenko"
author_url: "https://madsalt.tech/et/about/"
language: "et"
published: 2026-11-04
---

# Enable RLS in Supabase: mida tabel pärast tagastab

Lühidalt

RLS lülitatakse Supabase'is sisse ühe lausega tabeli kohta, `alter table public.todos enable row level security;`, või armatuurlaua valikuga "Enable RLS". SQL-redaktoris või migratsiooniga loodud tabelid seda vaikimisi ei saa. Kohe pärast sisselülitamist jääb tabel vaikseks, mitte lärmakaks. Minu kohalikul testil said avalik võti ja kaks sisselogitud kasutajat select'ile, update'ile ja delete'ile `200 []` ning ainult insert ebaõnnestus veaga `42501`. Salajane võti nägi ikka kõiki 3 rida. Tavaline vaade (view) tabeli peal andis avalikule võtmele ikka kõik 3 rida. 30. oktoobrist 2026 vajab uus tabel enne mis tahes ligipääsu ka granti, nii et lülitage RLS sisse ja kirjutage poliitikad samas migratsioonis kui grant.

Haldan tasuta [Supabase'i turvakontrolli](https://madsalt.tech/et/tools/supabase-security-check/) ja "RLS disabled" on leid, mida selgitatakse kõige halvemini. Enamik juhendeid ütleb, et pärast RLS-i sisselülitamist "tabel muutub kättesaamatuks". See on lugemise kohta tõsi ja kirjutamise kohta eksitav. Seepärast tegin ühe tabeli kohalikule Supabase'i stackile ja saatsin sellele igat sorti päringuid: avaliku võtmega, kahe sisselogitud kasutajana ja salajase võtmega, pärast iga allolevat sammu.

## Mis on RLS Supabase'is?

RLS (row-level security) on Postgresi funktsioon, mis filtreerib ridu päringu kaupa. Supabase muudab iga `supabase-js` päringu andmebaasipäringuks, mis käivitatakse rollina: `anon` avaliku (anon, publishable) võtme jaoks ja `authenticated` sisselogitud kasutaja jaoks. RLS-iga sees kontrollib Postgres teie poliitikaid iga rea kohta ning tagastab, muudab või kustutab ainult need read, mille mõni poliitika lubab. RLS-ita jõuab iga roll, millel on tabelil grant, igale reale.

Salajane (service role) võti on teistsugune. Selle rollil on `BYPASSRLS`, nii et RLS sellele kunagi ei kehti. Seepärast kuulub see ainult serverisse. Vahe kahe võtme vahel on artiklis [Supabase anon key vs service role key: mida kumbki avab](https://madsalt.tech/et/blog/supabase-anon-key-vs-service-role-key/).

## Kuidas enable RLS in Supabase tehakse?

Kolmel viisil, olenevalt sellest, kuidas tabel tehti:

- **Kui loote tabeli Table Editoris**, jätke "Enable Row Level Security (RLS)" märgituks. Supabase'i [armatuurlaua lähtekoodis](https://github.com/supabase/supabase/commit/33bd798d142183e162c25debcc50c8c711e68f66) on see märgitud "Recommended" ja selle väljalülitamine näitab hoiatust, et tabel on avalikult loetav ja kirjutatav.
- **Olemasoleva tabeli jaoks** ütleb Supabase'i [API turvajuhend](https://supabase.com/docs/guides/api/securing-your-api): minge jaotisse Database, siis Policies ja valige tabelil "Enable RLS".
- **SQL-iga** SQL-redaktoris või migratsioonis:

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

Supabase'i juhend ütleb selgelt, et armatuurlaual loodud tabelitel on RLS vaikimisi sees ning SQL-redaktoris või muu tööriistaga loodud tabelitel mitte. Kui ehitate skeemi migratsioonide või tehisintellekti tööriistaga, kontrollige iga tabelit.

## Mis juhtub kohe pärast RLS-i sisselülitamist?

Miski ei anna viga peale insert'i. Lõin tabeli `public.todos` omanikuveeruga (`user_id uuid default auth.uid()`), andsin sellele API rollidele grandid nii, nagu vanemates projektides, ja lisasin kolm rida: kaks kasutaja A ja ühe kasutaja B oma. Seejärel lülitasin RLS-i sisse ilma poliitikata:

| Päring          | Avalik võti     | Kasutaja A      | Kasutaja B      | Salajane võti     |
| --------------- | --------------- | --------------- | --------------- | ----------------- |
| Select          | 200, 0 rida     | 200, 0 rida     | 200, 0 rida     | 200, 3 rida       |
| Insert oma rida | 401, viga 42501 | 403, viga 42501 | 403, viga 42501 | 201, rida lisatud |
| Update rida     | 200, 0 rida     | 200, 0 rida     | 200, 0 rida     | 200, 1 rida       |
| Delete rida     | 200, 0 rida     | 200, 0 rida     | 200, 0 rida     | 200, 1 rida       |

Insert'i viga kõlab `new row violates row-level security policy`. Update ja delete vastavad `200` ja tühja massiiviga, nii et rakendus, mis ei kontrolli tagastatud ridu, teatab "salvestatud", kuigi midagi ei salvestatud. Lugege oma kirjutatu pärast RLS-i sisselülitamist tagasi või küsige loendust päisega `Prefer: count=exact`.

Enne RLS-i sai avalik võti samade grantidega lugeda kõiki 3 rida, lisada ridu ning muuta või kustutada mis tahes rida. Kasutaja A sai muuta ja kustutada kasutaja B rida ning anda oma read B-le.

## Kuidas tabel uuesti kasutatavaks teha?

Kirjutage poliitika iga operatsiooni kohta. Tavaline oma ridade komplekt:

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

Nendega nägi kasutaja A oma 2 rida ja kasutaja B oma 1. Avalik võti nägi ikka 0. Kui A proovis lisada rea, mille omanik on B, või viia oma rea B-le, oli vastus `403, 42501`. Selle keelduse annab update'i `with check`. Kui A proovis muuta või kustutada B rida, oli vastus `200, 0 rida`. Rohkem mustreid (avalikud profiilid, tiimid, MFA) on artiklis [Supabase RLS policy näited, testitud API kaudu](https://madsalt.tech/et/blog/supabase-rls-policy-examples/).

Üks tähelepanek salajase võtme kohta: rida, mille see lisas, sai `user_id = null`, sest `auth.uid()`-l pole selle võtme taga kasutajat. RLS jäi vahele, kuid vaikeväärtus ei teinud seda, mida veeru nimi vihjab.

## Mida avalik võti iga sammu järel luges?

![Avaliku võtme loetud read, 3-st. Üks Supabase'i tabel 3 reaga, iga sammu järel. Uus tabel, grant puudub, RLS väljas (viga 42501): 0; Grant lisatud, RLS väljas: 3; RLS sees, poliitikat pole: 0; RLS sees, oma ridade poliitikad: 0; Tavaline vaade tabeli peal: 3; Vaade, security_invoker: 0.](https://madsalt.tech/charts/et/how-to-enable-rls-in-supabase.svg)

*Joonis 1. Kohalik Supabase'i stack (CLI 2.109.1, Postgres 17.6), 28. oktoober 2026.*

Kaks sammu lekitavad kõik: grant ilma RLS-ita ja tavaline vaade tabeli peal, millel on korrektsed poliitikad. Järgmised kaks jaotist selgitavad mõlemat.

## Kas RLS-i on pärast 30. oktoobri granti muudatust ikka vaja?

Jah. 30. oktoobrist 2026 ei anna Supabase enam skeemi `public` uutele tabelitele API rollidele automaatseid granteid, nii uutes kui olemasolevates projektides. Minu kohalik stack käitub juba nii. Värskelt loodud tabel RLS-ita vastas igale rollile `42501`, salajane võti kaasa arvatud, nii et miski ei lekkinud. Üksikasjad on artiklis [Supabase 30. oktoobri grantide muudatus: mis läheb katki](https://madsalt.tech/et/blog/supabase-october-30-grant-change/).

Kuid grant tuleb tagasi niipea, kui rakendus tabelit vajab, ja sellest hetkest on RLS ainus asi avaliku võtme ja iga rea vahel. Seega pange kõik ühte migratsiooni, selles järjekorras:

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

Andke grant ainult rollidele, kes tabelit vajavad. Kui võtsin rollilt `anon` kõik tagasi, muutus avaliku võtme select'i vastus `200 []`-st `401, 42501`-ks. Grant on esimene lukk, RLS teine.

## Miks vaade ikka ridu lekitab?

Sest vaade töötab oma omaniku õigustega ja Supabase'is on see `postgres`, mis jätab RLS-i vahele. Kui `todos`-il olid oma ridade poliitikad, tagastas tavaline `create view public.todos_view as select * from public.todos` kõik 3 rida avalikule võtmele ja kasutajale B.

Kui sama vaade loodi uuesti `with (security_invoker = true)`, tagastas see avalikule võtmele 0 rida, A-le 2 ja B-le 1, täpselt nagu tabel:

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

Supabase'i Advisor märgib tavalise vaate koodiga `security_definer_view`; mida see tähendab ja kuidas seda parandada, on märkmes [Supabase security definer view: miks see jätab RLS vahele](https://madsalt.tech/et/notes/supabase-security-definer-view/).

## Kuidas RLS iga uue tabeli jaoks automaatselt sisse lülitada?

Sündmusetriggeriga. Supabase'i [event triggers juhend](https://supabase.com/docs/guides/database/postgres/event-triggers) annab funktsiooni `rls_auto_enable()` ja triggeri `ensure_rls`, mis käivitub pärast lauseid `create table`, `create table as` ja `select into` skeemis `public`. Paigaldasin selle nii, nagu avaldatud, ja sain:

- Hiljem lausega `create table` loodud tabelil oli RLS sees ilma `alter`-ita. Avalik võti sai select'ile `200 []` ja insert'ile `401`.
- Lausega `create table as select` loodud tabelil oli RLS samuti sees.
- Enne triggerit loodud tabel jäi välja. Trigger ei tööta tagasiulatuvalt.

Ilma triggerita oli kaitstud tabeli kõrvale loodud teisel tabelil RLS väljas ja kui sellele anti grant, luges ja kirjutas avalik võti seda vabalt. Trigger katab ka ainult skeemi `public`; teised avaldatud skeemid vajavad funktsioonis oma rida.

## Kas FORCE ROW LEVEL SECURITY aitab?

Mitte rollidele, mille pärast tasub muretseda. `alter table ... force row level security` paneb RLS-i kehtima ka tabeli omanikule. Supabase'is on nii `postgres` kui ka `service_role` rollidel `BYPASSRLS`, nii et pärast `force`-i luges omanik ikka 3 rida, salajane võti nägi ikka kõike ja `postgres`-i omandis vaade lekkis ikka. See muutis midagi ainult minu loodud omanikurolli puhul ilma `BYPASSRLS`-ita: 2 rida enne, 0 pärast.

## Kuidas oma projekti kontrollida?

- Loetlege SQL-redaktoris skeemi `public` tabelid, millel RLS on väljas:

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

- Armatuurlaua Advisor teatab sama koodiga `rls_disabled_in_public`; mida see viga tähendab, on märkmes [Supabase "RLS disabled in public": mida see tähendab](https://madsalt.tech/et/notes/supabase-rls-disabled-in-public/).
- Tasuta [Supabase'i turvakontroll](https://madsalt.tech/et/tools/supabase-security-check/) loeb teie projekti ainult lugemisõigusega ja loetleb tabelid, millel RLS on väljas ja millele API ligi pääseb, RLS-i vahele jätvad vaated ja poliitikad, mis lubavad kõigile, igaühe jaoks parandus-SQL-iga.
- Skanner ei saa teada, millised read kellele kuuluvad. Selle tõestamiseks saatke päringuid kahe kasutajana, nagu ülal. Täielik meetod rollidega rakenduse jaoks on artiklis [Supabase RLS-i testimine: 30 õigust 87-st ei teinud midagi](https://madsalt.tech/et/blog/how-to-test-supabase-rls/).

## Kuidas testisin

- Supabase CLI 2.109.1 sülearvutis: Postgres 17.6, PostgREST 14.14, Auth 2.192.0. Kaks kasutajat logisid sisse parooliga, lisaks kohalikud publishable- ja secret-võtmed.
- Üks tabel, `public.todos`, enne iga päringut samade 3 reaga uuesti täidetud. Iga samm rakendati SQL-ina ja iga päring läks läbi REST API, oleku kood ja sisu salvestatud.
- Sammude 2 kuni 5 grandid lisati käsitsi, et vastata enne 30. oktoobrit 2026 loodud projektile.

**Piirangud.** Üks kohalik stack, väljamõeldud andmed, 28. oktoober 2026. Armatuurlaua sammud on Supabase'i dokumentatsioonist tsiteeritud, mitte läbi klõpsatud. Armatuurlaua enda rolliga loodud tabelitel võivad olla teised vaikegrandid. Seda ma ei testinud, samuti mitte Storage'i, Realtime'i ega GraphQL-i.

Pole kindel, et teie tabelid on lukus?

Vaatan hea meelega koos teiega skeemi üle. Ilma müügijututa.

[Võtke ühendust](https://madsalt.tech/et/#contact)
