Módulo 8: Capstone The Andes Cargo Security Gate

1. Introducción al capstone

Descripción

Siete módulos construyeron siete piezas por separado. Este último módulo no agrega una octava pieza — las encadena. Vas a tomar conftest (Módulo 4), Trivy (Módulo 5) y cosign (Módulo 6) y convertirlos en tres jobs de un mismo pipeline de GitHub Actions, corridos en orden, cada uno condicionado a que el anterior haya pasado. Al final de este módulo, andes-cargo-infra/ tiene un security gate real: un cambio no llega a apply sin atravesar política, escaneo y firma, en ese orden, sin excepción.

Conexión con el módulo

Esta es la lección que responde una pregunta que las siete anteriores dejaron abierta a propósito: cada módulo construyó y verificó su control de forma aislada —conftest test corrido a mano, trivy config corrido a mano, cosign verify-blob corrido a mano—. Ninguno, hasta ahora, corrió en secuencia, dentro de un pipeline, con el poder de detener a los que vienen después. Ese es, exactamente, el trabajo de este módulo: no enseñar herramienta nueva, sino demostrar que las tres ya construidas se comportan como un sistema, no como tres comandos sueltos.


Qué se entrega al cerrar este módulo

Cuatro piezas, cada una con su propia lección:

  1. Un ci.yml extendido con tres jobs nombrados y encadenadospolicy-check (conftest), iac-scan (Trivy), verify-artifact (cosign) — cada uno con needs: apuntando al anterior, corridos de verdad con act pull_request.
  2. La prueba de que un cambio inocuo cruza los tres — un cambio real, pequeño, sin ninguna intención maliciosa, atraviesa policy-check, iac-scan y verify-artifact sin fricción, y llega al punto donde apply.yml (heredado, con el job verify-artifact que el Módulo 6 ya le agregó) tomaría el relevo.
  3. La prueba de que un cambio malo se detiene, y se detiene rápido — un intento real de ensanchar AppServerRole es rechazado por policy-check, antes de que iac-scan o verify-artifact siquiera arranquen. No es una promesa: es un act pull_request corrido de verdad, con el log completo como evidencia.
  4. Honestidad final, en un solo lugar — qué de esta guía completa corrió de verdad y qué quedó representativo, sin dispersarlo en siete módulos distintos, y hacia dónde apunta cada límite si Andes Cargo alguna vez corre esto contra una cuenta AWS real.

Recordatorio: las piezas de M1-M7, en una sola tabla

No vas a reconstruir nada de esto — cada fila ya está aplicada y verificada en los módulos anteriores. Esta tabla existe para que, al leer el ci.yml de la lección 3, reconozcas de inmediato de dónde viene cada pieza que aparece ahí.

MóduloQué construyóDónde vive en andes-cargo-infra/
M1El modelo de amenazas y el mapa de riesgosTHREAT-MODEL.md, RISK-MAP.md (7/7 filas Resolved al cierre de M7)
M2Identidad OIDC federada + roles de mínimo privilegiomodules/oidc-provider/, LambdaManifestProcessorRole/AppServerRole recortados
M3Gestión de secretos gestionada, nunca en texto planosecrets.tf (aws_ssm_parameter, aws_secretsmanager_secret)
M4Policy-as-code preventivo, tres políticas Regopolicy/no-destroy-shipments.rego, policy/least-privilege-iam.rego, policy/no-public-buckets.rego
M5Escaneo de IaC con herramientas de la comunidad.trivyignore, comentarios #checkov:skip= documentados
M6Cadena de suministro: SBOM + firma offlinesbom.cyclonedx.json, cosign.key/cosign.pub, manifest.sig
M7Guardrails preventivos y detectivos, clasificadosGUARDRAILS-MAP.md, permission boundary de AppServerRole, andes-cargo-trail

Los cinco controles genuinamente nuevos de este módulo no son un octavo concepto — son cinco de los siete de arriba, ahora encadenados en un solo pipeline en vez de vivir como comandos sueltos: OIDC (M2) ya gobierna quién puede correr este pipeline contra una cuenta real; secretos (M3) ya garantiza que nada de esto necesita una credencial en texto plano; conftest (M4), Trivy (M5) y cosign (M6) son los tres jobs literales que la lección 3 agrega a ci.yml. El capstone no inventa un sexto control — demuestra que los cinco, juntos, se comportan como un sistema.


Analogía: los controles en cadena de un aeropuerto

