Les clés de comptes de service stockées en tant que secrets CI/CD sont une source courante de fuites de credentials dans les environnements GCP. Elles persistent longtemps après que le pipeline qui en avait besoin a changé, sont copiées sur des machines locales pour les tests, et quand elles fuient — suite à un accident de dépôt, un runner CI compromis ou un log inadvertant — elles fonctionnent depuis n’importe où jusqu’à leur rotation.
La Workload Identity Federation (WIF) élimine la clé. Au lieu de stocker une credential, les systèmes CI s’authentifient via leur mécanisme d’identité natif (tokens OIDC) et échangent cela contre des credentials GCP de courte durée à la demande.
Comment ça fonctionne
Le flux :
- GitHub Actions (ou GitLab CI, etc.) génère un token OIDC de courte durée prouvant « Je suis le workflow X dans le dépôt Y, déclenché par l’événement Z »
- Ce token est échangé avec le Workload Identity Pool de GCP contre un token d’accès GCP de courte durée
- Le token d’accès est limité au compte de service configuré
- Le token expire au bout d’une heure — il ne peut pas être réutilisé hors de cette fenêtre
Pas de fichier de clé. Pas de secret à faire tourner. La credential est générée à chaque exécution de pipeline et expire automatiquement.
Configuration pour GitHub Actions
Le côté GCP nécessite un Workload Identity Pool et un Provider :
# Créer le pool d'identitégcloud iam workload-identity-pools create github \ --project=YOUR_PROJECT_ID \ --location=global \ --display-name="GitHub Actions Pool"
# Ajouter GitHub comme provider OIDCgcloud iam workload-identity-pools providers create-oidc github \ --project=YOUR_PROJECT_ID \ --location=global \ --workload-identity-pool=github \ --display-name="GitHub Actions Provider" \ --attribute-mapping="google.subject=assertion.sub,attribute.repository=assertion.repository" \ --issuer-uri="https://token.actions.githubusercontent.com"L’attribute-mapping traduit les claims du token OIDC de GitHub en attributs GCP. assertion.repository devient un attribut utilisable dans les conditions — essentiel pour s’assurer que seuls les dépôts autorisés peuvent utiliser ce pool.
Accorder au compte de service l’accès depuis le pool, restreint à des dépôts spécifiques :
gcloud iam service-accounts add-iam-policy-binding \ wlif-github-actions@YOUR_PROJECT_ID.iam.gserviceaccount.com \ --project=YOUR_PROJECT_ID \ --role="roles/iam.workloadIdentityUser" \ --member="principalSet://iam.googleapis.com/projects/YOUR_PROJECT_NUMBER/locations/global/workloadIdentityPools/github/attribute.repository/your-org/your-repo"Le binding principalSet limite l’accès à un dépôt spécifique. Un token compromis provenant d’un autre dépôt de la même organisation GitHub ne peut pas usurper l’identité de ce compte de service.
Le workflow GitHub Actions
Une fois le côté GCP configuré, le workflow tient en trois lignes :
permissions: id-token: write # Requis pour la génération du token OIDC contents: read
jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
- uses: google-github-actions/auth@v2 with: workload_identity_provider: 'projects/YOUR_PROJECT_NUMBER/locations/global/workloadIdentityPools/github/providers/github' service_account: 'wlif-github-actions@YOUR_PROJECT_ID.iam.gserviceaccount.com'
- name: Run dbt run: dbt run --target prodL’action google-github-actions/auth gère l’échange du token OIDC. Après son exécution, toutes les étapes suivantes du job disposent des credentials GCP via les Application Default Credentials — le même mécanisme que tout SDK GCP utilise.
Nommage du compte de service
En suivant la convention de nommage par workload, le préfixe wlif- marque ce compte comme un compte de service Workload Identity Federation. Cela le rend immédiatement identifiable dans les logs d’audit et les listings de politiques IAM. Quand wlif-github-actions apparaît dans une requête BigQuery JOBS, on sait que c’est un pipeline CI en cours d’exécution contre la production.
Créer des comptes de service distincts pour des pipelines distincts :
wlif-github-actions@project.iam.gserviceaccount.com— pour les déploiements d’applicationswlif-dbt-ci@project.iam.gserviceaccount.com— pour les runs CI dbtwlif-terraform-ci@project.iam.gserviceaccount.com— pour les modifications d’infrastructure
Chacun obtient uniquement les permissions dont son pipeline a besoin. Le compte de service CI dbt a besoin de bigquery.dataViewer pour exécuter les tests ; il n’a pas besoin de bigquery.dataEditor. Le compte Terraform CI a besoin des permissions d’administration IAM ; le compte dbt, certainement pas.
GitLab CI et autres plateformes
GitHub Actions est le cas le plus courant, mais WIF prend en charge tout provider d’identité compatible OIDC. GitLab, CircleCI et la plupart des autres plateformes CI prennent en charge l’authentification OIDC contre des providers externes.
La configuration GCP est quasi identique — créer un provider OIDC pointant vers l’endpoint de token de la plateforme, configurer le mapping d’attributs pour les claims pertinents (dépôt, projet, branche), et lier l’accès au compte de service à des valeurs d’attribut spécifiques.
La configuration côté workflow varie selon la plateforme. Consulter la documentation de la plateforme pour savoir comment générer des tokens OIDC et les transmettre aux services externes. L’invariant clé : on échange toujours un token natif à la plateforme contre des credentials GCP de courte durée, sans jamais stocker de clé.
Que faire des clés existantes
Une fois WIF configuré et fonctionnel, les clés de comptes de service existantes peuvent être supprimées. Pas tournées — supprimées. Elles ne sont plus nécessaires.
# Lister les clés pour le compte de servicegcloud iam service-accounts keys list \ --iam-account=wlif-github-actions@YOUR_PROJECT_ID.iam.gserviceaccount.com \ --filter="keyType=USER_MANAGED"
# Supprimer chaque clé (remplacer KEY_ID par l'ID de clé réel)gcloud iam service-accounts keys delete KEY_ID \ --iam-account=wlif-github-actions@YOUR_PROJECT_ID.iam.gserviceaccount.comExécuter l’audit des clés de comptes de service après la migration de tous les pipelines pour confirmer qu’il ne reste aucune clé. L’état cible est zéro clé gérée par l’utilisateur sur tous les comptes de service workload.