>_ Black Engine

Supabase "RLS disabled in public": qué es y cómo arreglarlo

Por Black Engine · 6 de noviembre de 2026

El aviso “RLS disabled in public” de Supabase (en el asesor de seguridad aparece con el código rls_disabled_in_public y el título “Table publicly accessible”) significa que una tabla del esquema public no tiene Row Level Security activado. En palabras de Supabase: “cualquiera con la URL de tu proyecto puede leer, editar y borrar todos los datos de esta tabla”. Se arregla activando RLS y creando políticas, en ese orden y al mismo tiempo, para no romper tu app.

Fuente: lint 0013_rls_disabled_in_public en la documentación de Supabase, consultada en noviembre de 2026.

Por qué es grave

Supabase expone tus tablas del esquema public a internet a través de su API para que tu página pueda leerlas. Para usar esa API se necesita:

  1. La URL del proyecto (https://xxxx.supabase.co), que está en el código de tu página.
  2. La llave pública (anon o publishable), que también está en el código de tu página, y es normal que esté ahí.

Lo único que protege tus datos es RLS. Sin él, esas dos cosas, que cualquiera puede ver con F12 en tu página, bastan para descargar o borrar la tabla completa. Si no tienes claro el concepto, empieza por qué es RLS en Supabase.

Cómo arreglar “RLS disabled” paso a paso

1. Haz una lista de las tablas afectadas

En Supabase: Advisors → Security Advisor. O en el SQL Editor:

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

2. Para cada tabla, decide quién debe acceder

Contesta antes de tocar nada:

  • ¿Es pública (catálogo de productos, horarios)? → cualquiera puede leer, nadie puede escribir desde la app.
  • ¿Es de cada usuario (perfiles, pedidos, mensajes)? → cada quien solo lo suyo.
  • ¿Es interna (registros, configuración, tablas que solo usa tu backend)? → nadie desde la app.

3. Activa RLS y crea las políticas en el mismo bloque

Hazlo en una transacción para que no haya un momento en que tu app se quede sin acceso. Ejemplo para una tabla de usuarios (pedidos con columna user_id):

begin;

alter table public.pedidos enable row level security;

create policy "Ver mis pedidos"
on public.pedidos for select
to authenticated
using ( (select auth.uid()) = user_id );

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

commit;

Ejemplo para una tabla pública de solo lectura (productos):

begin;
alter table public.productos enable row level security;

create policy "Catálogo visible para todos"
on public.productos for select
to anon, authenticated
using ( true );
commit;

Aquí using (true) está bien porque solo es para leer y los datos son públicos. Nadie puede insertar, editar ni borrar porque no hay políticas para eso.

Para una tabla interna que solo usa tu backend: activa RLS y no crees políticas. Tu backend usará la llave secreta, que se salta RLS.

Más casos (editar, borrar, administradores, equipos) en Supabase RLS: ejemplos de políticas.

4. Prueba la app

  • Entra con un usuario normal y revisa que todo lo que debe funcionar funcione.
  • Entra con otro usuario y confirma que no ve lo del primero.
  • Si algo falla al guardar, probablemente verás el error “new row violates row-level security policy”; lo explicamos en este artículo.

5. Vuelve a correr el Security Advisor

Debe desaparecer el error de esas tablas. Revisa también los otros avisos.

La otra opción: no exponer la tabla

Supabase menciona una alternativa: si la tabla no necesita ser accesible desde la API, puedes quitar su esquema de los “Exposed schemas” en la configuración de la API, o moverla a otro esquema que no esté expuesto. Útil para tablas que solo usa tu backend. No quites public si tu app lo usa, porque la romperías.

Supabase RLS disabled: casos comunes en apps hechas con IA

  • La IA creó tablas nuevas después. Le pediste una función nueva, creó una tabla y no le puso RLS. Revisa cada vez que agregues algo.
  • RLS estaba activo y “alguien” lo apagó para arreglar un error. Si en tu historial de chat con Lovable, Bolt o Cursor aparece disable row level security, revisa.
  • Tablas de prueba (test, temp, backup_usuarios) con copias de datos reales. Bórralas o protégelas.
  • Tablas de unión (por ejemplo usuarios_proyectos) que nadie piensa que son sensibles, pero dicen quién tiene acceso a qué.

Qué revisar si la tabla ya estuvo expuesta

Si la tabla tenía datos reales y estuvo sin RLS:

  1. Arregla primero (pasos de arriba).
  2. Revisa los logs de la API en Supabase (sección de Logs) para ver peticiones raras: muchas lecturas, borrados o accesos desde lugares inesperados.
  3. Revisa si faltan o cambiaron datos; ten un respaldo para comparar.
  4. Si había datos personales, consulta con un abogado tus obligaciones de aviso bajo la ley mexicana de protección de datos.

“Activé RLS y mi app dejó de mostrar datos”

Es lo que más asusta y es normal. Con RLS activado y sin políticas, Supabase niega todo por defecto desde la API: la tabla no se rompe, simplemente nadie con la llave pública puede leerla ni escribirla. Por eso en el paso 3 activamos RLS y creamos las políticas en el mismo bloque.

Si ya activaste RLS por separado y tu app quedó vacía:

  1. No lo apagues de nuevo. Esa es justo la reacción que deja la tabla abierta.
  2. Revisa en Authentication → Policies (o en la vista de la tabla) qué políticas tiene; probablemente ninguna.
  3. Crea la política que corresponda según el tipo de tabla (pública, de cada usuario o interna).
  4. Recarga la app con sesión iniciada y prueba otra vez.

Si la tabla sigue sin mostrar datos, revisa que la columna de la política (por ejemplo user_id) realmente tenga el ID del usuario en cada fila. Las filas viejas creadas antes del login a veces tienen esa columna vacía.

Cómo evitar que vuelva a aparecer

  • Pídeselo a la IA de forma explícita. Agrega a tus instrucciones del proyecto algo como: “Toda tabla nueva en public debe tener RLS activado y políticas para cada operación que use la app”.
  • Revisa el Security Advisor cada vez que agregues una función que cree tablas, no solo una vez.
  • Guarda los cambios de base de datos como migraciones y revisa que cada create table venga con su enable row level security. Si usas Lovable, ve cómo manejar migraciones de Supabase en Lovable.
  • Haz una revisión completa antes de lanzar con usuarios reales; la checklist de seguridad para apps hechas con IA cubre también llaves, accesos y respaldos.

En resumen

“RLS disabled in public” significa que la tabla está abierta a cualquiera; se arregla activando RLS y creando las políticas al mismo tiempo, según quién debe ver qué. No lo pospongas. Si tienes muchas tablas, no sabes qué política le toca a cada una o te da miedo romper tu app en producción, en Black Engine lo revisamos contigo por WhatsApp.

Preguntas frecuentes

¿Qué significa 'RLS disabled in public' en Supabase?

Que una tabla del esquema public no tiene activado Row Level Security. Supabase lo marca como error porque cualquiera con la URL del proyecto y la llave pública puede leer, editar y borrar sus datos.

¿Es urgente arreglarlo?

Sí, si la tabla tiene datos reales. La llave pública viene en el código de tu página, así que cualquiera puede usarla contra esa tabla.

Si activo RLS, ¿se rompe mi app?

Al activarlo sin políticas, la app deja de poder leer y escribir en esa tabla. Por eso hay que crear las políticas en el mismo paso.

¿Puedo simplemente ignorar el aviso si mi tabla no tiene nada importante?

Solo si no hay datos sensibles y nadie debería poder modificarla. Aun así, cualquiera podría borrar o llenar la tabla de basura; mejor activar RLS.

Pide ayuda por WhatsApp