---
title: "Supabase security definer view: kāpēc tas apiet RLS"
description: "Kāpēc Supabase skats atgriež rindas, ko RLS slēpj tā tabulā, ko nozīmē Advisor brīdinājums security_definer_view un kāds viens iestatījums to labo."
url: "https://madsalt.tech/lv/notes/supabase-security-definer-view/"
author: "Denys Zaichenko"
author_url: "https://madsalt.tech/lv/about/"
language: "lv"
published: 2026-11-02
---

# Supabase security definer view: kāpēc tas apiet RLS

Īsumā

Postgres skats darbojas ar sava īpašnieka tiesībām, ja vien tas nav izveidots ar `security_invoker = true`. Supabase īpašnieks parasti ir `postgres`, kas apiet RLS, tāpēc skats virs aizsargātas tabulas atgriež rindas, ko pati tabula slēpj. Manā lokālajā vidē publiskā atslēga no tabulas ieguva 0 rindu, bet no parasta skata virs tās visas 3 no 3; ar `security_invoker = true` skats arī atgrieza 0. Postgres 15 un jaunākā versijā iestatiet to katram skatam atklātā shēmā.

Manai bezmaksas [Supabase drošības pārbaudei](https://madsalt.tech/lv/tools/supabase-security-check/) ir noteikums "Skati, kas apiet RLS", un Supabase Security Advisor to pašu ziņo kā `security_definer_view`. To viegli nepamanīt, jo tabula, no kuras tas noplūst, izskatās aizsargāta.

## Kāpēc Supabase skats apiet RLS?

Skats ir saglabāts vaicājums. Pēc noklusējuma Postgres tabulu tiesības un RLS tajā pārbauda kā skata īpašniekam, nevis kā tam, kas to izsauc. Supabase [RLS ceļvedis](https://supabase.com/docs/guides/database/postgres/row-level-security) to saka tieši: skati pēc noklusējuma apiet RLS, jo parasti tiek veidoti ar lietotāju `postgres`, un skats virs aizsargātas tabulas izsniedz katru rindu, ko tās politikām bija jāatturē.

Data API sniedz skatus kā tabulas. Ja skats ir atklātā shēmā un `anon` vai `authenticated` var no tā veikt `select`, to nolasa arī publiskā atslēga.

## Ko skats atgrieza manā testā?

Lokālā Supabase vidē (CLI 2.109.1, Postgres 17.6, PostgREST 14.14) izveidoju tabulu `orders` ar trim izdomātiem klientiem, ieslēdzu RLS bez politikas un virs tās izveidoju skatu `order_summary` ar `select` tiesībām lomai `anon`. Tad izsaucu abus ar publishable key:

![Viena tabula, trīs veidi, kā to lasīt. Lokāls Supabase, RLS ieslēgts bez politikas, publishable key. Pati tabula: Publishable key → orders, RLS ieslēgts → 0 rindu; Parasts skats virs tās: Publishable key → order_summary skats → 3 no 3 rindām; Skats ar security_invoker: Publishable key → security_invoker skats → 0 rindu.](https://madsalt.tech/charts/lv/supabase-security-definer-view.svg)

*Mana reprodukcija lokālā Supabase vidē, 2026. gada 23. oktobris.*

| Pieprasījums ar publishable key                            | Rezultāts                              |
| ---------------------------------------------------------- | -------------------------------------- |
| `GET /rest/v1/orders` (RLS ieslēgts, politikas nav)        | `[]`                                   |
| `GET /rest/v1/order_summary` (parasts skats)               | visas 3 rindas ar vārdiem un e-pastiem |
| `GET /rest/v1/order_summary` pēc `security_invoker = true` | `[]`                                   |

Tā pati tabula, tā pati atslēga. Atgriezto mainīja tikai skata iestatījums.

## Kā to labot?

Postgres 15 un jaunākā versijā, ko darbina katrs pašreizējais Supabase projekts, liekiet skatam pārbaudīt RLS kā izsaucējam:

```sql
alter view public.order_summary set (security_invoker = true);
```

Jaunam skatam ierakstiet to definīcijā:

```sql
create view public.order_summary
with (security_invoker = true)
as select customer, email, total from public.orders;
```

Tad izsaucējam vajag arī `select` uz pamattabulu, un rindas nosaka tabulas politikas. Ja skatam jāapkopo dati, ko izsaucējs pa rindām neredz, piemēram, publisks skaits, turiet to ārpus atklātās shēmas un sniedziet caur funkciju ar šauru rezultātu.

Lai izvilktu `public` skatus, kas joprojām darbojas ar īpašnieka tiesībām:

```sql
select c.relname as view
from pg_class c join pg_namespace n on n.oid = c.relnamespace
where n.nspname = 'public' and c.relkind = 'v'
  and not coalesce(
    (select bool_or(option = 'security_invoker=true' or option = 'security_invoker=on')
     from unnest(c.reloptions) as option), false);
```

Manā vidē, kur bija viens parasts skats un divi ar `security_invoker = true`, tas atgrieza tikai parasto.

Materializētie skati RLS neatbalsta vispār, tāpēc pārbaude tos API atzīmē atsevišķi, noteikumā "Materializētie skati vai ārējās tabulas API". Kas vēl iet gar politikām, no secret key līdz `SECURITY DEFINER` funkcijām, ir manā [Lovable lietotnes drošības kontrolsarakstā](https://madsalt.tech/lv/blog/lovable-app-security-checklist/), bet kā pierādīt pašas politikas, ir rakstā [kā es testēju Supabase RLS](https://madsalt.tech/lv/blog/how-to-test-supabase-rls/). Politika, kas meklē komandas caur palīgfunkciju bez rekursijas, ir rakstā [Supabase RLS policy piemēri, pārbaudīti caur API](https://madsalt.tech/lv/blog/supabase-rls-policy-examples/). Funkcijai ar `SECURITY DEFINER` vajadzīgs vēl viens iestatījums, fiksēts `search_path`; kāpēc `search_path = public` manā testā nepietika, ir piezīmē [Supabase "function search path mutable": ko tas nozīmē](https://madsalt.tech/lv/notes/supabase-function-search-path-mutable/).
