GitHub Actions sin claves AWS: tutorial OIDC actualizado a 2026
Tu despliegue termina bien, pero en el repositorio queda una pregunta incómoda: ¿quién va a rotar la clave de AWS guardada en GitHub Secrets? Si una credencial permanente se filtra, el problema sigue vivo después de que acabe el workflow. Con OpenID Connect (OIDC), GitHub Actions puede identificarse ante AWS y recibir credenciales temporales para una ejecución concreta.
La idea es simple: el workflow pide a GitHub un token firmado, AWS comprueba a qué repositorio y rama pertenece y, si coincide con la política de confianza del rol, entrega acceso con permisos limitados. GitHub explica que id-token: write permite solicitar ese token; por sí solo no concede permisos de escritura en AWS.
Antes de configurar: define el alcance
Para este ejemplo, un workflow en la rama main de un repositorio publicará un archivo en una ruta concreta de S3. Necesitas permiso para administrar IAM y conocer el identificador de la cuenta AWS, el repositorio, la región y el bucket. Usa un rol exclusivo para este despliegue, con una política de permisos separada de su política de confianza.
1. Registra a GitHub como proveedor OIDC en IAM
En IAM, crea un proveedor de identidad OpenID Connect con URL https://token.actions.githubusercontent.com y audiencia sts.amazonaws.com. Son los valores documentados por GitHub para AWS. Después crea un rol que permita sts:AssumeRoleWithWebIdentity a ese proveedor.
2. Restringe la política de confianza
La condición aud indica para qué servicio se emitió el token; sub identifica el origen del workflow. Este ejemplo es para un repositorio que usa el formato de sujeto con identificadores inmutables:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
"token.actions.githubusercontent.com:sub": "repo:ORG@OWNER_ID/REPO@REPO_ID:ref:refs/heads/main"
}
}
}]
}
Sustituye todos los valores de ejemplo. Detalle importante en 2026: GitHub documenta que los repositorios creados después del 15 de julio de 2026, o aquellos que activaron la opción, incluyen los ID inmutables de propietario y repositorio en sub. Los anteriores pueden conservar el formato repo:ORG/REPO:ref:refs/heads/main. Si el job usa un entorno de GitHub, el sujeto cambia a la forma repo:ORG/REPO:environment:NOMBRE (con los ID cuando corresponda). Verifica qué formato aplica antes de copiar la política. Evita comodines que permitan asumir el rol desde otros repositorios o ramas. Consulta los formatos actuales de GitHub y las recomendaciones de IAM.
3. Concede solo el permiso que necesita el job
La confianza responde quién puede asumir el rol; la política de permisos responde qué puede hacer. Para subir un objeto a una ruta de ejemplo, una política mínima sería:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::mi-bucket-demo/public/*"
}]
}
Adapta el recurso a tu bucket real. Si tu despliegue necesita listar, borrar o invalidar una CDN, agrega únicamente esas acciones y recursos tras comprobarlo. No concedas acceso general a * por comodidad.
4. Solicita credenciales temporales desde el workflow
Guarda este archivo como .github/workflows/deploy.yml. Cambia la cuenta, el nombre del rol, la región y el bucket. La acción oficial intercambia el token OIDC por credenciales AWS; aws sts get-caller-identity confirma qué rol asumió el job sin imprimir credenciales.
name: Publicar sitio
on:
push:
branches: [main]
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: aws-actions/configure-aws-credentials@v6.3.0
with:
role-to-assume: arn:aws:iam::123456789012:role/gha-deploy-demo
aws-region: us-east-1
- run: aws sts get-caller-identity
- run: aws s3 cp ./public/index.html s3://mi-bucket-demo/public/index.html
El ejemplo usa las versiones indicadas en la documentación de la acción oficial de AWS. En producción, revisa las acciones de terceros y considera fijarlas a un commit aprobado por tu equipo.
Prueba el caso correcto y el caso denegado
- Desde
main, comprueba que el job asume el rol esperado y solo puede subir al prefijo autorizado. - Desde otra rama o repositorio, comprueba que no puede asumirlo. Si AWS devuelve
AccessDenied, revisa primeroaud,suby el nombre del entorno. - Si el rol se asume pero falla S3, revisa la política de permisos y la ruta del objeto: es otra capa de autorización.
- No actives este rol en jobs que ejecutan código de contribuciones externas sin revisar. Protege la rama y, si usas entornos, aplica sus reglas de despliegue.
Cuando el flujo funcione, elimina la antigua clave persistente de GitHub Secrets y revócala en IAM. Así el beneficio no se queda en el diagrama: desaparece una credencial de larga duración que ya no necesitas administrar.



