API key y tokens en código generado por IA: riesgos y controles antes del despliegue

API key, tokens y secretos en código generado por IA: el riesgo más subestimado

Un asistente de IA puede escribir en pocos minutos código que se conecta a bases de datos, API de pago, buckets en la nube, repositorios, sistemas SaaS, servicios de correo electrónico y entornos de despliegue. Sin embargo, para que todo funcione de inmediato, el camino más corto suele pasar por una clave pegada en un archivo, una variable impresa en los registros (logs), un .env creado al vuelo o un token copiado en el chat durante la depuración.

El riesgo de los secretos en el código generado por IA no se limita al clásico hardcoding. Las API keys, tokens, cadenas de conexión y credenciales pueden terminar en prompts, historiales de chat, incidencias (issues), registros de compilación (build logs), artefactos, mapas de origen (source maps), imágenes de contenedores, pruebas, archivos README, archivos temporales, configuraciones locales y espacios de trabajo remotos utilizados por los agentes. El repositorio puede parecer limpio mientras una clave permanece expuesta en otro lugar.

Para desarrolladores, fundadores técnicos y equipos DevOps, la pregunta concreta antes del despliegue es: ¿qué secretos ha visto la IA, dónde se han guardado, cuáles han llegado al repositorio, cuáles han terminado en las canalizaciones (pipelines) y cuáles deben rotarse antes de que la aplicación acceda a datos reales o servicios de producción?

[Callforaction-WAPT]

Por qué los agentes de IA aumentan el riesgo sobre los secretos

Las herramientas de codificación por IA trabajan dentro de un contexto más amplio que el de un solo archivo: pueden leer porciones del repositorio, generar archivos de configuración, proponer scripts, modificar pruebas, ejecutar comandos, explicar errores y ayudar a conectar servicios externos. En muchos flujos de trabajo, especialmente con el modo agente, terminal o entornos remotos, el asistente no se limita a sugerir código, sino que participa activamente en el proceso operativo.

Esto crea una nueva superficie de ataque para los secretos. Durante una sesión de depuración, un desarrollador puede pegar una cadena de conexión para preguntar por qué la base de datos no responde; el agente puede crear un .env.local para que pase una prueba; un comando puede imprimir variables de entorno en los registros; una compilación puede incluir una clave en el paquete del frontend. La velocidad hace que el problema sea menos visible: cuando el código finalmente funciona, el equipo tiende a centrarse en la funcionalidad, pero una clave expuesta puede dar acceso a pagos, nube, bases de datos, repositorios, servicios SaaS, sistemas de producción o datos de clientes.

Qué cuenta como secreto

Un secreto no es solo una contraseña. En un proyecto moderno, el perímetro incluye API keys, tokens OAuth, tokens de acceso personal, secretos JWT, secretos de webhook, claves privadas, certificados, archivos .pem, cuentas de servicio, URL de bases de datos, cadenas de conexión, cookies de sesión, tokens de actualización (refresh tokens), tokens de despliegue, claves de firma, tokens de GitHub o GitLab, credenciales en la nube, contraseñas SMTP, tokens de Slack, claves de Stripe y claves de proveedores de LLM.

Algunas claves parecen “públicas” porque se usan en el frontend o en la documentación del proveedor, pero incluso en esos casos se deben comprender las restricciones, el alcance (scope) y las posibilidades de abuso. Una anon key de Supabase no es lo mismo que una service role key, y un token de prueba puede, aun así, leer datos de staging, enviar correos, consumir crédito o abrir una ruta hacia sistemas internos.

Antes de publicar, cada secreto debería tener al menos cuatro datos: para qué sirve, en qué entorno es válido, qué privilegios concede y dónde está almacenado. Si una clave no tiene un propietario, una fecha de caducidad o un alcance claro, resulta difícil decidir qué hacer cuando aparece en un diff generado por la IA.

Dónde terminan los secretos durante el “vibe coding”

El primer lugar para verificar es el código mismo: fuentes, configuraciones, pruebas, scripts, ejemplos y archivos generados. Los agentes pueden insertar valores reales en config.ts, settings.py, docker-compose.yml, flujos de CI/CD, migraciones, seeds, fixtures, scripts de despliegue o archivos de prueba, transformando un ejemplo temporal en una configuración que llega al commit.

