Saltar al contenido

Fundamentos de seguridad

Dónde están tus claves API de Supabase: anon, service_role y URL

La URL del proyecto, la clave anon y la clave service_role están en una sola página del panel. Aquí tienes dónde está, y cuál de los cuatro va en tu app.

Vlad Tkachenko10 min de lectura
Un panel de ajustes: una URL y una clave anon a la vista, una clave service_role y un valor JWT ocultos tras puntos.

En resumen

  • Todas las claves de Supabase, service_role incluida, están en una página: abre tu proyecto en el panel y luego Settings → API Keys.
  • Allí hay cuatro valores. La URL del proyecto y la clave publicable van en tu app; la clave secreta y el valor JWT nunca.
  • Esa página te dice qué claves existen. No te dice cuál acabó en tu app, y solo la segunda pregunta puede hacerte daño.

Algo te ha pedido tu clave de Supabase. Una guía de instalación, un hilo de soporte, o una IA a la que le dijiste que arreglara tu app. Abres el panel, encuentras una página con una dirección y dos o tres claves con nombres como anon y service_role, y todas parecen poder ser la respuesta.

O es la otra versión de esto. Alguien abrió tu sitio, pulsó F12 y te dijo que una clave estaba expuesta. Ahora quieres mirar la clave que encontró, y no sabes dónde vive.

La mayoría de las guías empiezan en la página de claves API. Eso da por hecho que ya sabes cuál es tu proyecto de Supabase, y ese es precisamente el paso que un builder hizo por ti y nunca te explicó.

¿Dónde están las claves API de Supabase?

En el panel, dentro de tu proyecto, en Settings → API Keys.

El camino completo: entra en supabase.com, elige tu proyecto de la lista, abre Settings en la barra lateral izquierda y luego API Keys. Casi todas las guías y capturas que encuentres llaman a esa página Settings → API, porque así se llamaba hasta hace poco. Es la misma página y son los mismos valores.

Todo lo que hay en ella es una de dos cosas. Una dirección, que dice dónde vive tu proyecto. O una clave, que decide qué puede hacer una petición una vez llega. La página las lista juntas, en una sola columna, con la misma tipografía.

Nunca configuré Supabase. ¿Cuál es mi proyecto?

Lee la dirección que tu app ya está usando. La respuesta está dentro.

Cada proyecto de Supabase tiene una referencia: una cadena corta y aleatoria que además es la primera parte de la dirección del proyecto, https://yourreference.supabase.co. Tu app envía una petición a esa dirección en cada carga de página, así que la cadena ya está en tu app, y es la misma con la que el panel identifica tu proyecto.

Tres sitios donde encontrarla sin preguntar a nadie:

  • En tu builder. Lovable, Bolt, v0 y los demás muestran el proyecto de Supabase conectado en algún lugar de los ajustes o del panel de integraciones de tu proyecto.
  • En tu navegador. Abre tu app en producción, pulsa F12, ve a la pestaña Network y recarga la página. Las peticiones que salen hacia algo con .supabase.co llevan la referencia en su dirección.
  • En el código fuente de la página, si tu app escribe la dirección en el HTML en lugar de en un archivo de script.

Después entra en supabase.com y compara esa referencia con tu lista de proyectos. Los builders conectan Supabase a través de tu propia cuenta, así que el proyecto suele estar en un panel en el que te registraste una vez y nunca usaste. Una vez dentro de un proyecto la referencia aparece en la barra de direcciones del navegador, y así confirmas que estás en el correcto antes de copiar nada de él.

Las cuatro cosas de esa página

Una dirección y tres claves. Dos van en tu app y dos no salen nunca del panel.

Lo que vesQué esAdónde vaSi se filtra
Project URLLa dirección de tu proyecto, https://yourreference.supabase.co. Dice dónde, nunca quién.En tu appNada. Ya viaja a cada visitante en cada carga de página.
Publishable key sb_publishable_…Nombra el proyecto y no lleva permisos propios. Se llama anon en un proyecto antiguo.En tu appNada por sí sola. Lee exactamente lo que permiten tus reglas de Row Level Security.
Secret key sb_secret_…Lee y escribe cada fila de cada tabla, digan lo que digan tus reglas. Se llama service_role en un proyecto antiguo.Solo servidorCada fila de cada tabla, para quien la haya encontrado.
JWT secretFirma los tokens que dicen quién ha iniciado sesión. Se llama JWT signing keys en un proyecto nuevo.Se queda en SupabaseAlguien puede emitir un token que afirme ser cualquiera de tus usuarios, incluido un administrador.
Cuatro valores, una página. Supabase no traza ninguna línea entre ellos, y la máscara sobre los dos de abajo es la única pista que te da.

Hay un atajo en la propia página. Supabase imprime la URL del proyecto y la clave publicable donde puedes leerlas, y cubre la clave secreta y el valor JWT con puntos hasta que pides verlos. Los dos que tapa son justo los dos que nunca van en tu app.

