Saltar al contenido

Fundamentos de seguridad

Cómo usar secrets en Replit, y qué se publica de todos modos

Cómo usar secrets en Replit: añadir uno, leerlo y arreglar las dos causas del undefined. Y las claves que la herramienta Secrets no puede mantener privadas.

Vlad Tkachenko9 min de lectura
El logotipo de Replit, una flecha hacia un almacén cerrado de valores ocultos y otra hacia la aplicación en marcha que los lee.

En resumen

  • Cómo usar secrets en Replit: abre la herramienta Secrets, añade un nombre y un valor, y lee ese valor en tu código como variable de entorno.
  • Eso mantiene la clave fuera de tus archivos. No la mantiene fuera de tu aplicación publicada, porque lo que lee tu código de navegador queda incrustado en lo que descarga cada visitante.
  • La señal es el nombre. Una variable que empieza por VITE_ o NEXT_PUBLIC_ la puso en el navegador tu herramienta de compilación a propósito.
  • Si un secret aparece vacío en la aplicación publicada, casi siempre es que la versión en marcha se publicó antes de crearlo. Publica otra vez.

En algún momento entre construir tu aplicación y publicarla, Replit te dijo que dejaras de poner tu clave de API en el código. Así que buscaste cómo usar secrets en Replit, moviste la clave a la herramienta Secrets y el aviso desapareció. Luego alguien te dijo que la clave sigue visible en tu aplicación publicada, y las dos cosas parecen ciertas a la vez.

Lo son. Esta es la parte que la mayoría de los consejos sobre esto se dejan fuera: la herramienta Secrets decide dónde se guarda un valor. Tu código decide adónde se lleva. Son dos preguntas distintas, y solo la primera tiene algo que ver con la herramienta.

En Replit esto aprieta más que en ningún otro sitio, porque la mitad de tu aplicación que se ejecuta en la máquina de Replit y la mitad que se ejecuta en el portátil de tu visitante viven en el mismo proyecto, a menudo en archivos contiguos. Nada en el editor traza una línea entre ellas.

Entre el 12 y el 14 de agosto de 2026 pasamos las mismas nueve comprobaciones externas por 30.998 aplicaciones activas, de las cuales 3.042 estaban publicadas en Replit. En 219 de esas aplicaciones de Replit había algo con forma de clave dentro del código que descarga un visitante. En el conjunto de la muestra, la mayor parte de lo que encuentra esa comprobación es una clave de Google, que con restricciones suele estar bien. Las que no están bien son justo las que una herramienta de secrets debía haber evitado. Las cifras completas están en nuestro informe de escaneo.

¿Cómo uso secrets en Replit?

Abre la herramienta Secrets, añade un nombre y un valor, y lee ese valor en tu código como variable de entorno. Lleva alrededor de un minuto.

  1. En tu proyecto, abre Secrets. Está en la lista de herramientas, y buscar la palabra en ese panel lo encuentra.
  2. Elige + New secret. Ponle un nombre en mayúsculas con guiones bajos, como OPENAI_API_KEY. Ese nombre es el que usará tu código, así que importa más de lo que parece.
  3. Pega el valor en el segundo campo y guarda. Replit lo cifra y lo mantiene fuera de los archivos de tu proyecto.
  4. Léelo en tu código. En JavaScript es process.env.OPENAI_API_KEY, y en Python es os.getenv("OPENAI_API_KEY").
  5. Vuelve atrás y borra el valor de donde estuviera antes.

El paso cinco es el que la gente se salta, y del que depende que todo esto haya servido de algo. Crear un secret no elimina la copia que ya tenías. Una clave pegada en un archivo la semana pasada sigue en ese archivo, sigue en el historial de tu proyecto y sigue dentro de cada copia de tu aplicación publicada desde entonces.

Un archivo .env hace el mismo trabajo que la herramienta Secrets, con una diferencia que importa: es un archivo, así que viaja con el proyecto cuando alguien lo bifurca o lo conecta a un repositorio.

¿Son seguros los secrets de Replit?

Para lo que hacen, sí. El valor está cifrado, queda fuera de tu código fuente, y las tres formas más comunes de que a alguien se le escape una clave quedan cerradas con eso: compartes tu proyecto con un colaborador, lo conectas a un repositorio, o alguien te mira trabajar.

Piénsalo como un cajón cerrado con llave. Lo que hay dentro del cajón queda fuera de la vista de cualquiera que lea tus archivos. Lo que el cajón no puede decidir es qué hace tu aplicación con el contenido una vez que tu propio código lo ha abierto y se ha marchado con él.

Y una aplicación de Replit publicada se marcha con bastante. A cada visitante que carga tu sitio se le envía toda la mitad delantera, porque un navegador no puede dibujar una página que no ha recibido. Si el código que abre el cajón es código que se envía a los visitantes, el valor que sacó viaja con él.

