system onlinepath: /guias/devops-cloud/como-administrar-secretos-en-pipelines-y-aplicaciones/mode: knowledge_baselocal:
DevOps y cloud · Nivel intermedio

Cómo administrar secretos en pipelines y aplicaciones

Una contraseña escrita en el código es una filtración esperando ocurrir. Gestionar secretos bien no es una molestia burocrática: es la diferencia entre un incidente contenido y una brecha total.

11 min de lectura▣ Actualizada el ◇ Por Underc0de
Respuesta rápida

Un secreto es cualquier credencial que da acceso a algo: una contraseña de base de datos, la clave de una API, un token, un certificado. La regla número uno, sin excepciones: los secretos nunca se escriben en el código. El código se versiona en Git y se comparte, y un secreto escrito ahí queda expuesto —y una vez subido, aunque lo borres, sigue en el historial—. En lugar de eso, los secretos se inyectan en tiempo de ejecución mediante variables de entorno, que el programa lee del sistema al arrancar. A escala, se usa un gestor de secretos: un servicio dedicado que los guarda cifrados, controla quién puede leer cada uno, registra los accesos y permite cambiarlos sin tocar el código. Dos prácticas más los completan: la rotación (cambiarlos cada cierto tiempo, para que uno filtrado tenga ventana corta) y el mínimo privilegio (cada secreto da el menor acceso posible). Y si un secreto se filtra, el orden es claro: revocarlo de inmediato, generar uno nuevo, y recién después limpiar el historial —porque mientras siga siendo válido, borrarlo del repositorio no sirve de nada—.

Ver índice de contenidos
  1. 01Por qué no van en el código
  2. 02Variables de entorno
  3. 03El gestor de secretos
  4. 04Rotación y filtraciones
  5. 05Errores frecuentes
  6. 06Preguntas frecuentes
  7. 07Fuentes

Por qué no van en el código

La tentación es enorme: la aplicación necesita la contraseña de la base de datos, así que la escribo ahí, en una variable, y listo. Ese atajo es el origen de una parte enorme de las brechas de seguridad, y por una razón que hay que entender del todo.

El código se comparte y el historial no olvida

El código se versiona en Git y se comparte: con el equipo, a veces en un repositorio público, con cualquiera que obtenga una copia. Un secreto escrito en el código queda expuesto a todos ellos. Y hay algo peor: aunque lo borres en un commit posterior, sigue en el historial del repositorio, accesible para siempre a quien mire las versiones anteriores. Por eso «lo saco después» no funciona: una vez subido, un secreto se considera comprometido.

Los buscadores automáticos que rastrean repositorios públicos encuentran claves subidas por error en minutos, y las explotan. La regla, entonces, no es una formalidad: separar los secretos del código es una de las medidas de seguridad más básicas y de mayor impacto.

Variables de entorno

