Saltar al contenido
← Volver al blog
appsinfraestructura

Row Level Security de Supabase en apps de Lovable y Bolt

Cómo saber si los datos de tu app de Lovable o Bolt en Supabase están abiertos, qué hace Row Level Security y cómo activarlo sin romper la app que ya funciona.

Por Equipo Devonauts7 min de lectura
Read in English →
Una ingeniera sostiene una laptop de pie junto a racks de servidores

Row Level Security (RLS) es el conjunto de reglas dentro de tu base de datos de Supabase que decide qué filas puede leer, crear, cambiar o borrar cada persona. Si una tabla con datos de usuarios tiene RLS desactivado, o tiene una política que deja pasar a todos, cualquiera que abra tu app puede leer esa tabla directamente. Lo puedes comprobar en pocos minutos con el Security Advisor de Supabase y una prueba con dos cuentas, y lo puedes corregir tabla por tabla sin tumbar la app.

Esta guía es para quienes construyeron su app con Lovable o Bolt sobre Supabase y quieren saber si sus datos están protegidos.

¿Por qué RLS importa tanto en apps de Lovable y Bolt?

Las apps hechas así suelen hablar con la base de datos directamente desde el navegador. Para eso, la app lleva dentro la URL de tu proyecto y una clave pública (la clave anon, o publishable en los proyectos más nuevos). Esa clave está pensada para ser pública: cualquiera la encuentra en segundos con las herramientas de desarrollo del navegador.

Eso está bien, y así es como Supabase está diseñado, siempre que RLS haga su trabajo. Con la clave pública, un visitante puede mandar consultas a tu base de datos sin pasar por las pantallas de tu app. Lo único que separa a esa persona de tus datos son las políticas de cada tabla.

La propia documentación de Supabase lo dice sin rodeos: una tabla en un esquema expuesto y sin RLS se puede leer y modificar con cualquier rol que tenga acceso a ella. En un proyecto típico, eso incluye a visitantes que ni siquiera iniciaron sesión.

¿Qué backend usa tu app?

Antes de revisar nada, averigua dónde vive tu base de datos.

  • Lovable con tu propio proyecto de Supabase. El proyecto aparece en tu panel de Supabase y ahí puedes hacer todas las revisiones de esta guía.
  • Lovable Cloud. Lovable administra la instancia de Supabase por ti. No aparece en tu panel de Supabase, así que trabajas desde la vista Cloud de Lovable y su escaneo de seguridad. Lovable hace una revisión de seguridad antes de publicar: lee cada aviso antes de seguir adelante.
  • Bolt con Supabase. Todo lo de esta guía aplica tal cual.
  • Bolt Database. Bolt también puede alojar la base de datos por ti. Revisa su documentación para ver cómo maneja las reglas de acceso. La prueba con dos cuentas de más abajo sirve con cualquier backend.

¿Cómo saber si tus datos están abiertos?

Haz estas cuatro revisiones en orden. Las dos primeras toman un par de minutos.

1. Abre el Security Advisor

En el panel de Supabase, entra en Advisors y luego en Security Advisor. Ahí aparecen problemas como tablas del esquema público con RLS desactivado. Cualquier error sobre RLS en esa lista es urgente.

El Table Editor también marca las tablas que tienen RLS apagado; recorre tus tablas y busca esa etiqueta.

2. Lista tus tablas y políticas

Si te animas a pegar una consulta en el SQL Editor, esta te muestra las tablas del esquema public con RLS desactivado:

select tablename
from pg_tables
where schemaname = 'public' and rowsecurity = false;

Y esta te muestra cada política y lo que permite:

select tablename, policyname, cmd, roles, qual, with_check
from pg_policies
where schemaname = 'public'
order by tablename;

Las dos solo leen información; no cambian nada.

3. Busca políticas que permiten todo

En la segunda lista, fíjate en dos señales:

  • Un qual o with_check igual a true. Eso significa "todo el mundo": está bien para una lista pública de artículos y es un problema serio para pedidos, mensajes o perfiles.
  • Tablas que tienen política para leer (SELECT) pero nada para INSERT, UPDATE o DELETE, o al revés. Cada acción necesita su propia regla.

A veces la IA escribe una política de "permitir todo" para que desaparezca un error. La app vuelve a funcionar y los datos quedan abiertos.

4. Prueba con dos cuentas

Esta es la prueba que más importa, porque comprueba lo que pasa de verdad.

  1. Crea dos cuentas en tu app: usuario A y usuario B.
  2. Con A, crea algo privado: una nota, un pedido, un dato del perfil.
  3. Cierra sesión, entra como B e intenta llegar a lo de A. Cambia un ID en la barra de direcciones o abre la página donde aparecerían los datos de A.
  4. Si B puede ver o editar algo de A, esa tabla hay que arreglarla.

Prueba también la app sin sesión en una ventana de incógnito. Las páginas que piden inicio de sesión no deberían mostrar datos reales, ni siquiera por un segundo.

