RLS en Supabase: qué es y cómo activarlo (tutorial)
RLS en Supabase (Row Level Security, o seguridad a nivel de fila) son las reglas que deciden qué filas de cada tabla puede ver o modificar cada usuario. Es lo que impide que Juan vea los pedidos de María. Importa muchísimo porque en Supabase tu página habla directo con la base de datos usando una llave pública que cualquiera puede ver; sin RLS, esa llave abre toda la tabla.
Supabase RLS explained: la analogía
Imagina un edificio de departamentos:
- La llave pública (anon o publishable) es la puerta de entrada del edificio. Todos la tienen, y está bien.
- RLS son las cerraduras de cada departamento. Con ellas, cada quien solo entra al suyo.
- Sin RLS, pasas la puerta principal y todos los departamentos están abiertos.
- La llave service_role o secret es la llave maestra del conserje: abre todo sin importar las cerraduras. Nunca se le da a un visitante.
Por eso Supabase marca como error grave las tablas sin RLS en el esquema public: “cualquiera con la URL de tu proyecto puede leer, editar y borrar todos los datos de esta tabla” (Supabase, asesor de seguridad).
Por qué las apps hechas con IA fallan aquí
Herramientas como Lovable, Bolt o v0 crean tablas y conectan tu página a Supabase en minutos. Si la IA no crea las políticas, o crea unas demasiado abiertas para “que funcione”, tu app queda expuesta. En mayo de 2025, la vulnerabilidad CVE-2025-48757 mostró que 170 de 1,645 apps de la vitrina de Lovable tenían este problema.
Supabase RLS tutorial: cómo activarlo paso a paso
1. Revisa qué tablas no tienen RLS
En el panel de Supabase: Advisors → Security Advisor. Las tablas sin RLS aparecen como error. También en Table Editor cada tabla muestra si RLS está activo.
O en el SQL Editor:
select schemaname, tablename, rowsecurity
from pg_tables
where schemaname = 'public';
Las que digan false en rowsecurity no tienen RLS.
2. Activa RLS en la tabla
alter table public.pedidos enable row level security;
Ojo: en cuanto lo actives, nadie podrá leer esa tabla desde la app hasta que crees políticas. Es normal. Hazlo primero en un proyecto de prueba si tu app ya tiene usuarios.
3. Crea tu primera política: “cada quien ve lo suyo”
Supongamos que la tabla pedidos tiene una columna user_id con el ID del usuario que creó el pedido:
create policy "Usuarios ven sus propios pedidos"
on public.pedidos for select
to authenticated
using ( (select auth.uid()) = user_id );
Qué dice, en español:
for select: aplica a leer.to authenticated: solo a usuarios que iniciaron sesión.using (...): solo las filas donde eluser_ides el del usuario actual.(select auth.uid()): Supabase recomienda escribirlo así (conselect) porque se calcula una vez por consulta y es más rápido.
4. Política para crear registros
create policy "Usuarios crean sus propios pedidos"
on public.pedidos for insert
to authenticated
with check ( (select auth.uid()) = user_id );
with check revisa la fila nueva: impide que alguien cree un pedido a nombre de otro.
5. Prueba con dos usuarios
Entra con un usuario, crea datos; entra con otro y confirma que no los ve. Si algo falla con el error “new row violates row-level security policy”, lee este error de Supabase explicado.
Más políticas listas para copiar (editar, borrar, administradores, datos públicos) en Supabase RLS: ejemplos de políticas, con el detalle oficial en la guía de RLS de Supabase.
Conceptos clave en una tabla
| Término | Qué es |
|---|---|
| Política (policy) | Una regla que permite una acción (leer, crear, editar, borrar) bajo una condición |
using |
Condición sobre las filas que ya existen |
with check |
Condición sobre las filas nuevas o modificadas |
auth.uid() |
El ID del usuario que hizo la petición |
anon |
Rol de visitantes sin sesión |
authenticated |
Rol de usuarios con sesión iniciada |
Errores comunes
using (true): permite todo a todos. Solo tiene sentido en datos realmente públicos (por ejemplo, un catálogo) y solo para leer.- Activar RLS y no crear políticas: la app deja de mostrar datos.
- Olvidar tablas nuevas: cada tabla que la IA cree después también necesita RLS.
- Vistas (views): una vista puede saltarse RLS. En Postgres 15 o más, créala con
with (security_invoker = true). - Funciones
security definer: corren con permisos del creador y pueden saltarse RLS. - Confiar en ocultar botones: esconder el botón de “borrar” en la pantalla no protege nada; la regla tiene que estar en la base de datos.
- Usar la llave service_role en el frontend: se salta todo. Ve qué hacer si tu service_role key quedó expuesta.
En resumen
RLS son las cerraduras de cada fila de tu base de datos en Supabase; sin ellas, tu llave pública abre todo. Actívalo en cada tabla, crea políticas que limiten a cada usuario a lo suyo y pruébalo con dos cuentas. Si tu app ya tiene usuarios y no estás seguro de que tus políticas estén bien, en Black Engine lo revisamos contigo por WhatsApp.
Preguntas frecuentes
¿Qué significa RLS?
Row Level Security, seguridad a nivel de fila. Son reglas en la base de datos que deciden qué filas de una tabla puede leer, crear, editar o borrar cada usuario.
¿Qué pasa si no activo RLS en Supabase?
Cualquiera con la URL de tu proyecto y la llave pública puede leer, editar y borrar todos los datos de esa tabla. La llave pública está en el código de tu página, así que es fácil de obtener.
Activé RLS y ahora mi app no muestra nada, ¿qué hice mal?
Nada: con RLS activo y sin políticas, nadie puede acceder. Te falta crear las políticas que permiten a cada usuario ver lo suyo.
¿RLS aplica a la llave service_role?
No. La llave service_role (o las nuevas secret keys) se salta RLS por completo. Por eso nunca debe estar en el navegador.