Cómo se gestionan los secretos correctamente, contrastando la forma incorrecta con la correcta y mostrando el ciclo de vida. Arriba, tachado y marcado como incorrecto, el antipatrón: el secreto escrito directamente en el código fuente; una anotación señala que como el código se versiona y se comparte, ese secreto queda expuesto a todo el equipo y a cualquiera que obtenga una copia, y que aunque se borre después sigue quedando registrado en el historial del control de versiones, por lo que se considera comprometido para siempre. Debajo, marcada como correcta, la forma adecuada, mostrada como un flujo. A la izquierda, el gestor de secretos: un servicio dedicado que guarda todos los secretos cifrados, controla mediante permisos quién puede leer cada uno, registra cada acceso para auditoría, y permite cambiar un secreto en un solo lugar sin tocar el código. En el centro, el momento del despliegue o del arranque: el secreto viaja desde el gestor hasta la aplicación o el pipeline y se inyecta como una variable de entorno, es decir un valor que el programa lee del sistema al arrancar y que nunca queda escrito en el código ni en el repositorio; de este modo la misma aplicación puede usar credenciales distintas en desarrollo, en pruebas y en producción sin cambiar una sola línea. A la derecha, la aplicación en ejecución usando el secreto solo en memoria durante el tiempo que lo necesita. Rodeando todo el flujo, un ciclo con dos prácticas clave resaltadas. La primera, la rotación: los secretos se cambian cada cierto tiempo de forma periódica, de manera que si uno se filtra sin que nadie lo note, su ventana de utilidad para un atacante sea corta; el gestor de secretos facilita esta rotación al centralizar el cambio. La segunda, el mínimo privilegio: cada secreto otorga el menor acceso posible y solo a quien lo necesita, de modo que si uno se compromete, el daño quede acotado a una porción pequeña en lugar de dar las llaves de todo. Abajo, un recuadro de emergencia con el procedimiento ante una filtración, en orden estricto: primero revocar el secreto comprometido de inmediato para que deje de ser válido, después generar y desplegar uno nuevo, y solo entonces limpiar el historial; una nota advierte que mientras el secreto filtrado siga siendo válido, borrarlo del repositorio no sirve de nada porque el atacante ya lo tiene. Al pie, la idea que ordena todo: gestionar secretos bien es la diferencia entre un incidente contenido y una brecha total.
El secreto vive en un gestor, se inyecta como variable de entorno al desplegar, se rota periódicamente y se limita al mínimo privilegio. Ante una filtración: revocar primero, limpiar después.

La forma básica de sacar los secretos del código son las variables de entorno: valores que el programa lee del sistema al arrancar, no de su propio código. El código dice «leé la contraseña de la variable DB_PASSWORD»; el valor real vive fuera, en el entorno donde corre la aplicación.

javascript
// MAL: el secreto escrito en el código
const clave = "sk_live_9a8b7c6d5e";   // queda en el historial para siempre

// BIEN: el código lee el valor del entorno
const clave = process.env.API_KEY;    // el valor vive fuera del código

La ventaja adicional es que la misma aplicación corre en desarrollo, pruebas y producción con credenciales distintas, sin cambiar una línea: solo cambia el entorno. Este principio —la configuración y los secretos viven en el entorno, no en el código— es una de las bases del enfoque moderno de despliegue, y aplica igual en un pipeline, un contenedor o la infraestructura como código.

El gestor de secretos

Las variables de entorno sacan el secreto del código, pero el valor todavía hay que guardarlo y entregarlo desde algún lado. A escala, ese «algún lado» es un gestor de secretos: un servicio dedicado, pensado específicamente para custodiar credenciales. Sus funciones:

  • Almacenamiento cifrado. Los secretos se guardan cifrados, no en texto plano.
  • Control de acceso. Se define quién —qué persona, qué servicio— puede leer cada secreto, aplicando el mínimo privilegio.
  • Auditoría. Cada acceso queda registrado, de modo que se puede saber quién leyó qué y cuándo.
  • Cambio centralizado. Un secreto se cambia en un solo lugar y todas las aplicaciones que lo usan reciben el nuevo, sin tocar código.

Existen gestores de secretos como servicio en las nubes y también soluciones autoalojadas. La pieza clave no es cuál, sino el patrón: el secreto vive en el gestor, y las aplicaciones y pipelines lo piden en el momento de arrancar, con permisos acotados.

Rotación y filtraciones

Dos prácticas completan la gestión de secretos, y la segunda es un plan de emergencia que conviene tener claro antes de necesitarlo.

La rotación es cambiar los secretos cada cierto tiempo de forma periódica. La lógica: si un secreto se filtró sin que nadie lo note, rotarlo hace que su ventana de utilidad para un atacante sea corta. Un gestor de secretos facilita esto al centralizar el cambio. El estándar de gestión de claves del NIST trata este ciclo de vida en detalle.

!
Si un secreto se filtra: revocar primero, limpiar después