Un aeropuerto no revisa tu pasaporte, tu equipaje y tu identidad en la puerta del avión, todo a la vez, por una sola persona. Los controles están en cadena, y cada uno existe en un punto específico porque detener algo ahí es más barato que detenerlo después: control de documentos primero (¿tienes derecho a viajar?), rayos X de equipaje después (¿traes algo prohibido?), control de puerta al final (¿eres tú, con la tarjeta de embarque correcta?). Si fallas el primero —un pasaporte vencido—, nadie te deja avanzar a hacer cola en el segundo: no tiene sentido escanear el equipaje de alguien que ya no puede viajar.

El security gate de este módulo es exactamente esa cadena. policy-check es el control de documentos: ¿esta política de IAM tiene, siquiera, permiso para existir? Si falla ahí, nadie gasta los segundos de iac-scan escaneando configuración de un cambio que de todos modos no va a pasar. iac-scan es el rayos X: ¿hay algo mal configurado que un ojo humano no vería a simple vista? verify-artifact es el control de puerta: ¿el artefacto que está a punto de desplegarse es, de verdad, el que el equipo aprobó, sin ninguna alteración en el camino? Tres preguntas distintas, en el orden que minimiza el tiempo perdido en una respuesta que ya sabías que iba a ser "no".


El orden importa: por qué policy-check va primero

No es arbitrario. Cada control de este gate tiene un costo distinto en tiempo de ejecución:

policy-check   →   milisegundos   →   evalúa un plan ya calculado, sin tocar disco más que para leerlo
iac-scan       →   segundos        →   parsea HCL completo, descarga un bundle de reglas
verify-artifact →   segundos        →   instala una herramienta externa, verifica un archivo

Poner el control más barato primero significa que un cambio que de todos modos iba a fallar, falla en el paso que menos tiempo de runner desperdicia — el mismo criterio que el Módulo 5, lección 7, ya aplicó al decidir que el escaneo de Trivy corre antes de terraform init, no después. Este módulo lleva ese mismo criterio un nivel más arriba: no solo "¿en qué punto de un job corre este chequeo?", sino "¿en qué orden corren los jobs mismos?".


Cómo se organiza este módulo

#LecciónQué vas a hacer
1Esta introducciónMapa del módulo, recordatorio de M1-M7
2Repaso de arquitecturaEl diagrama completo del gate, superpuesto sobre ci.yml/apply.yml
3Encadenando el gate en ci.ymlEjecutado. Los tres jobs, con needs:, corridos con act
4Un cambio que cruza el gateEjecutado. Un tag nuevo en el bucket, verde de punta a punta
5Un cambio que el gate detieneEjecutado. AppServerRole ensanchado, detenido en policy-check
6Lo que esta guía dejó representativoHonestidad final, un solo lugar, cada límite con su razón
7Lo que Andes Cargo todavía necesitaEl mapa hacia el resto del ecosistema
8Proyecto finalEl repositorio completo como pieza de portfolio

Errores comunes

Pensar que este módulo construye un cuarto o quinto control de seguridad nuevo. Qué pasa: alguien llega a este módulo esperando aprender una herramienta más, además de conftest/Trivy/cosign. Cómo detectarlo: si tu expectativa al empezar la lección 3 es instalar algo que no conoces todavía. Cómo corregirlo: este módulo no instala nada nuevo — las tres herramientas ya están instaladas desde M4, M5 y M6. El trabajo entero es de orquestación: decidir el orden, declarar las dependencias entre jobs con needs:, y verificar que el conjunto se comporta como uno solo, no como tres piezas sueltas.

Confundir "el gate corrió limpio" con "el proyecto está libre de riesgo". Qué pasa: alguien, al ver los tres jobs en verde en la lección 3, concluye que andes-cargo-infra/ ya no tiene ningún hallazgo de seguridad pendiente. Cómo detectarlo: si tu entendimiento del estado del proyecto viene solo del resultado binario pasa/falla del pipeline, sin revisar RISK-MAP.md o GUARDRAILS-MAP.md. Cómo corregirlo: el gate detecta lo que sabe buscar — tres políticas Rego específicas, las reglas de Trivy, la integridad de un artefacto firmado. GUARDRAILS-MAP.md (Módulo 7) ya documentó, con precisión, qué controles quedan fuera de este gate por completo (SCP, Organizations, GuardDuty, Config) — un pipeline en verde no los reemplaza, y la lección 6 de este módulo lo repite explícitamente para que no quede como una nota perdida en un módulo anterior.

Saltar directamente a la lección 5 (el cambio que falla) sin correr primero la lección 3 (el gate armado). Qué pasa: alguien, impaciente por ver el caso "interesante" de un policy-check fallando, se salta el armado del pipeline. Cómo detectarlo: si intentas correr act pull_request sobre un ci.yml que no tiene los tres jobs con needs: encadenado todavía. Cómo corregirlo: la lección 5 depende, literalmente, de la estructura que la lección 3 construye — sin needs: iac-scan en el job verify-artifact y needs: policy-check en iac-scan, un fallo en policy-check no impediría que los otros dos jobs corrieran de todos modos (act, sin esa declaración, los correría en paralelo, sin ninguna dependencia entre ellos).