¿Dónde está la URL de mi proyecto de Supabase?

En dos sitios, y probablemente ya tengas uno delante. El panel la imprime arriba del todo en Settings → API Keys, con la etiqueta Project URL. La barra de direcciones de tu navegador muestra esa misma cadena cada vez que tu app habla con Supabase, con la forma https://yourreference.supabase.co.

En el código lleva uno de tres nombres, y los tres guardan esa misma cadena:

  • VITE_SUPABASE_URL en una app construida con Vite, que cubre la mayoría de lo que producen Lovable y Bolt
  • NEXT_PUBLIC_SUPABASE_URL en una app de Next.js
  • SUPABASE_URL en un servidor, en una edge function o en un script

El trozo del medio, yourreference, es la referencia de tu proyecto. Es la cadena por la que el panel identifica tu proyecto, y la que hay que comparar cuando tienes varios proyectos y ni idea de cuál pertenece a esta app.

Es una dirección más que un secreto, y por eso está a la vista junto a la clave publicable.

¿Dónde está la clave service_role, y qué es SUPABASE_SERVICE_ROLE_KEY?

En la misma página que todo lo demás. Abre Settings → API Keys y busca la fila service_role, o secret en un proyecto creado hace poco. A diferencia de la URL y la clave publicable, su valor queda detrás de un control de revelado hasta que lo pides.

Ese control es la única pista que te da el panel de que esta es distinta, y merece tomarse en serio: Supabase tapa exactamente los valores que nunca deben llegar a un navegador.

SUPABASE_SERVICE_ROLE_KEY es un nombre de variable más que una segunda clave: detrás está el valor que acabas de revelar. Te lo encontrarás en un archivo .env, en los ajustes de entorno de tu hosting, o en los secretos de una edge function. Lo que importa es el prefijo que lleva delante. Una variable llamada VITE_SUPABASE_SERVICE_ROLE_KEY o NEXT_PUBLIC_SUPABASE_SERVICE_ROLE_KEY se compila dentro del JavaScript que descargan tus visitantes, así que la clave es pública en cuanto despliegas. Esos prefijos son instrucciones de publicar, no descuidos.

Donde sí encaja es en una edge function, un manejador de webhooks, una tarea programada o un script de migración: en cualquier sitio donde el código corra en una máquina que controlas y ningún visitante pueda abrir el archivo. Esta es la clave que ignora Row Level Security por completo, así que lee cada fila de cada tabla digan lo que digan tus reglas.

Si no tienes claro que la tuya se quedó en el servidor, nuestro escáner de seguridad web gratis lee tu sitio en vivo desde fuera y nombra las claves que encuentra, en unos 20 segundos.

¿Qué clave necesita mi app?

La URL del proyecto y la clave publicable. Nada más, nunca.

Tu app se ejecuta en el navegador de tus visitantes y habla con Supabase desde ahí, así que esos dos valores viajan a cada visitante por diseño. Eso no es una filtración y nunca lo fue. Lo que impide que un desconocido lea toda tu base de datos con una clave publicable es Row Level Security: las reglas que deciden, fila a fila, quién puede ver qué.

Así que esas reglas son lo que hay que revisar cuando te preocupas, y activarlas no es lo mismo que estar protegido. La versión larga de por qué una clave es segura en público está en qué claves API son seguras en tu frontend.

¿Cómo sé qué clave llevó realmente mi app?

Desde el panel no puedes saberlo. Lista las claves que tiene tu proyecto, no la que acabó dentro de tu app.

Son dos preguntas distintas, y solo la segunda puede hacerte daño. Un proyecto puede tener una página de ajustes completamente normal y aun así tener su clave secreta pegada en un archivo que cualquiera puede abrir. Para responderla hay que leer la clave que está de verdad en la app.

En un proyecto nuevo, lee los primeros caracteres. sb_publishable_ es la que va ahí. sb_secret_ es la que hay que atender hoy.

En un proyecto antiguo, tienes que mirar dentro de la clave. anon y service_role son JWT: tres bloques separados por puntos, y el del medio se descodifica en texto perfectamente legible. Lleva un campo role, y esa sola palabra es toda la diferencia entre las dos. Cómo leerlo.

El panel te enseña qué claves existen. Cuál de ellas llevó tu app es una pregunta que solo tu app puede responder.

Si prefieres no revisar tu app a mano, nuestro escaneo gratuito lee tu sitio en producción desde fuera y nombra las claves que ve, además de si tus tablas responden a un desconocido que pregunta. Tarda unos 20 segundos y no necesita cuenta: escanear tu app.

¿Y si la clave secreta ya está en mi app?

Ocúpate de la clave antes de tocar nada de código, y en Supabase eso puede que no signifique lo que esperas.