¿Cómo se arregla RLS sin romper la app?

Activar RLS es una línea. Hacerlo con seguridad pide un poco más de cuidado, porque una tabla con RLS activado y sin políticas no devuelve nada. Tu app no mostrará un error: las listas saldrán vacías y parecerá rota.

Sigue este orden:

  1. Haz un respaldo antes. Confirma que los respaldos de tu plan están funcionando, o saca tu propia copia antes de cambiar nada.
  2. Ve tabla por tabla. Empieza por la más sensible (usuarios, pedidos, pagos, mensajes).
  3. Escribe una política por cada acción que necesitas. Para una tabla donde cada fila pertenece a un usuario y tiene una columna user_id, el patrón habitual es este:
alter table public.notes enable row level security;

create policy "Leer mis notas" on public.notes
  for select to authenticated
  using ( (select auth.uid()) = user_id );

create policy "Crear mis notas" on public.notes
  for insert to authenticated
  with check ( (select auth.uid()) = user_id );

create policy "Editar mis notas" on public.notes
  for update to authenticated
  using ( (select auth.uid()) = user_id )
  with check ( (select auth.uid()) = user_id );

create policy "Borrar mis notas" on public.notes
  for delete to authenticated
  using ( (select auth.uid()) = user_id );

using decide qué filas existentes puede tocar alguien. with check decide cómo puede quedar una fila nueva o modificada, y eso impide que un usuario cree filas a nombre de otro o le pase una fila a otra persona.

  1. Repite la prueba con dos cuentas después de cada tabla.
  2. Agrega un índice en user_id en las tablas grandes. Las políticas se ejecutan en cada consulta, y Supabase recomienda indexar las columnas que usan.

Si tu app es más compleja, con equipos, proyectos compartidos o roles de administrador, las políticas tienen que revisar la pertenencia a una tabla de equipos. Ahí es donde una segunda mirada ayuda.

¿Qué más puede dejar datos expuestos?

RLS en tus tablas es lo principal, pero revisa también esto:

  • La clave secreta en el navegador. La clave service_role (o la nueva clave secreta) se salta RLS por completo. Solo puede vivir en el servidor, en Edge Functions o en tu backend. Si alguna vez apareció en el código del frontend, rótala desde el panel. Nuestra checklist de seguridad para apps hechas con IA explica cómo buscarla.
  • Las vistas. Una vista suele ejecutarse con los permisos de quien la creó, y eso puede saltarse el RLS de las tablas que usa. En versiones recientes de Postgres, crearla con security_invoker = true hace que respete esas reglas.
  • Los buckets de Storage. Los archivos tienen sus propias políticas. Un bucket marcado como público se puede leer con solo tener el enlace.
  • Edge Functions que usan la clave secreta. Tienen que revisar quién las llama, porque RLS no lo hará por ellas.
  • Permisos de administrador solo en la pantalla. Esconder un botón no protege nada si la base de datos acepta la petición.

¿Cómo pedirle a la IA que lo arregle?

Si prefieres que Lovable o Bolt hagan el cambio, sé concreto y pide una explicación primero:

La tabla orders tiene RLS desactivado. Actívalo y agrega políticas para que cada usuario con sesión iniciada solo pueda hacer select, insert, update y delete de las filas donde user_id sea su propio id. No uses true en ninguna política y no cambies otras tablas. Explícame las políticas antes de aplicarlas.

Después, haz tú la prueba con dos cuentas. No te quedes con la palabra de la IA, y si un arreglo hace desaparecer el error dejando pasar a todos, deshazlo.

Respuestas rápidas

¿La clave pública en mi código es una filtración? No. La clave anon o publishable está pensada para ser pública. La que nunca debe llegar al navegador es la secreta o service_role.

Activé RLS y mi app no muestra nada. ¿Qué pasó? RLS está funcionando y todavía ninguna política permite leer. Agrega una política select para los usuarios que corresponda.

¿Las tablas públicas también necesitan RLS? Sí. Actívalo y agrega una política de lectura para todos: así la tabla se puede leer, pero nadie puede escribir en ella desde el navegador.

¿Puedo revisar sin tocar la base de datos? Sí. El Security Advisor y la prueba con dos cuentas no cambian nada.

¿Quieres que alguien lo revise por ti?

Empieza con el chequeo gratis, que mira lo que tu app deja ver desde afuera. Para una revisión completa de tablas, políticas y funciones, nuestra Auditoría de rescate cuesta $299, incluye un informe escrito en 2 días hábiles y te devolvemos el total si no encuentra ningún problema de severidad media o alta. Mira cómo arreglamos apps de Lovable o de Bolt, revisa nuestros precios o escríbenos.

¿Tu app sigue trabada?

Pasa el chequeo gratis con la URL de tu app, o pide la Auditoría de rescate de $299: un ingeniero senior revisa el código y te envía un informe escrito en 2 días hábiles.