
Pour exploiter des services comme Google Cloud depuis un environnement non-GCP (par exemple un environnement CI/CD comme les pipelines GitLab), les développeurs ont longtemps dû recourir à des clés de compte de service ou à d'autres identifiants à longue durée de vie pour s'authentifier auprès des services Google Cloud. Cette approche présente toutefois plusieurs risques de sécurité :
- Exposition prolongée des identifiants : les clés de compte de service ont une durée de vie longue, généralement valides jusqu'à leur révocation ou rotation manuelle. Stocker ces clés dans des dépôts de code source, des fichiers de configuration ou des environnements CI/CD accroît le risque d'accès non autorisé en cas de compromission de ces dépôts ou environnements.
- Élévation de privilèges : les clés de compte de service disposent souvent de permissions étendues, conçues pour couvrir diverses tâches au sein de Google Cloud. Si un attaquant met la main sur une clé, il peut accéder à un large éventail de ressources, bien au-delà de ce qu'exige une application ou un workload donné.
- Gestion des identifiants : la rotation régulière des clés de compte de service est indispensable pour respecter les bonnes pratiques de sécurité. Or, effectuée manuellement, elle se révèle fastidieuse et sujette aux erreurs, ce qui peut ouvrir la porte à des failles.
- Audit et traçabilité limités : avec des clés de compte de service, il est souvent difficile d'attribuer une action précise à un utilisateur ou à un service. Ce manque de granularité freine les efforts d'audit et complique la traçabilité des actions jusqu'à leur origine.
La Workload Identity Federation de GCP répond à ces enjeux de sécurité : elle vous permet de réutiliser votre fournisseur d'identité (IdP) existant pour vous authentifier auprès de Google Cloud Platform (GCP). C'est particulièrement pratique pour les pipelines GitLab, puisque vous pouvez utiliser vos identifiants GitLab pour accéder à GCP, sans avoir à gérer des comptes de service ou des identifiants distincts.
Les principaux composants de la Workload Identity Federation de GCP :
- Fournisseur d'identité (IdP) : l'IdP est le système qui authentifie les utilisateurs et leur délivre des identifiants. GCP prend en charge de nombreux fournisseurs : Active Directory Federation Services (ADFS), Okta, Azure Active Directory, ou tout fournisseur compatible avec OpenID Connect (OIDC) ou SAML 2.0.
- Workload identity pool : entité qui permet de gérer les identités externes. Nous recommandons de créer un pool dédié pour chaque environnement non-Google Cloud devant accéder aux ressources Google Cloud.
- Compte de service : dans GCP, les comptes de service servent à représenter des workloads. Pour accéder aux ressources, les identités du pool doivent obtenir un accès à un compte de service. Une fois ajoutées, ces identités pourront accéder à tous les services Google Cloud auxquels le compte de service a lui-même accès.
- Jeton fédéré : jeton émis par l'IdP et échangé contre un jeton de compte de service. Le jeton fédéré permet au workload de s'authentifier auprès de GCP en endossant le compte de service.
Dans cet article, nous verrons comment configurer la Workload Identity Federation dans GCP et accéder de manière sécurisée aux services GCP via des jetons éphémères dans les pipelines GitLab.
Prérequis
- Assurez-vous de disposer des rôles Workload Identity Pool Admin (
roles/iam.workloadIdentityPoolAdmin) et Service Account Admin (roles/iam.serviceAccountAdmin) sur le projet. - Activez les API ci-dessous.
#Update $GCP_PROJECT_ID valuegcloud services enable cloudresourcemanager.googleapis.com \iam.googleapis.com \iamcredentials.googleapis.com \sts.googleapis.com \--project $GCP_PROJECT_ID- Un compte GitLab. Créez-en un nouveau si nécessaire.
Mise en place de la Workload Identity Federation
- Étape 1 : créez un Workload Identity Pool.
#Update $GCP_PROJECT_ID valuegcloud iam workload-identity-pools create gitlab-demo-wip \ --location="global" \ --description="Gitlab demo workload Identity pool" \ --display-name="gitlab-demo-wip" --project=$GCP_PROJECT_ID
workload identity pool