El segundo lugar es el repositorio alrededor del código: archivos .env en sus diversas variantes, copias de seguridad, archivos .pem, claves descargadas de proveedores en la nube, credenciales de CLI, carpetas ocultas de la herramienta, salidas de depuración y archivos temporales. Un .gitignore incompleto es suficiente para transformar un atajo local en una filtración permanente en el historial de Git.

El tercer lugar, a menudo el más subestimado, está fuera del repositorio: prompts, chats, tickets, incidencias, comentarios de PR, registros de CI/CD, artefactos, imágenes de contenedores, mapas de origen, informes de pruebas, capturas de pantalla, reportes de errores y sistemas de observabilidad. Borrar una clave de un archivo no elimina la clave del chat donde se pegó o del registro donde se imprimió.

Hardcoding: cuando el código funciona de inmediato pero expone demasiado

El patrón más simple es también el más frecuente: para conectar un servicio, la IA sugiere una clave directamente en el código o en un ejemplo copiable. En una demo local parece inofensivo, pero en una PR, en un repositorio compartido o en un despliegue automático se convierte en un acceso real. Los casos más comunes incluyen URL de bases de datos en archivos del lado del servidor, tokens de API en funciones de integración, claves de pago en pruebas, contraseñas SMTP en configuraciones, secretos JWT codificados, secretos de webhook copiados en controladores y claves de servicio usadas para eludir un problema de autorización.

La corrección no es solo “mover a una variable de entorno”. La variable debe gestionarse en un gestor de secretos o en el sistema de despliegue con los permisos correctos, separada por entorno, no impresa en los registros y no accesible al frontend. Si la clave ha sido confirmada (commiteada) o compartida, debe rotarse.

Archivos .env, archivos de exclusión y configuraciones locales

Los archivos .env son útiles para el desarrollo, pero se vuelven riesgosos cuando la IA los crea o modifica sin una convención clara. Un agente puede generar un .env.example con valores reales, sugerir un .env.production para simplificar el despliegue o insertar un archivo de credenciales en el proyecto porque un SDK lo requiere.

Es importante controlar .gitignore, .dockerignore, los archivos de exclusión de la herramienta de IA y los utilizados por el IDE o el agente, porque en algunos flujos de trabajo es necesario impedir que carpetas locales, archivos .env, claves privadas, salidas de compilación o directorios de configuración entren en el contexto del asistente. El objetivo no es solo evitar el commit: es reducir lo que el agente puede leer y reutilizar.

Un buen patrón es mantener .env.example con nombres de variables y valores ficticios, documentar dónde obtener las claves reales y usar gestores de secretos o configuraciones protegidas de la plataforma para staging y producción. Cada archivo con valores reales debería permanecer fuera del repositorio y fuera de los prompts.

Prompts, chats y el historial del agente

Muchas filtraciones no nacen del código, sino de la conversación. Durante la depuración es fácil pegar un error completo con cabeceras, tokens, URL firmadas, cargas útiles (payloads), cadenas de conexión o capturas de pantalla de paneles: el asistente responde, el chat permanece guardado y el equipo olvida que ese secreto salió del perímetro del proyecto.

La regla operativa es simple: no pegues secretos en los prompts. Cuando pidas ayuda sobre un error, basta con sustituir los tokens y claves por marcadores de posición (placeholders), usar datos sintéticos y reducir las cargas útiles al mínimo. Si una clave real ya se ha compartido en el chat, debe tratarse como expuesta: es necesario verificar el proveedor, rotarla y comprobar si hubo accesos anómalos.

El modo privacidad, los planes empresariales o las configuraciones de retención pueden reducir algunos riesgos, pero no convierten un secreto pegado en el chat en una buena práctica. Incluso cuando el dato no se utiliza para el entrenamiento, puede permanecer en el historial, registros, exportaciones, sistemas de soporte o contexto operativo de la herramienta según la configuración del servicio.

Registros de compilación, pruebas y despliegue

Los scripts generados por la IA pueden imprimir demasiado. Un console.log(config), un printenv, un error de inicialización, una prueba fallida o un comando de depuración pueden exponer variables de entorno en los registros de CI/CD, que a menudo son visibles para más personas que el repositorio, se conservan durante semanas o se copian en artefactos.

Vale la pena revisar los flujos de trabajo de GitHub Actions, GitLab CI, Vercel, Netlify, Replit, Docker build, scripts npm, ejecutores de pruebas y sistemas de despliegue, buscando salidas que muestren configuraciones, cabeceras, tokens, URL completos, cadenas de conexión o cargas útiles. También es importante verificar el enmascaramiento de secretos, ya que no todos los tokens personalizados se enmascaran automáticamente y algunas transformaciones pueden eludir las protecciones. Cada modificación en la compilación, pruebas y despliegue debería revisarse como parte de la seguridad de los secretos, incluso cuando la IA interviene solo para “ayudar en la depuración”.