El orden importa y es contraintuitivo. Primero revocás el secreto comprometido, para que deje de ser válido. Segundo, generás y desplegás uno nuevo. Recién entonces limpiás el historial del repositorio. La razón: mientras el secreto filtrado siga siendo válido, borrarlo del código no sirve de nada —el atacante ya lo tiene copiado—. Lo único que corta el riesgo es invalidarlo. Una filtración de credenciales es uno de los fallos que recoge el OWASP Top 10, y conviene tratarla con la disciplina de un incidente de seguridad.

Errores frecuentes

  • Escribir secretos en el código. Quedan en el historial para siempre; es el error raíz.
  • Subir el archivo de configuración con secretos. Los archivos de entorno con valores reales no se versionan; se ignoran explícitamente.
  • Creer que borrar un commit basta. Si el secreto sigue siendo válido, hay que revocarlo, no solo borrarlo.
  • No rotar nunca. Un secreto eterno filtrado da acceso indefinido.
  • Un secreto con permisos de todo. El mínimo privilegio acota el daño de una filtración.
  • Compartir secretos por chat o correo. Quedan en historiales fuera de control; van por el gestor.
  • Registrar secretos en los logs. Imprimir una variable con la clave la filtra a los registros.

Preguntas frecuentes

¿Por qué no puedo escribir las contraseñas en el código?

Porque el código se versiona en un control de versiones y se comparte —con el equipo, a veces en repositorios públicos, y con cualquiera que obtenga una copia—, de modo que cualquier contraseña, clave o token escrito en él queda expuesto a todas esas personas. Y hay un agravante decisivo: aunque borres el secreto en un commit posterior, sigue quedando registrado en el historial del repositorio, accesible de forma permanente para quien revise las versiones anteriores. Por eso la excusa de «lo saco después» no funciona: en el momento en que un secreto se sube, se considera comprometido. A esto se suma que existen sistemas automáticos que rastrean continuamente los repositorios públicos en busca de credenciales subidas por error y las explotan en cuestión de minutos. Separar los secretos del código no es entonces una formalidad ni una molestia burocrática, sino una de las medidas de seguridad más básicas y de mayor impacto que existen, y su ausencia está detrás de una enorme cantidad de brechas.

¿Qué son las variables de entorno y cómo ayudan?

Las variables de entorno son valores que un programa lee del sistema donde se ejecuta, en lugar de tenerlos escritos en su propio código. Aplicadas a los secretos, permiten que el código diga algo como «leé la contraseña de la variable correspondiente» mientras el valor real vive fuera, en el entorno de la máquina o del servicio donde corre la aplicación, y nunca queda escrito en el código ni en el repositorio. Esto aporta dos beneficios importantes. El primero y principal es de seguridad: el secreto se saca del código, que es justamente el lugar donde no debe estar. El segundo es de flexibilidad: la misma aplicación, sin cambiar una sola línea, puede correr en desarrollo, en pruebas y en producción con credenciales distintas, porque lo único que cambia es el entorno que provee cada valor. Este principio de mantener la configuración y los secretos en el entorno y no en el código es una de las bases del enfoque moderno de despliegue de aplicaciones.

¿Qué es un gestor de secretos?

Es un servicio dedicado específicamente a custodiar credenciales, que resuelve el problema de dónde guardar y cómo entregar los secretos de forma segura a escala. Cumple varias funciones clave. Almacena los secretos cifrados en lugar de en texto plano. Controla mediante permisos quién puede leer cada secreto, ya sea una persona o un servicio, permitiendo aplicar el principio de mínimo privilegio. Registra cada acceso, de modo que queda una auditoría de quién leyó qué y cuándo. Y centraliza el cambio, de manera que un secreto se actualiza en un solo lugar y todas las aplicaciones que lo usan reciben el nuevo valor sin necesidad de tocar código. Existen gestores de secretos ofrecidos como servicio por las plataformas de nube y también soluciones que se pueden autoalojar. Lo importante no es cuál se elija, sino adoptar el patrón: el secreto vive en el gestor, y las aplicaciones y los pipelines lo solicitan en el momento de arrancar, con permisos acotados y de forma auditable.