configuration du workload identity pool
- Étape 2 : ajoutez un fournisseur de workload identity pool pour GitLab et utilisez les conditions d'attributs pour restreindre les identités autorisées à s'authentifier via le workload identity pool.
- La configuration du mappage d'attributs est un élément clé de la mise en place de la Workload Identity Federation. Elle permet de mapper les attributs des identifiants émis par un fournisseur d'identité externe vers des attributs Google Cloud, comme
subjectetemail. Certains fournisseurs d'identité parlent de claims pour désigner ces attributs. - Chaque fournisseur d'identité externe expose ses propres attributs. Pour AWS, Google fournit des mappages par défaut qui couvrent la plupart des cas d'usage. Vous pouvez également définir des mappages personnalisés.
- Pour les fournisseurs OIDC comme GitLab, c'est à vous de définir les mappages. Pour les construire, consultez la documentation du fournisseur afin d'obtenir la liste des attributs disponibles dans ses identifiants. Pour GitLab, référez-vous au payload du jeton d'identité pour connaître les claims inclus dans chaque jeton.
La condition d'attribut ci-dessous limite l'accès aux seules identités issues de mon namespace GitLab personnel. Consultez la documentation Gitlab Namespace pour savoir si vous travaillez sur un namespace de groupe ou personnel.
#Update GITLAB_NAMESPACE_PATH valuegcloud iam workload-identity-pools providers create-oidc gitlab-identity-provider --location="global" \ --workload-identity-pool="gitlab-demo-wip" \ --issuer-uri="https://gitlab.com" \ --allowed-audiences=https://gitlab.com \ --attribute-mapping="google.subject=assertion.sub,attribute.aud=assertion.aud,attribute.project_path=assertion.project_path,attribute.project_id=assertion.project_id,attribute.namespace_id=assertion.namespace_id,attribute.namespace_path=assertion.namespace_path,attribute.user_email=assertion.user_email,attribute.ref=assertion.ref,attribute.ref_type=assertion.ref_type" \ --attribute-condition="assertion.namespace_path.startsWith(\"$GITLAB_NAMESPACE_PATH\")" \ --project=$GCP_PROJECT_ID
exemple de résultat de commande gcloud

fournisseur gitlab ajouté au workload identity pool

configuration du fournisseur d'identité gitlab
- À ce stade, vous pouvez vous authentifier depuis un job GitLab CI/CD vers Google Cloud, mais vous ne disposez d'aucune permission sur Google Cloud (autorisation).
- Étape 3 : créez un compte de service que l'identité externe gitlab pourra usurper (impersonation).
#Create a service accountgcloud iam service-accounts create gitlab-wif-demo --project=$GCP_PROJECT_ID
#Add sample permissions to the Service accountgcloud projects add-iam-policy-binding $GCP_PROJECT_ID \ --member=serviceAccount:gitlab-wif-demo@${GCP_PROJECT_ID}.iam.gserviceaccount.com \ --role=roles/storage.admin- Étape 4 : accordez à l'identité externe gitlab les permissions nécessaires pour usurper le compte de service, afin qu'un job GitLab CI/CD puisse autoriser ses appels Google Cloud par impersonation. Cette étape attribue une permission IAM directement sur le compte de service, donnant à l'identité externe le droit d'agir en son nom.
La commande ci-dessous autorise toutes les identités du pool à accéder aux ressources GCP via l'impersonation, mais nous recommandons de la restreindre à des identités externes spécifiques en fonction de leurs attributs.
Consultez https://cloud.google.com/iam/docs/workload-identity-federation#impersonation pour les scénarios courants d'attribution de rôles.
PROJECT_NUMBER=$(gcloud projects describe $(gcloud config get-value core/project) --format=value\(projectNumber\) --project $GCP_PROJECT_ID)
gcloud iam service-accounts add-iam-policy-binding gitlab-wif-demo@${GCP_PROJECT_ID}.iam.gserviceaccount.com \ --role=roles/iam.workloadIdentityUser \ --member="principalSet://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/gitlab-demo-wip/*"
compte de service relié au workload identity pool
Tester la Workload Identity Federation dans un pipeline GitLab
Dans les étapes précédentes, nous avons configuré le workload identity pool pour qu'il fasse confiance aux identités issues de mon namespace GitLab personnel. Aucune modification n'est requise dans votre compte GitLab : vous pouvez activer la Workload Identity Federation au cas par cas, pour des jobs CI/CD individuels, et adapter la configuration à vos besoins.
- Étape 5 : créez un projet GitLab vide ou réutilisez un projet existant.

