seguridad

La clave service_role de Supabase está en el código público

Supabase te da dos llaves. Una es pública y va en el navegador a propósito. La otra, la service_role, se salta todas las reglas de seguridad de tu base de datos y solo debe vivir en un servidor. La segunda ha acabado dentro del código que se descarga cualquiera que visite tu web.

Revisado en agosto de 2026

De paso

Compruébalo en tu app ahora, gratis

Esto no da la cara solo: tu app funciona igual de bien esté abierta o cerrada. La única forma de saberlo es mirar.

Solo leemos lo que tu app ya le entrega a cualquier visitante.

Diagnóstico

Por qué te pasa

Casi nunca es un despiste tonto: es la salida más rápida a un problema real. En algún momento tu app necesitó hacer algo que las políticas de seguridad no le dejaban, saltó un error, y la forma más rápida de que ese error desapareciera fue usar la llave que se salta las políticas. Funcionó. Y como funcionó, se quedó.

También ocurre al copiar. En el panel de Supabase las dos claves están una debajo de la otra, con nombres parecidos y el mismo aspecto de cadena larguísima. Si coges la de abajo en vez de la de arriba, tu app funciona exactamente igual de bien, y ahí está la trampa: no hay ningún síntoma. Nada falla, nada avisa, y el problema puede llevar meses ahí.

Lo que la hace peligrosa es lo que significa técnicamente: no es una contraseña más, es la credencial que Supabase reserva para el servidor precisamente porque ignora todas las políticas que hayas escrito. Da igual lo bien configurada que tengas la seguridad por filas: esta llave pasa por encima de toda ella.

Lo que este error no significa

  • No significa que te hayan entrado. Que una llave esté accesible no quiere decir que alguien la haya usado, y en la mayoría de los casos que vemos no la ha usado nadie. Pero eso no se supone: se comprueba en los registros de acceso de tu proyecto, y es parte del arreglo.
  • No tiene nada que ver con la anon key. Esa otra clave que también ves en tu código está diseñada para ser pública y por sí sola no da acceso a nada. Si alguien te dice que tener la anon key a la vista es una brecha, no sabe de lo que habla.
  • No se arregla borrando la línea y desplegando. La clave ya ha estado publicada: hay que darla por comprometida y sustituirla, porque cualquiera que la copiara en su momento la sigue teniendo aunque tú la quites de la web hoy.

Solución

Arréglalo tú, gratis

Aquí el orden importa más que la prisa, y es la razón por la que mucha gente empeora las cosas: si revocas la clave antes de tener el reemplazo colocado, tu app se cae; si despliegas antes de revocar, la clave sigue siendo válida un rato más. Este es el orden que no rompe nada.

  1. 01Primero mira, no toques. En Supabase, entra en Logs y revisa la actividad de la API de los últimos días buscando picos raros o consultas desde sitios que no reconoces. Esto se hace antes de nada, porque algunos de los pasos siguientes generan ruido en esos mismos registros.
  2. 02Averigua si esa clave la está usando algo legítimo en un servidor tuyo, aparte del navegador. Si la usa alguna función o algún proceso de fondo, tendrás que actualizarlos a la vez o se caerán con el resto.
  3. 03En Project Settings y luego API Keys, genera una clave de servicio nueva sin borrar todavía la vieja, si tu proyecto te permite tener las dos a la vez. Coloca la nueva en las variables de entorno de tu servidor, sin ningún prefijo de los que publican al navegador.
  4. 04Ahora sí: quita la clave del código del navegador y despliega. Comprueba que la app sigue funcionando; si algo deja de funcionar aquí, ese algo era precisamente lo que se estaba saltando la seguridad y hay que resolverlo con una política, no devolviendo la llave al navegador.
  5. 05Revoca la clave antigua en Supabase. Desde este momento, la copia que tuviera cualquiera deja de servir.
  6. 06Vuelve a Logs y comprueba que no hay actividad nueva rechazada que venga de la clave vieja. Si la hay, no es una anécdota: alguien la tenía.

Si tu proyecto usa el sistema antiguo de claves y no te deja tener dos activas a la vez, el orden cambia: hay que preparar el despliegue de antemano y rotar y desplegar casi seguidos, asumiendo unos minutos de caída. Ese es el caso en el que más gente se atasca.

Y esto para la parte de código

Pégaselo tal cual al agente que escribió tu app. Está redactado para que te diga lo que ha hecho, no solo para que lo haga.

Prompt para tu agente

En mi app ha acabado publicada la clave service_role de Supabase en el código que llega al navegador.

Necesito que hagas esto, y en este orden:
1. Búscala en todo el proyecto y dime en qué ficheros aparece y con qué nombre de variable, sin pegarme la clave entera en la respuesta.
2. Por cada uso, explícame qué está haciendo ahí y por qué hacía falta saltarse las políticas de seguridad. Esto es lo importante: quiero entender qué operación no funcionaba con la clave pública.
3. Propón para cada uno de esos usos una alternativa que no necesite la llave maestra en el navegador: o una política de seguridad por filas que permita esa operación concreta, o mover esa operación a una función de servidor.
4. Deja el código preparado para leer la clave nueva desde una variable de entorno de servidor, sin prefijo VITE_ ni NEXT_PUBLIC_ bajo ningún concepto.

No revoques ni cambies ninguna clave tú, y no me digas que basta con borrar la línea: la clave ya es pública y la rotación la hago yo en el panel, en un orden concreto.

Si no sale

Si el escáner ha encontrado algo, no lo toques con prisa

Cerrar una puerta abierta tiene un orden: primero se corta el acceso, después se comprueba en los registros si alguien entró, y solo entonces se despliega. Hacerlo al revés deja la app caída y borra el rastro de lo que pasó. Si prefieres no hacerlo solo, elige cuándo lo hacemos.

Las 10 primeras apps son gratis. Estoy empezando y necesito casos reales. A cambio te pido permiso para contar después qué me encontré, sin decir de quién era la app ni enseñar tus datos. Sin tarjeta y sin suscripción: cuando se acaben las plazas empezaré a cobrar y lo diré aquí.

Cita a partir de mañana

Agendar revisión

Gratis

durante el lanzamiento

Elegimos hueco, miro tu app con calma y te digo qué pasa y cómo se arregla.

  • Sesión de trabajo en directo contigo
  • Diagnóstico del error y del riesgo real
  • Te quedas con el arreglo aplicado

Hoy, en cola prioritaria

Rescate exprés

Gratis

durante el lanzamiento

Entras en la cola de hoy. Reservas hueco y lo dejamos resuelto en el día.

  • Hueco el mismo día
  • Prioridad sobre las revisiones agendadas
  • Mismo trabajo, antes

Quién

Marc Sala

IT Manager

  • Analista de ciberseguridad certificado por Google

No es un rating anónimo de un marketplace: es la persona que va a entrar en tu app. Reviso el código, encuentro qué falla y lo arreglo contigo delante, explicándote qué ha pasado sin jerga.