Dos direcciones de confianza#
Conectar un proveedor Git con la nube implica dos relaciones de confianza distintas. En una, un sistema externo (tu CI, una plataforma de despliegue) necesita leer tus repositorios. En la otra, ese sistema necesita actuar en tu cuenta de AWS: subir imágenes, actualizar servicios o sincronizar un bucket.
Durante años la receta habitual fue una clave SSH personal para Git y un par de access keys de un usuario IAM pegado en la plataforma o en los secretos del CI. Funciona, pero deja credenciales de larga duración repartidas por varios sistemas.
Esta guía muestra la alternativa moderna para cada dirección: OpenID Connect (OIDC) para que GitHub Actions obtenga credenciales temporales de AWS sin guardar ninguna llave, y claves de solo lectura o GitHub Apps para dar acceso mínimo a los repositorios.
Por qué evitar access keys#
Las access keys son credenciales de larga duración asociadas a un usuario IAM: un Access key ID y un Secret access key que no caducan por sí solos. AWS recomienda como buena práctica usar credenciales temporales, como roles IAM, en lugar de crear access keys, y revisar las alternativas antes de generarlas.
- Si se filtran (en un log, un fork o una captura), funcionan hasta que alguien las desactive.
- Hay que rotarlas a mano y AWS solo muestra el secret una vez, al crearlas.
- Cada sistema que las guarda es un lugar más que proteger.
Con OIDC, cada ejecución del workflow recibe un token firmado por GitHub, lo intercambia por credenciales de AWS válidas durante un tiempo limitado y no queda nada que rotar.
Documentación: AWS IAM · Access keys ↗ · AWS IAM · Gestionar access keys ↗ · AWS IAM · Buenas prácticas ↗
Cómo funciona OIDC entre GitHub y AWS#
- El job de GitHub Actions pide a GitHub un token JWT; para eso necesita el permiso id-token: write.
- El token incluye claims sobre quién lo pide, como el repositorio, la rama o el environment, en el claim sub, y la audiencia en aud.
- La acción configure-aws-credentials presenta el token a AWS STS para asumir un rol (AssumeRoleWithWebIdentity).
- IAM compara los claims con las condiciones de la trust policy del rol. Si coinciden, STS devuelve credenciales temporales; si no, el job falla.
La seguridad depende por completo de esas condiciones. GitHub exige definir al menos una para que repositorios no confiables no puedan obtener tokens para tu nube, e IAM recomienda evaluar siempre el claim sub.
Documentación: GitHub · Acerca de OIDC ↗ · GitHub · OIDC con AWS ↗
Configurar AWS: proveedor y rol#
Primero agrega GitHub como proveedor de identidad OIDC en IAM, con la URL https://token.actions.githubusercontent.com y la audiencia sts.amazonaws.com (la que usa la acción oficial). Se hace una vez por cuenta.
Después crea un rol con una trust policy que fije organización, repositorio y, mejor aún, el environment de GitHub:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::111122223333: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:mi-org/mi-repo:environment:prod"
}
}
}
]
}Evita comodines amplios como repo:mi-org/* salvo que de verdad quieras que cualquier repositorio de la organización asuma el rol. Adjunta al rol solo los permisos del despliegue, y usa un rol distinto por ambiente.
Atención a un cambio reciente: en repositorios creados después del 15 de julio de 2026, o que hayan optado por ello, el sub incluye identificadores inmutables de propietario y repositorio (por ejemplo repo:mi-org@123456/mi-repo@456789:...). Comprueba qué formato usa tu repositorio antes de escribir la condición.
Documentación: AWS IAM · Crear un proveedor OIDC ↗ · AWS IAM · Rol para OIDC y GitHub ↗ · GitHub · Claims inmutables en OIDC ↗
El workflow de GitHub Actions#
# .github/workflows/deploy.yml
name: deploy
on:
push:
branches: [main]
permissions:
id-token: write # permite pedir el token OIDC (no da permisos de escritura)
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
environment: prod # debe coincidir con el sub de la trust policy
steps:
- uses: actions/checkout@v7
- uses: aws-actions/configure-aws-credentials@v6
with:
role-to-assume: arn:aws:iam::111122223333:role/github-deploy-prod
aws-region: us-east-1
- run: aws sts get-caller-identity # comprueba el rol asumidoSi configuras el environment prod en GitHub con reglas de protección, como revisores obligatorios o ramas permitidas, esa aprobación se convierte también en requisito para obtener credenciales de producción, porque el rol solo acepta tokens de ese environment.
Documentación: configure-aws-credentials ↗ · GitHub · Environments ↗ · AWS CLI · sts get-caller-identity ↗
Errores comunes#
- Not authorized to perform sts:AssumeRoleWithWebIdentity: casi siempre el sub no coincide. Un job con environment emite environment:NOMBRE, no ref:refs/heads/RAMA.
- El job no puede pedir el token: falta permissions id-token: write en el workflow o en el job.
- Trust policy con solo aud: cualquier repositorio de GitHub podría intentar asumir el rol. Añade siempre el sub.
- Workflows con pull_request_target o runners no efímeros: el README de la acción advierte tener especial cuidado, porque pueden ejecutar código no confiable con acceso a credenciales.
Documentación: GitHub · OIDC con AWS ↗ · configure-aws-credentials ↗
La otra dirección: acceso de lectura a tus repositorios#
Si una plataforma externa necesita clonar tus repositorios, dale el acceso mínimo. Las opciones principales, de más amplia a más acotada:
| Opción | Alcance | Notas |
|---|---|---|
| Clave SSH en tu cuenta personal | Todo lo que tu usuario puede leer y escribir | Solo para pruebas; se rompe si esa persona deja la organización. |
| Usuario máquina (GitHub) | Repositorios asignados en la organización | Solo las organizaciones pueden limitarlo a lectura; GitHub permite una cuenta así para automatización. |
| Deploy key (GitHub, GitLab) o access key (Bitbucket) | Un repositorio (Bitbucket: varios) | Puede ser de solo lectura; en Bitbucket las access keys son siempre de lectura. |
| GitHub App | Repositorios donde se instala, con permisos finos | Tokens de instalación que caducan en 1 hora; no consume un asiento de usuario. |
Cuando registres una clave pública que te entregó una plataforma, verifica que sea la correcta comparando su huella con la que muestra tu proveedor: guárdala en un archivo y ejecuta ssh-keygen -lf archivo.pub.
Documentación: GitHub · Deploy keys y machine users ↗ · GitHub · Cuándo usar una GitHub App ↗ · GitHub · Tokens de instalación ↗ · Bitbucket · Access keys ↗ · GitLab · Deploy keys ↗ · OpenSSH · ssh-keygen ↗ · GitHub · Revisar claves SSH ↗
Checklist#
- Proveedor OIDC de GitHub creado en cada cuenta de AWS que recibe despliegues.
- Un rol por ambiente, con aud y sub fijados a repositorio y environment.
- Permisos del rol limitados a lo que hace el despliegue.
- Ninguna access key de AWS en los secretos del repositorio.
- Acceso de lectura a repositorios con deploy keys, access keys o una GitHub App, no con claves personales.
Fuentes y alcance
Documentación consultada el 25 de septiembre de 2026. Los ejemplos y criterios de decisión son propuestas editoriales; adáptalos al contrato de tu aplicación y valídalos en tu entorno de pruebas autorizado.
- AWS IAM · Access keys ↗
- AWS IAM · Gestionar access keys ↗
- AWS IAM · Buenas prácticas ↗
- GitHub · Acerca de OIDC ↗
- GitHub · OIDC con AWS ↗
- AWS IAM · Crear un proveedor OIDC ↗
- AWS IAM · Rol para OIDC y GitHub ↗
- GitHub · Claims inmutables en OIDC ↗
- configure-aws-credentials ↗
- GitHub · Environments ↗
- AWS CLI · sts get-caller-identity ↗
- GitHub · Deploy keys y machine users ↗
- GitHub · Cuándo usar una GitHub App ↗
- GitHub · Tokens de instalación ↗
- Bitbucket · Access keys ↗
- GitLab · Deploy keys ↗
- OpenSSH · ssh-keygen ↗
- GitHub · Revisar claves SSH ↗
Compara soluciones cloud
Revisa tarifas, límites, condiciones y fuentes de cada opción.
Abrir comparador