>_ Black Engine

SUPABASE_SERVICE_ROLE_KEY expuesta en Lovable: qué hacer

Por Black Engine · 6 de noviembre de 2026

Si tu SUPABASE_SERVICE_ROLE_KEY quedó en el código de tu app de Lovable (en el frontend, en un archivo .env subido a GitHub o pegada en el chat), trátala como robada: esa llave se salta todas las reglas RLS y da acceso total a tu base de datos. Lo que toca es: (1) sacarla del frontend, (2) crear una llave nueva en Supabase, (3) mover tus funciones a la nueva y (4) desactivar la vieja. Borrarla del código no basta.

Las llaves de Supabase, en corto

Según la documentación de llaves de Supabase (noviembre de 2026):

Llave Formato ¿Se salta RLS? ¿Puede ir en el navegador?
Publishable sb_publishable_... No Sí
anon (antigua) JWT largo eyJ... No Sí
Secret sb_secret_... Sí Nunca
service_role (antigua) JWT largo eyJ... Sí Nunca

Supabase anunció que las llaves antiguas anon y service_role se retiran para finales de 2026, y recomienda pasarse a publishable y secret. Las antiguas siguen funcionando hasta que las desactives.

Lovable supabase api key: la llave que tu app de Lovable usa en el frontend debe ser la anon/publishable. Es normal verla en el código. La que no debe aparecer es la service_role/secret.

Cómo saber si tu service_role key está expuesta

En tu app publicada

  1. Abre tu app en Chrome.
  2. F12 → pestaña Sources (Fuentes).
  3. Ctrl+Shift+F (o Cmd+Option+F en Mac) y busca: service_role, sb_secret_, SERVICE_ROLE.
  4. Si usas llaves antiguas, copia cada texto largo que empiece con eyJ y pégalo en un decodificador de JWT local o revisa si en el código está junto a la palabra service_role. Un JWT de service_role contiene "role": "service_role".

En tu repositorio de GitHub

Si conectaste Lovable a GitHub, busca en el repositorio (incluido el historial, no solo la versión actual):

git log -p | grep -iE "service_role|sb_secret_" | head

Un .env que se subió alguna vez sigue en el historial aunque lo hayas borrado después. Más detalle en qué hacer si una API key quedó expuesta.

En variables que empiezan con VITE_

Lovable genera apps con Vite. En Vite, toda variable que empieza con VITE_ termina en el navegador. Si tienes VITE_SUPABASE_SERVICE_ROLE_KEY, está expuesta. Ve variables de entorno en Vite y React.

Qué hacer, paso a paso

1. Arregla la causa primero

Supabase recomienda corregir la fuga antes de rotar, para que la nueva no se filtre igual:

  • Quita la llave del código del frontend.
  • Mueve la lógica que la necesitaba a una Edge Function (código que corre en el servidor de Supabase) y guarda la llave en sus secretos. En Lovable, usa la sección Secrets para valores del servidor; Lovable incluso detecta cuando pegas una llave en el chat y te sugiere guardarla ahí.
  • Pídele a Lovable explícitamente: “No uses la service role key en el frontend; mueve esta operación a una Edge Function”.

2. Crea una llave secreta nueva

En Supabase: Settings → API Keys. Crea una nueva secret key (sb_secret_...).

3. Cambia tus funciones del backend a la nueva llave

Actualiza el secreto en tus Edge Functions u otros servidores que la usen. Prueba que todo funcione.

4. Desactiva o borra la vieja

  • Si la expuesta era una secret key nueva: bórrala (no se puede deshacer).
  • Si era la service_role antigua: desactiva las llaves antiguas en Settings → API Keys. Supabase indica que, en ese caso, también hay que revocar el JWT secret antiguo y migrar a las llaves de firma JWT, porque cualquier cosa que confíe en ese secreto aceptaría la llave filtrada. Sigue la guía oficial Rotate a leaked or compromised API key; cambiar el JWT secret puede cerrar las sesiones de tus usuarios y romper integraciones, así que planéalo.

Si notas que alguien ya está abusando de la llave (datos borrados, usuarios raros), no esperes a migrar todo: desactiva primero y arregla después.

5. Revisa si hubo daño

  • Revisa los logs de Supabase de los días en que la llave estuvo expuesta.
  • Busca usuarios creados que no reconoces, tablas modificadas o borradas, archivos nuevos en Storage.
  • Si había datos personales y hubo acceso indebido, asesórate sobre tus obligaciones de aviso.

Por qué pasa tanto en apps hechas con IA

Cuando una política RLS bloquea algo, la IA a veces “resuelve” usando la llave de administrador en el frontend: el error desaparece y la app funciona. Es el atajo más peligroso posible. Si en tu historial de chat le pediste “arregla el error de permisos” y desde entonces todo funciona, revisa esto primero. Ve también ¿es segura mi app hecha con Lovable?

Cómo evitar que vuelva a pasar

  • La service_role/secret solo en Edge Functions o tu backend.
  • Nunca en variables VITE_.
  • .env en .gitignore desde el día uno.
  • Una llave secreta distinta para cada componente del backend, como recomienda Supabase, para que una fuga solo obligue a cambiar esa.
  • Arregla los errores de permisos con políticas correctas: ejemplos de políticas RLS.

En resumen

La service_role key es la llave maestra de tu base de datos: si estuvo en el frontend o en GitHub, dala por comprometida, mueve la lógica al servidor, crea una llave nueva y desactiva la vieja. Si no sabes dónde la usa tu app o te da miedo romper algo al rotarla, en Black Engine lo revisamos contigo por WhatsApp.

Preguntas frecuentes

¿Qué es la SUPABASE_SERVICE_ROLE_KEY?

Es la llave de administrador de tu proyecto de Supabase. Se salta todas las políticas RLS, así que quien la tenga puede leer, cambiar y borrar cualquier dato.

¿La anon key de Supabase también es peligrosa?

No por sí sola: la llave anon o publishable está pensada para ir en el navegador. Lo que la vuelve peligrosa es tener tablas sin RLS o con políticas abiertas.

¿Dónde debe ir la service_role key en un proyecto de Lovable?

Solo en el backend: en los secretos de las Edge Functions de Supabase o en la sección Secrets de Lovable para funciones del servidor. Nunca en el código del frontend ni en variables VITE_.

¿Borrar la llave del código es suficiente?

No. Si ya estuvo publicada o en GitHub, hay que darla por comprometida y reemplazarla en Supabase. Borrarla del código no la invalida.

Pide ayuda por WhatsApp