dépôt gitlab
- Étape 6 : créez un fichier nommé
.gitlab-ci.ymlet configurez un pipeline GitLab à partir du modèle ci-dessous. Pour en savoir plus, consultez la documentation des pipelines CI/CD.
#Update the $GCP_PROJECT_NAME and $GCP_PROJECT_NUMBER valuesvariables: GCP_PROJECT_NAME: $GCP_PROJECT_NAME GCP_WORKLOAD_IDENTITY_PROVIDER: "projects/$GCP_PROJECT_NUMBER/locations/global/workloadIdentityPools/gitlab-demo-wip/providers/gitlab-identity-provider" SERVICE_ACCOUNT_EMAIL: "gitlab-wif-demo@$GCP_PROJECT_NAME.iam.gserviceaccount.com"
stages: - gcp_wif_demo
.gcp_wif_auth: &gcp_wif_auth #id_tokens to create JSON web tokens (JWT) to authenticate with third party services.This replaces the CI_JOB_JWT_V2 id_tokens: GITLAB_OIDC_TOKEN: aud: https://gitlab.com before_script: - apt-get update && apt-get install -yq jq #Get temporary credentials using the ID token - | PAYLOAD=$(cat <<EOF { "audience": "//iam.googleapis.com/${GCP_WORKLOAD_IDENTITY_PROVIDER}", "grantType": "urn:ietf:params:oauth:grant-type:token-exchange", "requestedTokenType": "urn:ietf:params:oauth:token-type:access_token", "scope": "https://www.googleapis.com/auth/cloud-platform", "subjectTokenType": "urn:ietf:params:oauth:token-type:jwt", "subjectToken": "${GITLAB_OIDC_TOKEN}" } EOF ) - | FEDERATED_TOKEN=$(curl -s -X POST "https://sts.googleapis.com/v1/token" \ --header "Accept: application/json" \ --header "Content-Type: application/json" \ --data "${PAYLOAD}" \ | jq -r '.access_token' ) #Use the federated token to impersonate the service account linked to workload identity pool #The resulting access token is stored in CLOUDSDK_AUTH_ACCESS_TOKEN environment variable and this will be passed to the gcloud CLI - | export CLOUDSDK_AUTH_ACCESS_TOKEN=$(curl -s -X POST "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/${SERVICE_ACCOUNT_EMAIL}:generateAccessToken" \ --header "Accept: application/json" \ --header "Content-Type: application/json" \ --header "Authorization: Bearer ${FEDERATED_TOKEN}" \ --data '{"scope": ["https://www.googleapis.com/auth/cloud-platform"]}' \ | jq -r '.accessToken' )
gcloud_test: <<: *gcp_wif_auth stage: gcp_wif_demo image: gcr.io/google.com/cloudsdktool/google-cloud-cli:441.0.0 script: - gcloud config set project ${GCP_PROJECT_NAME} - gcloud storage ls
.gitlab-ci.yml
- PAR DÉFAUT, les pipelines GitLab CI/CD se déclenchent automatiquement à chaque nouveau commit poussé. Consultez la sortie du pipeline dans Build -> Pipelines.

statut de déclenchement du pipeline gitlab

exemple de log de job gitlab
Les logs du job confirment que l'authentification et l'autorisation ont fonctionné comme prévu, avec le jeton éphémère généré par la Workload Identity Federation.
En résumé, la Workload Identity Federation est un service précieux pour sécuriser vos pipelines GitLab et renforcer votre posture de sécurité. Si vous ne l'utilisez pas encore, nous vous encourageons à l'adopter dans vos pipelines à la place des clés de compte de service.