Artefactos, paquetes frontend y mapas de origen

Un secreto puede salir incluso después de la compilación. Si se utiliza una variable privada en el código del lado del cliente, puede terminar en el paquete JavaScript; si los mapas de origen (source maps) son públicos, pueden revelar detalles que el equipo pensaba que permanecían internos; si una imagen de contenedor incluye archivos .env o credenciales en capas anteriores, eliminarlos en un paso posterior puede no ser suficiente.

Este paso es especialmente importante para aplicaciones generadas con v0, Lovable, Bolt.new, Replit Agent u otras herramientas que conectan rápidamente frontend, API y despliegue. En el frontend es necesario distinguir con precisión entre variables públicas y privadas: prefijos como NEXT_PUBLIC_ o equivalentes hacen que una variable esté disponible para el navegador, por lo que si la IA mueve una clave privada a una variable pública para resolver un error, el despliegue puede exponerla a cualquiera que abra las herramientas de desarrollo (DevTools).

Agentes con terminal, sistema de archivos y MCP

Cuando un agente puede leer archivos, ejecutar comandos o usar herramientas externas, el riesgo cambia de naturaleza. El problema no es que el agente “quiera” robar secretos, sino que el contexto operativo puede incluir archivos y salidas sensibles: un comando puede leer .env, una herramienta MCP puede acceder a repositorios o tickets, una sesión remota puede contener credenciales de entorno.

Antes de dar a un agente acceso operativo, es útil separar los secretos de tiempo de ejecución del espacio de trabajo de desarrollo, utilizando entornos dedicados, credenciales con el mínimo alcance, archivos de exclusión, aprobación para comandos sensibles y cuentas de servicio no reutilizadas en producción. Para MCP y herramientas externas, es necesario mapear qué sistemas pueden ser leídos o modificados —repositorios, gestores de incidencias, bases de datos, nube, almacenamiento de archivos, CI/CD, gestores de secretos— porque si una herramienta puede acceder a un secreto, ese secreto debe ser gobernado como parte del perímetro del agente.

Repositorio privado no significa secreto protegido

Un repositorio privado reduce la exposición, pero no es un gestor de secretos. Las credenciales en el código pueden ser leídas por colaboradores, forks internos, CI/CD, herramientas de análisis, aplicaciones instaladas, copias de seguridad, espejos, agentes y cuentas comprometidas. Si el repositorio se vuelve público por error o se comparte con un proveedor, los secretos en el historial se vuelven inmediatamente críticos.

El problema del historial de Git es particularmente relevante: aunque se elimine la clave del último commit, puede permanecer en commits anteriores, ramas, etiquetas, solicitudes de extracción (pull requests), caché o forks. Reescribir el historial puede reducir la visibilidad, pero no garantiza que nadie haya leído ya el secreto, por lo que la rotación sigue siendo necesaria. Antes de abrir un repositorio a nuevos colaboradores, publicar una plantilla, compartir una demo o conectar agentes externos, es indispensable realizar un escaneo en el historial, ramas y etiquetas, no solo en el árbol de trabajo (working tree).

Escaneo de secretos: necesario, no suficiente

El escaneo de secretos y la protección de inserción (push protection) son controles fundamentales que bloquean muchos errores antes de que lleguen al repositorio remoto y ayudan a detectar claves conocidas ya presentes en la base de código. GitHub, los proveedores de nube y diversas herramientas de seguridad ofrecen controles útiles sobre patrones reconocidos.

El límite es que no todo secreto tiene una firma conocida: tokens internos, cadenas personalizadas, credenciales fragmentadas, secretos compuestos, valores codificados, archivos propietarios o claves generadas por sistemas corporativos pueden escapar a los escáneres estándar. Incluso un token real pero caducado puede señalar un problema de proceso, porque si llegó allí una vez, puede volver a suceder. Para proyectos generados por IA, la estrategia más sólida combina escáneres automáticos, patrones personalizados, revisión manual y controles sobre las salidas: un escáner limpio es una buena señal, no una prueba definitiva.

Rotación: cuando borrar no es suficiente