¿Por qué hay que rotar los secretos?

Rotar un secreto significa cambiarlo por uno nuevo cada cierto tiempo de forma periódica, y la razón es acotar el daño de una filtración que podría no haberse detectado. Si un secreto permaneciera inalterado para siempre y en algún momento se filtrara sin que nadie lo advirtiera, un atacante tendría acceso indefinido con esa credencial. Al rotarlo periódicamente, en cambio, cualquier secreto comprometido deja de ser válido en la siguiente rotación, de modo que su ventana de utilidad para quien lo haya obtenido es corta. La rotación es una defensa en profundidad: no evita la filtración, pero limita cuánto tiempo sirve. Un gestor de secretos facilita mucho esta práctica, porque permite cambiar el valor en un único lugar y propagarlo automáticamente a todo lo que lo use, sin la fricción de actualizarlo a mano en muchos sitios, que es justamente lo que suele llevar a que la rotación no se haga. Los estándares de gestión de claves tratan este ciclo de vida en detalle.

¿Qué hago si subí un secreto al repositorio por error?

Lo primero y más importante es entender el orden correcto de las acciones, que es contraintuitivo. El primer paso debe ser revocar el secreto comprometido de inmediato, es decir invalidarlo en el servicio al que da acceso para que deje de funcionar. El segundo paso es generar un secreto nuevo y desplegarlo donde haga falta para que la aplicación siga operando. Y solo el tercer paso es limpiar el historial del repositorio para quitar el secreto de las versiones anteriores. La razón de este orden es crucial: mientras el secreto filtrado siga siendo válido, borrarlo del repositorio no sirve absolutamente de nada, porque quien lo haya visto ya tiene una copia y puede usarlo; lo único que corta el riesgo real es invalidar la credencial. Por eso tratar una filtración de secretos debe encararse como lo que es, un incidente de seguridad, aplicando los principios de la respuesta ante incidentes y de la gestión de vulnerabilidades: contener primero, remediar después.

¿Esta regla aplica también a Docker, Kubernetes y los pipelines?

Sí, es exactamente la misma regla en todos esos contextos, porque el principio de fondo es siempre el mismo: los secretos no deben quedar incrustados en nada que se versione, se comparta o se distribuya. En Docker, eso significa no escribir secretos en la imagen ni en el Dockerfile, ya que quedan grabados en las capas, e inyectarlos como variables de entorno al ejecutar. En Kubernetes, significa no ponerlos en los manifiestos versionados sino usar los objetos de secretos y un gestor externo. En los pipelines de integración y despliegue continuos, significa no escribirlos en el archivo del workflow sino cargarlos en el almacén de secretos cifrados de la plataforma. En la infraestructura como código con Terraform, significa no ponerlos en los archivos de configuración y además proteger el estado, que puede contenerlos. En todos los casos el patrón es idéntico: el secreto vive en un mecanismo aparte pensado para protegerlo, se inyecta o se referencia en tiempo de ejecución, y jamás se incrusta en el código, la imagen, el manifiesto o la configuración que se guarda y se comparte.

Fuentes

Documentación oficial y material de la comunidad consultados para esta guía. Fecha de consulta: 28 de julio de 2026.

Aportes de la comunidad Underc0de

  1. Underc0de, foro. Sección Hacking. Filtración de credenciales y su impacto en seguridad.
  2. Underc0de, foro. Sección Programación. Manejo de configuración y credenciales en el código.

Documentación oficial

  1. OWASP. Secrets Management Cheat Sheet. Prácticas de referencia, citadas en la guía.
  2. NIST. SP 800-57: Recommendation for Key Management. Ciclo de vida y rotación de claves.
  3. OWASP. OWASP Top 10. Los fallos de configuración y de identidad más habituales.
  4. The Twelve-Factor App. Config. Por qué la configuración y los secretos van en el entorno.