¿Qué mitad de tu aplicación lee la clave?

La mitad que se ejecuta en la máquina de Replit puede leer un secret sin peligro. La mitad que se ejecuta en el navegador de tu visitante no puede, y la forma habitual de hacer que funcione es también la forma en que la clave se vuelve pública.

Tu código de servidor es la parte que ejecuta Replit: una ruta de Express, un manejador de Python, una función que habla con OpenAI o con Stripe y le devuelve una respuesta a tu aplicación. Lee un secret, lo usa, y el valor nunca sale de la máquina.

Tu código de navegador es todo lo que ejecuta el portátil de tu visitante. En un proyecto de React es la mayor parte de lo que has estado editando. Se compila en un paquete de JavaScript y lo descarga entero cualquiera que abra tu sitio.

Un cajón, dos lectores. El valor va adonde vaya el código que lo abrió.

process.env no existe en un navegador, así que el código de navegador que lo lee no obtiene nada. Para que el valor llegue, alguien lo renombra: VITE_OPENAI_API_KEY en un proyecto de Vite, o NEXT_PUBLIC_OPENAI_API_KEY en uno de Next.js. Funciona de inmediato, porque ese prefijo es una instrucción a la herramienta de compilación para escribir el valor dentro del paquete. La propia documentación de Vite lo dice con esas palabras y desaconseja poner ahí claves de API por ese mismo motivo.

Así que la comprobación más rápida de este artículo es una búsqueda. Abre tu proyecto y busca VITE_ y NEXT_PUBLIC_. Cada coincidencia es un valor que tu herramienta de compilación tiene orden de publicar.

Para algunos eso es correcto. Una clave publicable de Supabase está diseñada para vivir en un navegador, y una clave de Google Maps con una restricción de referente también. Es incorrecto para todo lo que gasta dinero o lee una base de datos sin preguntar quién llama, y distinguir las dos lleva alrededor de un minuto por clave.

Si prefieres ver qué está repartiendo tu aplicación publicada antes de ir archivo por archivo, nuestro escaneo gratuito lee tu sitio desde fuera y te dice qué encuentra ahí. Tarda unos 20 segundos y no necesita cuenta: escanea tu aplicación.

¿Por qué no funciona mi secret de Replit?

Dos motivos, y desde donde estás producen el mismo síntoma: un valor vacío y una aplicación que no funciona.

El código que lo lee se ejecuta en el navegador. Ahí no hay ningún entorno que leer, así que process.env.TU_CLAVE está vacío y lo seguirá estando. Esto no es un problema de configuración, y volver a crear el secret las veces que haga falta no lo mueve. La llamada que necesita la clave tiene que mudarse a la mitad de servidor de tu aplicación.

Tu aplicación publicada está corriendo una versión anterior. Replit mantiene dos conjuntos de valores, los de tu espacio de trabajo y aquellos con los que corre tu aplicación publicada. Se sincronizan, así que un secret que añadas llega normalmente al despliegue. Lo que la aplicación en marcha usa de verdad, sin embargo, es lo que había la última vez que la publicaste. Añade un secret después y la aplicación en marcha no sabrá nada de él hasta que vuelvas a publicar.

El mismo nombre en los dos sitios. La aplicación en marcha funciona con los valores que había la última vez que publicaste.

La propia guía de Replit para una aplicación que funciona en el editor y se rompe al publicarse empieza exactamente en este punto, así que vale la pena abrir los secrets de despliegue y leer los nombres antes de dar nada por roto. Un nombre escrito OPENAI_KEY en un sitio y OPENAI_API_KEY en el otro produce el mismo valor vacío que un secret que falta.

Un despliegue que falla a medianoche es cuando se toma el atajo. Pegar el valor directamente en el código desbloquea la situación en segundos, la aplicación vuelve, y la clave queda en tu paquete publicado a partir de ese momento.

La clave ya está en mi aplicación publicada. ¿Y ahora?

Rótala, antes de cambiar nada de código. En el panel del proveedor, genera una clave nueva y revoca la vieja.

Ese orden importa porque la rotación es el único paso que hace que el valor expuesto deje de funcionar. Editar tu código lo quita de la versión actual y lo deja en el historial de tu proyecto, y no hace absolutamente nada con las copias de tu paquete que ya se han descargado, cacheado y rastreado. Que tu aplicación sea pequeña tampoco ayuda: los rastreadores automáticos leen sitios públicos buscando cadenas con forma de clave sin parar, sin la menor idea de quién eres.