Si una clave ha sido expuesta, la pregunta no es “¿la hemos eliminado?”, sino “¿sigue siendo válida?”. Un secreto confirmado, impreso en un registro, pegado en un chat, incluido en un artefacto o compartido en un ticket debe considerarse comprometido hasta que sea rotado o revocado.

La rotación debe seguir una secuencia ordenada: identificar el servicio, comprender los privilegios y consumidores, crear una nueva clave, actualizar entornos y canalizaciones, verificar que la aplicación funcione, revocar la clave antigua y comprobar los registros de acceso en busca de uso anómalo. En sistemas críticos también es necesario verificar si el secreto daba acceso a datos de clientes, pagos, nube o repositorios.

Para reducir el impacto futuro, es útil usar alcances mínimos y claves separadas por entorno: una clave de desarrollo no debería poder leer producción, un token utilizado por una canalización no debería tener privilegios administrativos globales y un secreto de webhook no debería reutilizarse entre diferentes servicios.

Qué hacer cuando encuentras un secreto expuesto

Cuando surge una clave en una PR generada por IA, en un registro o en un chat, la primera pregunta no es cómo limpiar el archivo, sino qué capacidad concede esa credencial: ¿puede leer una base de datos, modificar la nube y IAM, enviar pagos o correos, realizar despliegues, acceder a repositorios o datos de clientes?

El siguiente paso es delimitar la exposición buscando el mismo valor en el árbol de trabajo, historial de Git, ramas, etiquetas, PR, registros de CI/CD, artefactos, imágenes de contenedores, mapas de origen, incidencias, tickets, prompts y chats. Si aparece en varios lugares, la rotación debe cubrir a todos los consumidores y la limpieza debe incluir los sistemas que conservan copias.

La secuencia correcta es: crear una nueva clave con el alcance mínimo, actualizar la aplicación y la canalización, verificar que el servicio funcione, revocar la clave antigua y comprobar los registros de acceso del proveedor. Si la credencial afectaba a producción, datos de clientes, pagos, repositorios o la nube, el hallazgo debería bloquear el lanzamiento hasta que se complete la rotación.

Incluso una clave “de prueba” debe verificarse, porque muchos entornos de staging comparten datos, webhooks, buckets o cuentas de servicio más amplios de lo previsto. Antes de clasificar el incidente como menor, es necesario comprobar el entorno, privilegios, límites de gasto, datos accesibles e integraciones conectadas.

Lista de verificación de limpieza antes del despliegue

Antes de publicar código generado o modificado con IA, realiza al menos estos controles:

  • Escanea el repositorio, historial de Git, ramas, etiquetas y solicitudes de extracción.
  • Busca archivos .env, .pem, .key, .p12, archivos de credenciales, copias de seguridad y configuraciones de CLI.
  • Controla los scripts de compilación, pruebas, despliegue y flujos de trabajo de CI/CD.
  • Verifica registros recientes, artefactos, imágenes de contenedores, paquetes frontend y mapas de origen.
  • Revisa prompts, chats, tickets e incidencias utilizados para la depuración.
  • Separa las claves de desarrollo, staging y producción.
  • Mueve los secretos a un gestor de secretos, bóveda (vault) o variables protegidas de la plataforma.
  • Habilita el escaneo de secretos y la protección de inserción donde estén disponibles.
  • Añade patrones personalizados para tokens internos o formatos propietarios.
  • Rota cada clave expuesta, sospechosa o que haya pasado por un sistema no previsto.

Esta lista de verificación debe ejecutarse incluso si el repositorio es privado y aunque la aplicación aún no sea pública, porque un secreto puede ser explotado antes de la puesta en marcha (go-live) si concede acceso a la nube, bases de datos, pagos, correos electrónicos o repositorios.

Cómo ISGroup puede verificar secretos y configuraciones

ISGroup puede apoyar una verificación dirigida sobre código generado o modificado con IA, centrándose en el hardcoding, archivos sensibles, configuraciones, canalizaciones, registros, artefactos, dependencias y las formas en que los agentes han interactuado con el proyecto. El objetivo es entender si existen credenciales expuestas, si deben rotarse y qué controles insertar antes del próximo despliegue.