El consejo habitual es rotar: generas una clave nueva, revocas la vieja y el valor que se filtró deja de funcionar. Eso sigue valiendo para las claves nuevas. Un proyecto puede tener varias claves sb_secret_ a la vez y revocarlas de una en una, así que sustituir una ya no implica un minuto en el que todo lo que la usaba está roto.

Para el par original no vale en absoluto. Las propias notas de resolución de problemas de Supabase dicen que ya no es posible rotar los antiguos secretos anon, service_role y JWT. Inutilizar una clave service_role antigua que se ha filtrado pasa por crear las claves nuevas, mover tu app y tu código de servidor a ellas, y después desactivar el par viejo. Lo que implica esa migración son unos cuantos pasos en el panel y un valor cambiado en tu app, bastante más llevadero una tarde tranquila que el día en que lo necesitas.

Qué hacer ahora

Qué hacer

  • Abre Settings → API Keys dentro de tu proyecto. Si no encuentras el proyecto, saca la referencia de https://yourreference.supabase.co y compárala con la lista de tu panel.
  • Pon la URL del proyecto y la clave publicable en tu app. Esas dos, y nada más.
  • Lee la clave que tu app llevó de verdad. sb_secret_ al principio, o "role": "service_role" dentro de una antigua, es el hallazgo que hay que atender hoy.
  • Si hay una clave secreta en tu frontend, inutilízala antes de editar nada. En un proyecto antiguo eso significa crear las claves nuevas y desactivar el par viejo, y no hay un solo botón para hacerlo.
  • Mira Row Level Security ya que estás en el panel. Una clave publicable solo es segura gracias a esas reglas, y sin ellas lee toda tu base de datos.

Si prefieres recorrer esto como una lista, la checklist de seguridad de 10 minutos cubre esto y las otras cosas que conviene apagar en una app recién lanzada, y tenemos una guía en lenguaje claro para apps de Supabase.

Preguntas frecuentes

¿Dónde está la clave service_role en Supabase?

En el panel, dentro de tu proyecto, en Settings → API Keys. En un proyecto antiguo aparece con el nombre service_role y está oculta tras un botón para mostrarla; en uno nuevo es una clave secreta que empieza por sb_secret_. Las guías más antiguas llaman a esa misma página Settings → API.

¿Qué aspecto tiene una clave anon de Supabase?

En un proyecto nuevo es una cadena larga que empieza por sb_publishable_. En uno antiguo es un JWT: tres bloques de caracteres separados por puntos, que empiezan por eyJ, y de unos cientos de caracteres en total. La clave service_role tiene exactamente el mismo aspecto, y por eso se confunden.

¿La URL de mi proyecto de Supabase es secreta?

No. Es la dirección a la que tu app envía cada petición, así que viaja a cada visitante por diseño y no existe ninguna versión de tu app en la que esté escondida. Encontrarla no es un hallazgo. Lo que decide si un desconocido puede leer tus datos es Row Level Security, no si conoce tu dirección.

Mi app la construyeron por mí y nunca he abierto Supabase. ¿Cómo entro?

Busca primero la referencia de tu proyecto: la cadena corta y aleatoria que hay en la dirección que tu app ya llama, https://yourreference.supabase.co. Los builders conectan Supabase a través de tu propia cuenta, así que el proyecto suele estar en un panel en el que te registraste una vez y nunca usaste. Entra en supabase.com con esa cuenta y compara la referencia con la lista de proyectos.

¿Puedo rotar una clave service_role filtrada?

Solo si es una de las nuevas claves sb_secret_, de las que puedes tener varias y revocarlas de una en una. Supabase ha dicho que ya no es posible rotar los antiguos secretos anon, service_role y JWT. Inutilizar una clave antigua filtrada pasa por crear las claves nuevas, mover tu app y tu código de servidor a ellas, y después desactivar el par viejo.

¿Qué es SUPABASE_SERVICE_ROLE_KEY?

Es el nombre de variable de entorno con el que tu código guarda la clave secreta, la que aparece como service_role en un proyecto antiguo y como sb_secret_ en uno nuevo. Su sitio es solo la configuración del lado del servidor: una edge function, un manejador de webhooks, una tarea programada. Cualquier cosa con prefijo VITE_ o NEXT_PUBLIC_ se compila dentro del bundle del navegador, así que una clave service_role detrás de uno de esos nombres es pública en cuanto despliegas.

Escrito por

Vlad Tkachenko

Fundador de Reeve

Me paso el día mirando apps creadas con Lovable, Bolt, v0, Cursor y Replit, y la corta lista de errores que aparecen en ellas una y otra vez.

Más sobre el autor

Sigue leyendo

Todos los artículos

¿No sabes cómo está tu propia app?

Haz un escaneo gratuito y obtén una nota clara de la A a la F en unos 20 segundos. Sin cuenta y sin tarjeta.

Analizar mi app gratis

Comprobación externa automatizada, no una auditoría completa. La ausencia de hallazgos no es garantía de seguridad.