Ejercicios

Ejercicio 1 — Antes de leer la lección 2, dibuja de memoria el diagrama del gate. Basándote solo en esta introducción, escribe (en texto, sin mirar ninguna lección posterior) la secuencia de los tres jobs nuevos, con sus nombres exactos y qué herramienta corre cada uno.

Ver solución

policy-check (conftest, evalúa el plan contra policy/) → iac-scan (Trivy, escanea el HCL crudo) → verify-artifact (cosign, verifica lambda/function.zip contra manifest.sig). El orden importa: cada uno depende del anterior vía needs:, así que un fallo en cualquiera detiene a los que le siguen. El punto del ejercicio no es memorizar los tres nombres —eso lo vas a ver una y otra vez en las próximas lecciones— sino confirmar que entendiste, desde esta introducción, que el orden no es alfabético ni arbitrario: es de costo creciente.

Ejercicio 2 — Explica, a alguien que solo hizo M1-M3 de esta guía (no M4-M7), por qué este módulo no le va a servir todavía. ¿Qué prerequisito específico de M4, M5 y M6 hace que este capstone no tenga sentido sin haberlos completado?

Ver solución

Este módulo no construye policy/, no instala Trivy, no genera cosign.key/cosign.pub ni manifest.sig — los toma como ya construidos, exactamente igual que M4.8, M5.8 y M6.8 ya los dejaron. Alguien que solo completó M1-M3 llegaría a la lección 3 sin ninguna de las tres piezas que el ci.yml de esa lección asume que existen: sin policy/, conftest test no tendría contra qué evaluar; sin .trivyignore ya calibrado, trivy config --exit-code 1 fallaría sobre hallazgos que M5 ya resolvió o suprimió con razón documentada; sin manifest.sig, no habría nada que verificar. El capstone asume, literalmente, el estado final de andes-cargo-infra/ al cierre de M7 — es la razón por la que esta guía lo deja para el último módulo, no antes.

Ejercicio 3 — Predice cuál de los tres jobs es el más rápido, y justifica por qué, antes de verlo confirmado con tiempos reales en la lección 3. Usando solo el razonamiento de "el orden importa" de esta lección, ¿cuál de policy-check, iac-scan, verify-artifact esperarías que termine primero, en aislamiento (sin contar el tiempo de instalación de cada herramienta)?

Ver solución

policy-check, en su paso de evaluación pura (conftest test tfplan.json -p policy/), es el más rápido de los tres: evalúa un JSON ya calculado, en memoria, contra cuatro reglas Rego — un trabajo de milisegundos, como ya viste en el Módulo 4. iac-scan parsea HCL completo y descarga un bundle de reglas de Trivy (segundos). verify-artifact necesita instalar cosign desde cero en cada corrida del runner (varios segundos) antes incluso de verificar la firma. La lección 3 confirma esto con tiempos reales de la propia salida de act — pero el razonamiento de esta introducción ya debería haberte llevado a la respuesta correcta sin necesidad de correr nada todavía.


Resumen y siguiente paso

Este módulo no agrega una pieza de seguridad nueva a Andes Cargo — encadena las cinco que M2-M6 ya construyeron en un sistema real: tres jobs nombrados (policy-check, iac-scan, verify-artifact), con needs: declarando el orden, corridos de verdad con act. Vas a ver un cambio inocuo cruzar los tres sin fricción, y un cambio real que ensancha AppServerRole detenido en el primero, antes de que los otros dos siquiera arranquen — la prueba de que "verde no es sinónimo de seguro" (Módulo 1) tiene, ahora, un mecanismo real que lo hace cierto en sentido contrario: rojo en el punto correcto sí es sinónimo de que el gate está haciendo su trabajo.

La lección 2 dibuja el diagrama completo del gate, superpuesto sobre el ci.yml/apply.yml heredado, antes de tocar una sola línea de YAML.

Recursos

  1. Este curso, Módulos 4, 5 y 6 — el origen de cada una de las tres herramientas que este módulo encadena, con su instalación y su primer uso individual ya verificados.
  2. Este curso, Módulo 7, GUARDRAILS-MAP.md — la matriz que este módulo capstone no reemplaza ni repite, solo referencia.
  3. cicd-and-gitops-on-aws-guide, Módulo 3 y Módulo 5 — el ci.yml/apply.yml original de nueve steps que este módulo extiende sin reescribir.