Si en el proyecto generado por IA encuentras… Riesgo principal Control recomendado
API keys, tokens, archivos .env, cadenas de conexión o archivos sensibles en el repositorio Exposición directa de credenciales Revisión de código
Servicios, hosts, paneles o API alcanzables mediante credenciales sospechosas Superficies explotables o configuraciones expuestas Evaluación de vulnerabilidades
Modo agente, CI/CD, artefactos de compilación, escaneo de secretos y procesos de fusión no gobernados Riesgo repetible en lanzamientos sucesivos Ciclo de vida de aseguramiento de software
Nube, buckets, bases de datos, IAM o cuentas de servicio vinculadas a claves expuestas Privilegios excesivos o configuración errónea en la nube Evaluación de seguridad en la nube
Aplicación o API ya en línea con posible clave comprometida Abuso real desde el exterior Pruebas de penetración en aplicaciones web

La elección del control depende de lo que permita hacer el secreto: leer datos, modificar la nube, enviar pagos, acceder a repositorios, usar API externas o realizar despliegues. Eliminar los secretos del código antes del lanzamiento y reducir el daño posible en caso de una nueva exposición son los dos objetivos concretos que deben alcanzarse antes de la puesta en marcha.

Evidencias a preparar para una revisión

Para una revisión eficaz es útil preparar el repositorio, las ramas afectadas, las PR generadas por IA, la lista de herramientas utilizadas, los flujos de trabajo de CI/CD, los sistemas de despliegue, los entornos, los archivos de exclusión, el gestor de secretos, la lista de variables críticas y las alertas de escaneo de secretos ya recibidas.

Es igualmente importante recopilar indicios fuera del código: chats en los que se pegaron errores, tickets de depuración, registros de compilación, artefactos, imágenes de contenedores, mapas de origen, capturas de pantalla, prompts compartidos, archivos README y scripts temporales. Si una clave ha sido rotada, es útil conservar cuándo, por quién, dónde se utilizaba y qué registros de acceso se comprobaron, porque esta información permite distinguir entre un secreto realmente expuesto, un falso positivo, una clave de prueba sin privilegios, una credencial de producción que debe revocarse de inmediato y un problema de proceso que debe corregirse en el ciclo de desarrollo.

Decisión antes de la publicación

Bloquea el despliegue si encuentras claves de producción en el repositorio, claves de rol de servicio en el frontend, URL de bases de datos con privilegios reales, tokens de nube con amplio alcance, secretos en registros públicos, artefactos descargables con credenciales o tokens pegados en el chat sin rotación.

Puedes planificar después del lanzamiento solo las mejoras con un riesgo residual claro: reforzar la nomenclatura de las variables, añadir patrones personalizados a los escáneres, completar la documentación, reducir el alcance de claves no críticas o mejorar la incorporación (onboarding) del equipo. La rotación de una clave expuesta nunca debe posponerse.

La decisión final debe ser verificable: qué secretos se encontraron, cuáles se rotaron, qué escáneres están activos, qué archivos están excluidos, qué registros se comprobaron y qué proceso impide que el mismo error vuelva a aparecer en el siguiente lanzamiento.

Preguntas frecuentes

  • Si el repositorio es privado, ¿debo eliminar las API keys de todos modos?
  • Sí. Un repositorio privado no es un gestor de secretos. Los colaboradores, CI/CD, agentes, aplicaciones instaladas, copias de seguridad y cuentas comprometidas pueden acceder a las credenciales.
  • Si he borrado la clave del código, ¿debo rotarla?
  • Sí, si la clave ha sido confirmada, impresa en registros, incluida en artefactos o pegada en prompts. La eliminación del archivo no invalida el secreto.
  • ¿El escaneo de secretos es suficiente para estar tranquilo?
  • No. Es un control necesario, pero puede no reconocer tokens personalizados, secretos parciales, formatos internos o credenciales presentes fuera del repositorio, como registros y chats.
  • ¿Puedo poner claves en el frontend si el framework lo permite?
  • Solo si son claves diseñadas para ser públicas y limitadas. Las claves de servicio, URL de bases de datos privadas, tokens administrativos, secretos JWT y credenciales en la nube no deben terminar en el paquete.
  • ¿Qué hago si he pegado una clave en un chat de IA?
  • Trátala como expuesta: rótala, verifica los registros de acceso del proveedor, comprueba dónde se utilizaba y actualiza al equipo sobre cómo compartir errores sin credenciales reales.
  • ¿Qué secretos son más urgentes de rotar?
  • Claves en la nube, tokens de GitHub/GitLab, claves de rol de servicio, URL de bases de datos de producción, API keys de pago, secretos de webhook, secretos JWT, claves privadas y tokens con acceso a datos de clientes.

[Callforaction-WAPT-Footer]

Lecturas adicionales

Leave a Reply

Your email address will not be published. Required fields are marked *