En corto
| |
Y en el workflow:
| |
Los roles que necesite el pipeline (Artifact Registry, Cloud Run, GKE…) se los das a github-actions@… como a cualquier service account.
Por qué
La alternativa clásica es exportar una llave JSON del service account y guardarla como secreto en GitHub. Esa llave no caduca, cualquiera con acceso al repo o a los logs puede copiarla, y rotarla es un trabajo manual que nadie hace. Con Workload Identity Federation GitHub emite un token OIDC de corta vida para cada job, Google lo verifica contra el issuer de GitHub, comprueba tu attribute condition y entrega credenciales temporales del service account. No hay secreto que guardar ni rotar, y puedes limitar quién entra hasta el nivel de repo o rama.
Las piezas
| Pieza | Qué es |
|---|---|
Pool (github) | Contenedor de identidades externas; uno por proveedor basta |
Proveedor OIDC (github-oidc) | Confía en https://token.actions.githubusercontent.com y mapea claims del token (repository, repository_owner, actor, ref) a atributos |
| Attribute condition | Filtro CEL sobre esos claims. Sin ella, cualquier repo de GitHub podría intentar entrar al pool; el README oficial pide ponerla siempre |
Binding workloadIdentityUser | Qué identidades del pool pueden hacerse pasar por el service account: attribute.repository/my-org/my-repo, o attribute.repository_owner/my-org para toda la organización |
auth@v3 | Cambia el token de GitHub por credenciales de Google y las deja configuradas para gcloud, los SDK y Terraform |
Para restringir a una rama, mapea el claim y úsalo en la condición y en el binding:
| |
Con Terraform
El módulo oficial hace pool, proveedor y bindings en un bloque:
| |
El output es exactamente el valor que va en workload_identity_provider del workflow.
Sin service account
auth@v3 también admite federación directa: el principalSet recibe roles IAM sin pasar por un service account (workload_identity_provider y project_id, sin service_account). Menos piezas, pero no todos los servicios aceptan principales federados; para Artifact Registry, GCS y la mayoría de APIs sí, y es el camino que Google recomienda para casos nuevos.
Trampas
id-token: writeenpermissionsdel job. Sin él,authfalla con “Unable to get ACTIONS_ID_TOKEN_REQUEST_URL”.- Número de proyecto, no ID, en la ruta del proveedor y del
principalSet:projects/123456789012/…. Permission 'iam.serviceAccounts.getAccessToken' denied: falta el bindingroles/iam.workloadIdentityUsero elattribute.repositoryno coincide (mayúsculas y nombre exacto del repo).- La condición debe referirse a claims mapeados: si usas
assertion.refen la condición sin haberlo mapeado a un atributo, el proveedor se crea pero nunca casa. - Forks y PRs externos: los tokens de un PR desde un fork llevan
repositorydel fork; una condición porrepository_ownerlos deja fuera, que suele ser lo que quieres. - Rotación: no hay nada que rotar, pero sí que revisar.
gcloud iam workload-identity-pools providers describey los logs de auditoría de STS dicen quién está entrando.
Referencia: google-github-actions/auth y Workload Identity Federation en la documentación de Google Cloud.