Módulo 2: Federated Identity And Least Privilege Iam
1. Introducción: lo que se nombró, ahora se construye
Descripción
RISK-MAP.md cerró el Módulo 1 con siete riesgos, siete filas, todas honestamente marcadas Open. La primera fila de esa tabla dice: TM-01, Spoofing, credenciales estáticas de larga vida en el pipeline, control: federación OIDC + trust policy acotada, módulo: M2. Esta lección abre exactamente esa fila.
Si viniste de cicd-and-gitops-on-aws-guide, ya conoces el mecanismo de OIDC de memoria: en el Módulo 4, lección 4 de esa guía, aprendiste el flujo de seis pasos —JWT, identity provider, trust policy, credenciales temporales—; en la lección 5, viste el YAML completo, listo para producción, con una advertencia explícita en su primera línea: "esta lección es representativa desde su primera línea". Esa guía no podía construir el lado de AWS: ni act puede emitir un JWT real, ni LocalStack —el laboratorio $0 de esa guía— tiene un rol IAM real esperando del otro lado. Terminaba con un pointer directo, citado textual: "cloud-security-and-guardrails-guide es la guía hermana que sí construye este patrón de punta a punta".
Esta es esa guía, y este es ese módulo. Lo que cicd-and-gitops-on-aws-guide mostró en YAML, sin poder ejecutarlo, aquí se construye: un identity provider de IAM real, declarado en Terraform, aplicado contra LocalStack; una trust policy real, acotada a un repositorio y una rama exactos; y, hasta donde el plan gratuito de LocalStack lo permite, una llamada real a sts:AssumeRoleWithWebIdentity que te va a enseñar, en vivo, exactamente qué SÍ y qué NO valida un laboratorio $0.
Conexión con el módulo
Este módulo tiene ocho lecciones, y se leen en tres bloques. Las lecciones 2 y 3 completan el vocabulario que te falta: por qué una credencial de larga vida es peor de lo que probablemente pensabas (lección 2), y cómo funciona OIDC del lado de AWS, pieza por pieza, antes de escribir HCL (lección 3). Las lecciones 4, 5 y 6 son la columna vertebral construida: el identity provider (4), la trust policy de mínimo privilegio (5), y el experimento central de todo el módulo —qué valida LocalStack Hobby de un JWT, y qué no (6)—. Las lecciones 7 y 8 cierran el trabajo: los dos roles reales de Andes Cargo, recortados a mínimo privilegio (7), y el proyecto que deja modules/oidc-provider/ completo, aplicado, verificado (8).
El mapa de este módulo: las 8 lecciones
MÓDULO 2 — IDENTIDAD FEDERADA Y MÍNIMO PRIVILEGIO IAM
M2.1 Introducción (esta) mapa del módulo
M2.2 El antipatrón de credenciales, a fondo por qué un secreto filtrado no se borra
M2.3 Cómo funciona OIDC, paso a paso JWT, identity provider, trust policy
M2.4 Manos a la obra: el identity provider aws_iam_openid_connect_provider, EJECUTADO
M2.5 Manos a la obra: la trust policy aws_iam_role condicionado, EJECUTADO
M2.6 Qué valida LocalStack, y qué no el experimento central del módulo
M2.7 Manos a la obra: endureciendo los roles LambdaManifestProcessorRole, AppServerRole
M2.8 Proyecto: la identidad federada modules/oidc-provider/ completo
| # | Lección | Qué construye |
|---|---|---|
| 1 | Introducción (esta) | El mapa del módulo; qué heredaste de cicd-and-gitops-on-aws-guide M4.4/M4.5 |
| 2 | El antipatrón de las credenciales, retomado a fondo | Por qué un secreto filtrado en Git no es un archivo que se borra — es un commit que persiste |
| 3 | Cómo funciona la federación OIDC, paso a paso | El JWT, el identity provider como "en quién confío", la trust policy como "qué le permito" |
| 4 | Manos a la obra: el IAM OIDC Identity Provider | Ejecutado: aws_iam_openid_connect_provider en modules/oidc-provider/ |
| 5 | Manos a la obra: una trust policy de mínimo privilegio | Ejecutado: aws_iam_role condicionado a repo:andes-cargo/andes-cargo-infra:ref:refs/heads/main |
| 6 | Manos a la obra: qué valida LocalStack, y qué no | Ejecutado (el experimento) + representativo (la conclusión): un JWT de prueba real, una llamada representativa |
| 7 | Manos a la obra: endureciendo los roles reales | Ejecutado: LambdaManifestProcessorRole/AppServerRole recortados a mínimo privilegio |
| 8 | Proyecto: la identidad federada de Andes Cargo | modules/oidc-provider/ completo, aplicado; documento de qué cambiaría contra AWS real |
Qué heredas, sin que se vuelva a explicar
Este módulo asume, sin repetirlo:
- De
cicd-and-gitops-on-aws-guide, Módulo 4: el mecanismo conceptual completo de OIDC —los seis pasos,permissions: id-token: write, la trust policy como concepto— y el YAML completo y representativo del patrón (aws-actions/configure-aws-credentials,role-to-assume). Si ese vocabulario no te suena firme, la lección 3 de este módulo lo repasa brevemente antes de construir sobre él, pero no lo vuelve a enseñar desde cero. - De
terraform-and-iac-guide: el proyectoandes-cargo-infra/completo —doce recursos, los módulosmodules/s3-bucket/ymodules/iam-role/—, y el patrón dedata "aws_iam_policy_document"para escribir políticas. - De este mismo curso, Módulo 1:
THREAT-MODEL.md(los siete hallazgosTM-01aTM-07) yRISK-MAP.md(el orden de resolución). Este módulo cierra las filasTM-01yTM-07— las dos primeras del mapa.
Lo que este módulo agrega a andes-cargo-infra/
Un solo directorio nuevo, modules/oidc-provider/, construido en dos pasos (lección 4 agrega el identity provider; lección 5 lo extiende con el rol y su trust policy), más ediciones a iam.tf —el mismo archivo que terraform-and-iac-guide ya declaró, no uno nuevo— para recortar los dos roles existentes. Cero recursos de negocio nuevos, exactamente como prometió el diseño de esta guía desde su primera lección.
andes-cargo-infra/
├── THREAT-MODEL.md (M1, sin cambios de contenido)
├── RISK-MAP.md (M1 → este módulo actualiza TM-01 y TM-07 a Resolved)
├── iam.tf (heredado — este módulo RECORTA las dos políticas existentes)
├── modules/
│ ├── s3-bucket/ (heredado, sin cambios)
│ ├── iam-role/ (heredado, sin cambios)
│ └── oidc-provider/ ← NUEVO de este módulo
│ ├── main.tf aws_iam_openid_connect_provider + aws_iam_role
│ ├── variables.tf
│ └── outputs.tf
└── oidc.tf ← NUEVO — llama a modules/oidc-provider/
El compromiso de honestidad de este módulo específico
Tres de los cuatro casos representativos de toda esta guía viven, total o parcialmente, en este módulo — vale la pena verlos juntos antes de empezar:
- M2.4 y M2.5 corren
terraform fmt/validate/plande verdad, contra el motor real de Terraform 1.15.8 con el providerhashicorp/aws~> 6.0. Elapplycontra LocalStack y la lectura conawslocalquedan representativos por la misma razón exacta que ya viste en el Módulo 1: este entorno de escritura no tiene unLOCALSTACK_AUTH_TOKENexportado, así que el contenedor no arranca (Could not connect to the endpoint URL). Cada bloque representativo está reconstruido campo por campo del HCL real que sí corrió. - M2.6 es el experimento pedagógico central de todo este módulo. El JWT de prueba se construye con Python y
PyJWT, y esa parte sí corre de verdad —vas a ver el token real, no uno inventado—. La llamadaawslocal sts assume-role-with-web-identityy la observación de que LocalStack no verifica firma ni emisor quedan representativas, con la fuente exacta citada en el momento en que aparece: la funcionalidadIAM Policy Enforcementde LocalStack está documentada como incluida únicamente en los planes de pago Base y Ultimate, no en el plan gratuito Hobby/Community que usa todo este ecosistema. - M2.7 corre
terraform plande verdad sobre las políticas recortadas de los dos roles reales; la aplicación y verificación conawslocal iam get-role-policyquedan representativas por la misma razón de siempre.
Nada de esto es una debilidad escondida. Es, literalmente, la enseñanza central de este módulo: identidad y autorización son, de las capas de seguridad de AWS, las que un emulador gratuito no puede reproducir con el mismo rigor que una cuenta real — y saber exactamente dónde está esa línea es, en sí mismo, una habilidad de seguridad real.
Errores comunes
Pensar que este módulo reemplaza las credenciales dummy (test/test) que andes-cargo-infra/ usa contra LocalStack (de expectativa). Qué pasa: alguien termina la lección 8 y espera que providers.tf ya no tenga access_key = "test" / secret_key = "test". Cómo detectarlo: si buscas en este módulo un cambio al bloque provider "aws" de terraform-and-iac-guide. Cómo corregirlo: ese bloque sigue exactamente igual — sigue siendo la forma correcta de que Terraform, corriendo en tu máquina, hable con LocalStack. Lo que este módulo construye es la identidad que un pipeline de GitHub Actions usaría para hablar con una cuenta AWS real; son dos problemas distintos, con dos soluciones distintas, que conviven en el mismo proyecto sin pisarse.
Saltarse la lección 3 porque "ya vi OIDC en cicd-and-gitops-on-aws-guide" (de flujo). Qué pasa: alguien llega directo a la lección 4 con HCL, sin repasar qué claim exacto del JWT usa la trust policy, y se pierde en la lección 5. Cómo detectarlo: si no puedes explicar, sin mirar atrás, la diferencia entre lo que valida aud y lo que valida sub en una trust policy. Cómo corregirlo: la lección 3 es corta a propósito —no repite el diagrama completo de seis pasos que ya viste, pero sí ancla los dos nombres exactos de claims que vas a escribir en HCL dos lecciones después.
Tratar el caso representativo del M2.6 como "esta guía tampoco pudo construir OIDC de verdad, igual que cicd-and-gitops-on-aws-guide" (de lectura, ver también M1.1). Qué pasa: alguien lee que la validación del JWT es representativa y concluye que este módulo no construyó nada más que esa guía. Cómo detectarlo: si tu resumen mental de este módulo es "sigue sin poder probarse OIDC". Cómo corregirlo: la diferencia es real y específica — el identity provider (M2.4) y la trust policy (M2.5) sí se declaran y se aplican de verdad contra una cuenta (LocalStack), algo que cicd-and-gitops-on-aws-guide nunca pudo hacer por no tener ninguna cuenta AWS del otro lado. Lo único representativo es la última milla: que esa cuenta específica (LocalStack Hobby) no tiene el motor de pago que verificaría de verdad la firma y el emisor de un JWT externo. Es un límite mucho más angosto y mucho más preciso que el de la guía anterior.
Ejercicios
Ejercicio 1 — Ubica la fila exacta de RISK-MAP.md que este módulo cierra. Sin mirar el documento, escribe de memoria el ID, la categoría STRIDE, y la descripción del riesgo de la primera fila de RISK-MAP.md. Después, encuentra la segunda fila que este módulo también cierra (pista: M2.7, no M2 a secas).
Ver solución
Primera fila: TM-01, Spoofing, "Long-lived static pipeline credentials", control "OIDC federation + scoped trust policy", módulo M2. Segunda fila, que se resuelve específicamente en la lección 7 de este módulo, no en las lecciones 4-6: TM-07, Elevation of privilege, "AppServerRole broader than its actual usage", control "Least-privilege role tightening", módulo M2.7. Si ubicaste ambas sin ayuda, tienes clara la doble tarea de este módulo: construir identidad nueva (TM-01) y recortar permisos ya existentes (TM-07) son dos trabajos distintos que conviven en el mismo módulo.
Ejercicio 2 — Explica, a un colega que solo hizo cicd-and-gitops-on-aws-guide, qué es genuinamente distinto aquí. Tu colega dice: "Ya vi OIDC completo en YAML en esa guía, ¿qué hay de nuevo en esta?". Respóndele en dos o tres frases, siendo específico sobre qué lado del flujo cada guía construye.
Ver solución
Una respuesta completa suena, más o menos, así: "Esa guía te mostró el YAML completo del lado de GitHub Actions —el permissions: id-token: write, el role-to-assume—, pero no había ninguna cuenta AWS real del otro lado esperando esa llamada: ni siquiera podía emitir un JWT de verdad, porque act no implementa esa función. Esta guía construye exactamente esa otra mitad: el identity provider y el rol con su trust policy, declarados en Terraform, aplicados contra una cuenta real —LocalStack—. Es la primera vez en todo el ecosistema que existe algo real del lado de AWS para que ese YAML, llegado el momento, pudiera apuntar."
Ejercicio 3 — Predice cuál de las cuatro razones representativas de esta guía vas a encontrar primero, y por qué. Basándote en la tabla de honestidad del diseño de esta guía (citada en la introducción del Módulo 1), ¿cuál de los cuatro casos representativos aparece primero cronológicamente dentro de esta guía completa, y en qué lección exacta?
Ver solución
La validación real de un token OIDC contra AWS —la primera de las cuatro razones representativas nombradas en el diseño de esta guía (validación de OIDC, enforcement de IAM en general, guardrails detectivos a escala, Organizations/SCP multi-cuenta)— aparece primero, en la lección 6 de este mismo módulo (M2.6). Tiene sentido que sea la primera: es la más directamente relacionada con el tema que abre la guía completa —identidad—, y las otras tres (enforcement de IAM en M2.7/M7.3, guardrails detectivos en M7.4, multi-cuenta en M7.6) dependen conceptualmente de haber entendido primero esta.
Resumen y siguiente paso
En esta lección viste el mapa completo de las ocho lecciones de este módulo, confirmaste qué heredas sin que se vuelva a explicar —el mecanismo conceptual y el YAML representativo de cicd-and-gitops-on-aws-guide, el proyecto andes-cargo-infra/ completo de terraform-and-iac-guide, y las dos filas de RISK-MAP.md que este módulo va a cerrar—, y viste, de entrada, dónde exactamente van a aparecer los tres bloques representativos de este módulo, con su razón técnica ya anticipada.
Antes de avanzar deberías poder: nombrar las ocho lecciones en orden y qué construye cada una; explicar la diferencia entre lo que este módulo construye de verdad (identity provider, trust policy, aplicados contra una cuenta) y lo que queda representativo (la verificación de firma y emisor de un JWT externo); y ubicar las dos filas exactas de RISK-MAP.md que este módulo cierra.
La lección 2 retoma el antipatrón de las credenciales de larga vida —ya nombrado en el Módulo 1 como TM-01— y lo lleva más a fondo que cualquier guía anterior de este ecosistema: no solo "es inseguro guardar una clave", sino la mecánica exacta, demostrada con Git real, de por qué un secreto filtrado en un commit no desaparece cuando borras el archivo.
Recursos
cicd-and-gitops-on-aws-guide, Módulo 4, lecciones 4 y 5 — el mecanismo conceptual completo de OIDC y el YAML representativo que este módulo construye del lado de AWS.terraform-and-iac-guide— el proyectoandes-cargo-infra/completo que este módulo extiende, sin declarar ningún recurso de negocio nuevo.- Este curso, Módulo 1, lección 8 (
RISK-MAP.md) — las dos filas (TM-01,TM-07) que este módulo resuelve, con el razonamiento de por qué se resuelven en este orden. - LocalStack Docs — IAM Policy Enforcement — la fuente exacta de por qué tres de las lecciones de este módulo marcan pasos como representativos: "Included in Plans: Base, Ultimate", sin Hobby.
src/paths/aws-cloud-ecosystem/VALIDACION.md— la auditoría de mercado que fija el peso de este módulo: OIDC como el hueco más citado de la competencia.