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ónQué construye
1Introducción (esta)El mapa del módulo; qué heredaste de cicd-and-gitops-on-aws-guide M4.4/M4.5
2El antipatrón de las credenciales, retomado a fondoPor qué un secreto filtrado en Git no es un archivo que se borra — es un commit que persiste
3Cómo funciona la federación OIDC, paso a pasoEl JWT, el identity provider como "en quién confío", la trust policy como "qué le permito"
4Manos a la obra: el IAM OIDC Identity ProviderEjecutado: aws_iam_openid_connect_provider en modules/oidc-provider/
5Manos a la obra: una trust policy de mínimo privilegioEjecutado: aws_iam_role condicionado a repo:andes-cargo/andes-cargo-infra:ref:refs/heads/main
6Manos a la obra: qué valida LocalStack, y qué noEjecutado (el experimento) + representativo (la conclusión): un JWT de prueba real, una llamada representativa
7Manos a la obra: endureciendo los roles realesEjecutado: LambdaManifestProcessorRole/AppServerRole recortados a mínimo privilegio
8Proyecto: la identidad federada de Andes Cargomodules/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 proyecto andes-cargo-infra/ completo —doce recursos, los módulos modules/s3-bucket/ y modules/iam-role/—, y el patrón de data "aws_iam_policy_document" para escribir políticas.
  • De este mismo curso, Módulo 1: THREAT-MODEL.md (los siete hallazgos TM-01 a TM-07) y RISK-MAP.md (el orden de resolución). Este módulo cierra las filas TM-01 y TM-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/plan de verdad, contra el motor real de Terraform 1.15.8 con el provider hashicorp/aws ~> 6.0. El apply contra LocalStack y la lectura con awslocal quedan representativos por la misma razón exacta que ya viste en el Módulo 1: este entorno de escritura no tiene un LOCALSTACK_AUTH_TOKEN exportado, 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 llamada awslocal sts assume-role-with-web-identity y 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 funcionalidad IAM Policy Enforcement de 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 plan de verdad sobre las políticas recortadas de los dos roles reales; la aplicación y verificación con awslocal iam get-role-policy quedan 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

  1. 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.
  2. terraform-and-iac-guide — el proyecto andes-cargo-infra/ completo que este módulo extiende, sin declarar ningún recurso de negocio nuevo.
  3. 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.
  4. 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.
  5. 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.