GitHub Actions puede dejar de usar claves de AWS de larga duración
La federación OIDC permite que cada ejecución pida credenciales temporales a AWS STS en vez de arrastrar un AWS_ACCESS_KEY_ID fijo en los secretos del repositorio.

GitHub Actions lleva tiempo permitiendo que un flujo de trabajo asuma un rol de IAM en AWS sin guardar ninguna clave estática. El mecanismo es la federación por OpenID Connect: GitHub firma un JWT por ejecución y AWS STS lo canjea por credenciales temporales. Si tu repositorio todavía tiene AWS_ACCESS_KEY_ID y AWS_SECRET_ACCESS_KEY entre sus secretos, ese par de cadenas es el eslabón más débil de la cadena, y rota cuando le apetece a un atacante, no cuando tú lo decidas.
Con la acción configure-aws-credentials esas credenciales duran una hora por defecto, y se pueden alargar hasta el máximo de sesión configurado en el propio rol. No hay clave que filtrar, ni captura olvidada en un ticket, ni rotación pendiente.
El proveedor de identidad se crea una vez por cuenta
El recurso de proveedor OIDC en IAM apunta a token.actions.githubusercontent.com y lo comparten todos los flujos que asuman roles en esa cuenta. Recrearlo por proyecto es el error habitual: AWS rechaza un segundo proveedor con la misma URL y no hace ninguna falta. Se aprovisiona una vez —Terraform o consola— y desde ahí se referencia desde tantos roles como repositorios tengas.
Si lo creaste hace años con un thumbprint explícito, déjalo como está. AWS ya no depende de ese valor para el proveedor de GitHub, pero uno existente tampoco rompe nada.
La política de confianza es donde vive la seguridad
Aquí se decide si todo lo anterior sirve de algo. El campo sub del token codifica repositorio y, según el caso, rama, tag, entorno o contexto de pull request. Hay que exigirlo de forma explícita: un sub con comodín tipo repo:mi-org/* deja que cualquier flujo de cualquier repositorio de la organización asuma el rol, incluido uno recién creado o uno que ejecute una acción de terceros comprometida.
Cuando el job declara environment, el sub pasa a tener la forma environment:production, y conviene fijarlo también ahí: si el entorno tiene revisores obligatorios, ganas una aprobación humana encima de la comprobación del token. StringLike solo cuando el comodín sea intencionado. La documentación de GitHub para OIDC contra AWS recoge el formato exacto de cada variante.
Una confianza estrecha no justifica permisos anchos. El rol debería poder hacer exactamente lo que hace el pipeline —empujar a un repositorio de ECR, actualizar un servicio de ECS, escribir en un bucket concreto— y nada adyacente. Conviene separar los roles de plan y de apply, y los de staging y producción: un terraform plan que sale de un pull request no necesita los permisos con los que se aplica en main.
En el YAML, permissions: id-token: write es obligatorio a nivel de job o de workflow, y es el fallo de configuración más frecuente. Ojo: al declarar el bloque permissions, todo lo que no aparezca queda en none, de ahí que haga falta contents: read para el checkout. Y no referencies la acción como @main; un tag de versión mayor ya es mejor que una rama, pero un SHA completo con Dependabot actualizándolo es lo único que te protege de un compromiso de la cadena de suministro.
La migración se hace repositorio a repositorio y no rompe nada del lado de AWS: el mismo rol sigue existiendo, solo cambia cómo se llega a él. Lo que hay que revisar cuando la des por terminada no es el flujo de trabajo, sino cada condición de la política de confianza.

