Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Accès sécurisé aux services Google Cloud dans vos pipelines GitLab grâce à Workload Identity Federation

By Chimbu ChinnaduraiSep 1, 20236 min read

Cette page est également disponible en English, Deutsch, Español, Italiano, 日本語 et Português.

Secure-access-to-GCP-services-in-GitLab-Pipelines-with-Workload-Identity-Federation-DoiT-International

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 value
gcloud 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 value
gcloud 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

gitlab-ci-cd

workload identity pool

gitlab

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 subject et email. 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 value
gcloud 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

ci

exemple de résultat de commande gcloud

pipeline

fournisseur gitlab ajouté au workload identity pool

gitlab

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 account
gcloud iam service-accounts create gitlab-wif-demo --project=$GCP_PROJECT_ID
#Add sample permissions to the Service account
gcloud 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/*"

gitlab

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.

gitlab

dépôt gitlab

  • Étape 6 : créez un fichier nommé .gitlab-ci.yml et 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 values
variables:
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

workload

.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.

gcp

statut de déclenchement du pipeline gitlab

workload

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.