Ce e RLS și de ce e oprit · Lecția 1 din 11 · 5 minute
Cum funcționează RLS
Supabase îți dă o bază de date Postgres cu un API gata făcut peste ea. Aplicația ta din browser vorbește direct cu acel API, fără niciun server al tău între ele. În arhitectura asta, singurul lucru care stă între un străin și rândurile tale este protecția la nivel de rând, pe scurt RLS. Prima lecție e despre ce e, de fapt, RLS și de ce e piesa centrală a întregului curs.
De ce nu ai un server care să te apere
La o aplicație clasică, browserul cere date de la serverul tău, iar serverul decide ce ai voie să vezi înainte să atingă baza. La Supabase, pasul ăsta lipsește din construcție. Biblioteca de client din browser trimite cereri direct către API-ul bazei, folosind o cheie publică. E rapid și comod, exact motivul pentru care uneltele de vibe coding îl folosesc, dar înseamnă că decizia „ai voie sau nu” nu se mai ia pe un server al tău. Se ia în baza de date.
Aici intră RLS. E o funcție a Postgresului, nu o invenție Supabase. Ea îți permite să spui bazei, la nivel de rând: acest utilizator poate vedea acest rând, acela nu. Fără ea, o bază Supabase publicată e o foaie de calcul pe care oricine cu adresa aplicației o poate deschide întreagă.
Ce face, exact, o politică RLS
RLS nu e un zid în jurul bazei. E o regulă evaluată pe fiecare rând, la fiecare cerere. Când activezi RLS pe un tabel, Postgresul verifică pentru fiecare rând dacă o politică îi dă voie celui care întreabă să îl atingă. Politica e o expresie logică, de exemplu „rândul ăsta îți aparține ție”. Dacă expresia e adevărată, rândul trece. Dacă e falsă, rândul pur și simplu nu există pentru acel utilizator, ca și cum ar fi fost filtrat dintr-un `select`.
Identitatea celui care întreabă vine din token-ul de autentificare, iar în politică o citești cu `auth.uid()`, care îți dă identificatorul utilizatorului logat. De aici, mai tot cursul se învârte în jurul unei singure comparații: `auth.uid() = user_id`. Rândurile în care ea e adevărată sunt ale tale, restul nu.

Cele două stări extreme
Un tabel are, practic, trei situații. Prima: RLS dezactivat. Nu se verifică nimic, deci oricine ajunge la API vede și modifică toate rândurile. Asta e starea periculoasă, și, cum vezi în lecția următoare, e chiar starea implicită în multe cazuri. A doua: RLS activat, dar fără nicio politică. Postgresul refuză totul, pentru că nu are nicio regulă care să lase ceva să treacă. E incomod, aplicația pare stricată, dar e sigur. A treia, cea corectă: RLS activat plus politici care leagă fiecare rând de proprietarul lui.
Refuză implicit, permite explicit
De ce contează atât de mult aici
În scanările la scară pe aplicații construite cu unelte AI, cauza numărul unu a datelor expuse e mereu aceeași: un token public de Supabase fără RLS în spate. UpGuard a analizat în septembrie 2026 circa 300.000 de domenii care foloseau Supabase și a găsit 16.326 de baze cu tabele citibile de oricine, peste jumătate cu indicii de date personale. Nu vorbim despre spargeri, ci despre tabele fără protecția la nivel de rând, lăsate așa. Restul cursului e despre cum să nu fii unul dintre ele.
De reținut
La Supabase, clientul din browser vorbește direct cu baza printr-o cheie publică; nu ai un server care să filtreze cererile în locul tău.
RLS e o funcție Postgres care evaluează, pe fiecare rând și la fiecare cerere, dacă cel care întreabă are voie să îl atingă.
Comparația centrală a cursului e `auth.uid() = user_id`: rândurile pentru care e adevărată sunt ale utilizatorului logat.
Cu RLS activat, poziția de pornire e „nimeni nu are voie la nimic”; tu deschizi explicit prin politici. Fără RLS, e invers și periculos.