Parte: 11 — DevSecOps y seguridad del SDLC · Fuente: Securing DevOps (Julien Vehent) y OWASP Secrets Management Cheat Sheet ⏱️ Duración estimada: 90 min · Nivel: Intermedio
Aprender a prevenir, detectar y remediar la filtración de secretos (API keys, tokens, contraseñas, claves privadas) en repositorios de código. Un secreto commiteado —aunque se borre después— queda en el historial de Git y debe considerarse comprometido. Implementaremos una defensa en profundidad: detección en el historial, hooks de pre-commit que bloquean antes de commitear, y escaneo en CI, usando gitleaks y el framework pre-commit.
Al finalizar, el alumno podrá:
| # | Tema | Por qué importa |
|---|---|---|
| 1 | Anatomía de una fuga de secreto | Entender el ciclo de vida del riesgo |
| 2 | Detección por entropía y patrones | Cómo encuentran los escáneres los secretos |
| 3 | gitleaks: historial y pre-commit | Herramienta principal |
| 4 | El framework pre-commit | Orquestar hooks locales reproducibles |
| 5 | Escaneo en CI | Red de seguridad si el hook se salta |
| 6 | Remediación: rotar y purgar | Detectar no basta; hay que rotar |
| 7 | Gestión de secretos correcta | Vaults en vez de secretos en código |
Una contraseña, token o clave privada no deja de estar expuesta porque se borre del último commit. Git conserva objetos e historial; además, pueden existir clones, forks, cachés de CI, artefactos, registros y copias de seguridad. La respuesta correcta comienza por revocar o rotar la credencial y revisar su uso. Reescribir el historial reduce propagación futura, pero no puede demostrar que nadie la copió.
El diagrama distingue prevención y respuesta. El hook reduce errores antes del commit, pero es local y el usuario puede omitirlo; CI aplica una regla central, pero llega después de la subida. El gestor evita almacenar el valor en el repositorio, aunque una tarea todavía puede imprimirlo o enviarlo a un destino hostil. La defensa necesita capas y un flujo de incidente.
Las reglas combinan formatos conocidos, palabras contextuales y entropía. Un valor aleatorio puede parecer secreto sin serlo; una contraseña débil y humana puede escapar a un detector de entropía. La verificación contra el proveedor aumenta certeza, pero también podría enviar material sensible fuera de la organización, por lo que debe evaluarse. Los resultados requieren clasificación: credencial real, ejemplo deliberado, dato de prueba o falso positivo. Los ejemplos deben usar valores inequívocamente ficticios y dominios reservados.
La configuración no debería llenar una lista global de exclusiones. Una excepción precisa indica archivo, regla, motivo y revisión. Los binarios, fixtures y archivos generados necesitan tratamiento específico. También se escanean commits previos y artefactos, no solo el directorio de trabajo.
El objetivo no es mover una clave larga desde YAML a otra variable igualmente permanente. Siempre que la plataforma lo permita, el pipeline intercambia una identidad de corta duración —por ejemplo mediante OIDC— por credenciales limitadas a una tarea. Se restringen audiencia, repositorio, rama, entorno, operación y duración. Los logs se enmascaran, pero el enmascaramiento es una red de seguridad, no autorización: transformaciones como base64 pueden eludirlo.
Un desarrollador publica una clave cloud, hace un segundo commit borrándola y concluye que el problema está resuelto. El equipo revoca la clave, consulta registros desde su emisión, identifica ejecuciones, rota recursos derivados y después limpia el historial coordinando clones. Añade detección local y central, reemplaza la clave por federación de identidad limitada al entorno y crea una prueba que evita imprimir variables. La secuencia prioriza detener el acceso antes de embellecer Git.
| Término | Definición útil |
|---|---|
| Secreto | Material que permite autenticar, firmar, descifrar o autorizar. |
| Rotación | Sustitución controlada de una credencial y actualización de consumidores. |
| Revocación | Invalidación de la credencial comprometida. |
| Entropía | Medida estadística usada como señal, no prueba de que un valor sea secreto. |
| Credencial efímera | Autorización de corta duración emitida para un contexto concreto. |
El alumno domina la materia si puede diseñar prevención local y central, clasificar un hallazgo, ejecutar una respuesta en el orden correcto y reemplazar un secreto permanente por identidad limitada sin afirmar que limpiar el historial elimina la exposición pasada.
git log/git show de commits antiguos.Instalación:
# gitleaks
brew install gitleaks # o descarga el binario de releases
# framework pre-commit
pip install pre-commit
Nota ética: nunca subas secretos reales a repos públicos para "probar". Usa secretos falsos de ejemplo. Si detectas un secreto de tu organización, trátalo como incidente: rota primero.
🧪 Laboratorio ejecutable del programa:
devsecops-pipeline— es la capa 3 del lab: secretos con formato realista, y el matiz de los genéricos que se escapan a la detección.
gitleaks detect --source . --report-format json --report-path gitleaks.json -v
Revisa hallazgos: cada uno lista commit, archivo, línea y regla.
2. Instala el hook de pre-commit. Crea .pre-commit-config.yaml:
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.18.0
hooks:
- id: gitleaks
pre-commit install
AKIAIOSFODNN7EXAMPLE) e intenta commitear: el hook debe abortar el commit..gitleaks.toml con una allowlist para valores de ejemplo/tests, con justificación.gitleaks detect en cada push; es la red de seguridad si alguien no tiene el hook local. Usa la action oficial gitleaks/gitleaks-action.git filter-repo --path archivo --invert-paths o BFG, (c) fuerza push coordinado con el equipo. Documenta que la rotación es lo primero.Implementa defensa en profundidad contra secretos en un repositorio.
Criterio de aceptación: (a) hay un hook de pre-commit con gitleaks que bloquea secretos localmente; (b) CI escanea el historial en cada push y falla ante un hallazgo; (c) existe una allowlist justificada para falsos positivos; y (d) se entrega un runbook de remediación que pone la rotación del secreto como primer paso, antes de purgar el historial.
| Síntoma / mensaje | Causa y cómo arreglar |
|---|---|
| "Borré el secreto en un nuevo commit, ya está" | Sigue en el historial. Rota el secreto y purga con filter-repo/BFG. |
| El hook no se ejecuta | Falta pre-commit install o el archivo de config. Verifícalo con pre-commit run --all-files. |
| Muchos falsos positivos en tests | Valores de ejemplo detectados como secretos. Añade allowlist en .gitleaks.toml. |
| Solo se escanea HEAD, no el historial | Usaste --no-git o un modo limitado. Usa gitleaks detect sobre todo el repo. |
| Se purgó el historial pero el secreto sigue funcionando | No se rotó. Purgar no invalida la credencial; rotar sí. |
❓ Un secreto estuvo 5 minutos en un repo privado y lo borré, ¿hay riesgo? Sí. Asume compromiso y rota. Repos privados se clonan, se cachean y pueden volverse públicos por error; los bots escanean GitHub en segundos.
❓ ¿Los hooks de pre-commit son suficientes?
No por sí solos: son locales y evitables (--no-verify). Combínalos siempre con escaneo en CI del lado servidor.
❓ ¿Qué hago si el secreto está en cientos de commits? Rota primero. Luego purga con git-filter-repo o BFG y coordina el force-push con todo el equipo (reescribe el historial compartido).
❓ ¿Cómo evito el problema de raíz? No pongas secretos en el código. Usa un secrets manager/vault e inyéctalos en runtime como variables de entorno o montajes.
Clase 240 — SCA: dependencias y riesgo de terceros