Después, en este orden:

  1. Pon la clave nueva en Secrets y léela solo desde código de servidor.
  2. Mueve la llamada que la necesitaba. Todo lo que hable con OpenAI, Anthropic, Stripe o con tu base de datos usando una clave administrativa va detrás de una ruta a la que llame tu aplicación, de modo que el navegador le pregunte a tu servidor y tu servidor sea quien guarde la clave.
  3. Revisa las páginas de uso y facturación del proveedor para el periodo en que la clave vieja estuvo pública. La rotación detiene lo que pase a partir de ahora y no dice nada de lo que ya pasó.

Las claves de proveedores de modelos son las primeras que hay que revisar en Replit. OPENAI_API_KEY es el ejemplo al que recurre la propia documentación de Replit cuando te enseña a añadir un secret, y de una clave de OpenAI o Anthropic no existe variante publicable. Cada una de ellas factura directamente a tu cuenta.

Un sitio más donde mirar ya que estás: si tu proyecto publica source maps, un visitante puede leer ese paquete como los archivos originales que escribiste, con tus propios nombres de variables todavía puestos.

Qué hacer esta semana

Qué hacer

  • Mueve todas tus claves a la herramienta Secrets y luego borra las copias que dejaste en archivos. Crear un secret no elimina el valor antiguo.
  • Busca en tu proyecto VITE_ y NEXT_PUBLIC_. Cada coincidencia es un valor que tu herramienta de compilación publica a propósito, y cada uno tiene que ser una clave que se podía publicar.
  • Para cualquiera que no lo sea, mueve la llamada que la usa a tu mitad de servidor, de modo que el navegador le pregunte a tu aplicación y sea tu aplicación la que guarde la clave.
  • Si un secret aparece vacío en la aplicación publicada pero funciona en el editor, publica otra vez y comprueba el nombre en tus secrets de despliegue antes de tocar el código.
  • Rota en el proveedor todo lo que ya haya salido, antes de tocar el código. Después lee la página de facturación de las semanas en que estuvo público.

Haz primero la búsqueda. Lleva un minuto, no necesita instalar nada y te dice cuáles de las claves de tu proyecto ya son públicas. La lista de seguridad de 10 minutos cubre el resto de lo que conviene confirmar en una aplicación recién lanzada, y la guía en lenguaje llano para esta plataforma es ¿es segura tu aplicación de Replit?.

Preguntas frecuentes

¿Son seguros los secrets de Replit?

Para lo que hacen, sí. Replit cifra los valores y los mantiene fuera de tus archivos, así que compartir tu proyecto, conectarlo a un repositorio o retransmitir mientras trabajas ya no entrega la clave a quien esté mirando. Lo que la herramienta no puede decidir es adónde lleva tu aplicación ese valor después. Una clave que lee código ejecutado en la máquina de Replit se queda en Replit. La misma clave leída por código que se ejecuta en el navegador de tu visitante queda incrustada en lo que publicas, y haberla guardado antes en Secrets no cambia nada de eso.

¿Por qué mi secret de Replit sale undefined?

Hay dos causas y desde donde estás se ven iguales. O el código que lo lee se ejecuta en el navegador, donde no hay ningún entorno que leer y process.env no contiene nada, o tu aplicación publicada está corriendo una versión desplegada antes de que crearas el secret. Para lo segundo, publica otra vez: una aplicación en marcha usa los valores que había la última vez que salió.

¿Puedo usar un secret en mi frontend de React en Replit?

Puedes poner un valor ahí, y no será secreto. El código de React se ejecuta en la máquina de tu visitante, así que todo lo que lea tiene que enviarse antes a esa máquina. Las herramientas de compilación lo hacen explícito con un prefijo: Vite solo expone al código del navegador las variables que empiezan por VITE_, y Next.js solo las que empiezan por NEXT_PUBLIC_. Añadir el prefijo es como la gente consigue que una clave funcione en el frontend, y es también el momento en que esa clave se vuelve pública. Las claves publicables van ahí. Todo lo que gasta dinero o lee una base de datos va en el servidor.

¿Tengo que volver a añadir mis secrets al publicar?

Normalmente no, porque los secrets de despliegue se sincronizan con los de tu espacio de trabajo, pero el valor que usa tu aplicación en marcha es el que estaba presente en tu última publicación. Un secret añadido después llega al despliegue en la siguiente. La propia guía de Replit para una aplicación que funciona en el editor y falla al publicarse empieza aquí, así que si algo faltó al desplegar, abre los secrets de despliegue y comprueba que el nombre esté y esté escrito igual.

Pegué una clave de API en un archivo antes de encontrar la herramienta Secrets. ¿Basta con borrar el archivo?

No. Rota primero la clave en el proveedor, que es lo que cierra la puerta de verdad, y después mueve el valor a Secrets. Borrar una línea de código la quita de la versión actual y no del historial de tu proyecto, ni de ninguna copia de tu aplicación publicada que alguien ya tenga. La rotación es el único paso que hace que el valor antiguo deje de funcionar, y suele llevar cerca de un minuto en el panel del proveedor.

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.