Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Sicher auf Google Cloud Services in GitLab Pipelines zugreifen – mit Workload Identity Federation

By Chimbu ChinnaduraiSep 1, 20236 min read

Diese Seite ist auch in English, Español, Français, Italiano, 日本語 und Português verfügbar.

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

Bisher mussten Entwickler beim Zugriff auf Google Cloud aus einer Nicht-GCP-Umgebung (z. B. einer CI/CD-Umgebung wie GitLab Pipelines) auf Service-Account-Keys oder andere langlebige Anmeldedaten zurückgreifen, um sich gegenüber Google Cloud Services zu authentifizieren. Dieser Ansatz bringt jedoch einige Sicherheitsrisiken mit sich:

  • Langfristig exponierte Anmeldedaten: Service-Account-Keys sind langlebige Credentials, die typischerweise so lange gültig sind, bis sie manuell widerrufen oder rotiert werden. Werden diese Keys in Source-Code-Repositories, Konfigurationsdateien oder CI/CD-Umgebungen abgelegt, steigt das Risiko unbefugten Zugriffs, sobald eine dieser Umgebungen kompromittiert wird.
  • Privilegieneskalation: Service-Account-Keys verfügen häufig über weitreichende Berechtigungen, um verschiedenste Aufgaben innerhalb von Google Cloud auszuführen. Erlangt ein Angreifer Zugriff auf einen solchen Key, kann er auf eine Vielzahl von Ressourcen zugreifen – oft weit über das hinaus, was für eine bestimmte Anwendung oder einen einzelnen Workload nötig wäre.
  • Verwaltung von Anmeldedaten: Eine regelmäßige Rotation der Service-Account-Keys gehört zu den zentralen Sicherheits-Best-Practices. Eine manuelle Rotation ist jedoch aufwändig und fehleranfällig – mit der Folge potenzieller Sicherheitslücken.
  • Eingeschränkte Auditierbarkeit und Nachvollziehbarkeit: Bei der Verwendung von Service-Account-Keys lässt sich nur schwer feststellen, welche konkrete Person oder welcher Service eine bestimmte Aktion ausgelöst hat. Diese fehlende Granularität erschwert Audits und macht es schwerer, Aktionen bis zu ihrem Ursprung zurückzuverfolgen.

GCP Workload Identity Federation setzt genau an diesen Sicherheitsbedenken an und ermöglicht es Ihnen, Ihren bestehenden Identity Provider (IdP) zur Authentifizierung gegenüber der Google Cloud Platform (GCP) zu nutzen. Für GitLab Pipelines ist das besonders praktisch: Sie können Ihre GitLab-Anmeldedaten verwenden, um sich gegenüber GCP zu authentifizieren – ganz ohne separate Service Accounts oder Credentials verwalten zu müssen.

Die zentralen Komponenten der GCP Workload Identity Federation:

  • Identity Provider (IdP): Der IdP ist das System, das Nutzer authentifiziert und ihnen Anmeldedaten ausstellt. GCP unterstützt verschiedene Identity Provider wie Active Directory Federation Services (ADFS), Okta, Azure Active Directory oder jeden Identity Provider, der OpenID Connect (OIDC) oder SAML 2.0 unterstützt.
  • Workload Identity Pool: Eine Entität, über die Sie externe Identitäten verwalten. Wir empfehlen, für jede Nicht-Google-Cloud-Umgebung, die auf Google-Cloud-Ressourcen zugreifen soll, einen eigenen Pool anzulegen.
  • Service Account: In GCP repräsentieren Service Accounts Workloads. Damit Pool-Identitäten auf Ressourcen zugreifen können, müssen ihnen Zugriffsrechte auf einen Service Account erteilt werden. Anschließend können diese Identitäten auf alle Google Cloud Services zugreifen, auf die der Service Account ebenfalls Zugriff hat.
  • Federated Token: Ein Federated Token wird vom IdP ausgestellt und gegen ein Service-Account-Token eingetauscht. Mit dem Federated Token kann sich der Workload als der jeweilige Service Account gegenüber GCP authentifizieren.

In diesem Blogpost zeigen wir Ihnen, wie Sie Workload Identity Federation in GCP einrichten und über kurzlebige Tokens in GitLab Pipelines sicher auf GCP-Services zugreifen.

Voraussetzungen

  • Stellen Sie sicher, dass Sie im Projekt über die Rollen Workload Identity Pool Admin (roles/iam.workloadIdentityPoolAdmin) und Service Account Admin (roles/iam.serviceAccountAdmin) verfügen.
  • Aktivieren Sie die folgenden APIs.
#Update $GCP_PROJECT_ID value
gcloud services enable cloudresourcemanager.googleapis.com \
iam.googleapis.com \
iamcredentials.googleapis.com \
sts.googleapis.com \
--project $GCP_PROJECT_ID
  • Ein GitLab-Konto. Falls noch nicht vorhanden, legen Sie ein neues Konto an.

Workload Identity Federation einrichten

  • Schritt 1: Legen Sie einen Workload Identity Pool an.
#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

Konfiguration des Workload Identity Pools

  • Schritt 2: Fügen Sie einen Workload Identity Pool Provider für GitLab hinzu und nutzen Sie Attribute Conditions, um einzuschränken, welche Identitäten sich über den Workload Identity Pool authentifizieren dürfen.
  • Die Konfiguration des Attribute Mappings ist ein zentraler Bestandteil beim Einrichten der Workload Identity Federation. Damit lassen sich Attribute aus den vom externen Identity Provider ausgestellten Anmeldedaten auf Google-Cloud-Attribute wie subject und email abbilden. Manche Identity Provider bezeichnen diese Attribute als Claims.
  • Jeder externe Identity Provider kann unterschiedliche Attribute bereitstellen. Für AWS liefert Google Standard-Mappings, die die meisten gängigen Szenarien abdecken. Sie können auch eigene Mappings hinterlegen.
  • Bei OIDC-Providern wie GitLab geben Sie die Mappings selbst an. Eine Liste der verfügbaren Attribute finden Sie in der jeweiligen Provider-Dokumentation. Für GitLab finden Sie die Claims jedes ID-Tokens im ID Token Payload.

Die folgende Attribute Condition beschränkt die Identitäten ausschließlich auf meinen persönlichen GitLab-Namespace. Über GitLab Namespace lässt sich ermitteln, ob es sich um einen Gruppen- oder einen persönlichen Namespace handelt.

#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

Beispielausgabe des gcloud-Befehls

pipeline

GitLab-Provider zum Workload Identity Pool hinzugefügt

gitlab

Konfiguration des GitLab Identity Providers

  • Damit können Sie sich nun aus einem GitLab-CI/CD-Job heraus gegenüber Google Cloud authentifizieren. Allerdings haben Sie in Google Cloud noch keinerlei Berechtigungen (Autorisierung).
  • Schritt 3: Erstellen Sie einen Service Account, den die externe GitLab-Identität per Impersonation übernehmen kann.
#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
  • Schritt 4: Erteilen Sie der externen GitLab-Identität die Berechtigung, den Service Account zu impersonieren. So kann ein GitLab-CI/CD-Job über Service-Account-Impersonation Zugriff auf Google Cloud erhalten. In diesem Schritt wird die IAM-Berechtigung direkt auf dem Service Account selbst gesetzt, sodass die externe Identität im Namen dieses Service Accounts agieren darf.

Der folgende Befehl erlaubt allen Identitäten im Pool, per Service-Account-Impersonation auf GCP-Ressourcen zuzugreifen. Wir empfehlen jedoch, die Impersonation anhand bestimmter Attribute auf konkrete externe Identitäten einzuschränken.

Gängige Szenarien zur Vergabe von Rollen finden Sie unter https://cloud.google.com/iam/docs/workload-identity-federation#impersonation.

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

Service Account mit dem Workload Identity Pool verbunden

Workload Identity Federation in der GitLab Pipeline testen

In den vorherigen Schritten haben wir den Workload Identity Pool so konfiguriert, dass er den Identitäten aus meinem persönlichen GitLab-Namespace vertraut. In Ihrem GitLab-Konto sind keine Konfigurationsänderungen erforderlich – Sie können Workload Identity Federation für einzelne CI/CD-Jobs aktivieren. Das Setup lässt sich an Ihre Anforderungen anpassen.

  • Schritt 5: Legen Sie ein leeres GitLab-Projekt an oder verwenden Sie ein bestehendes.

gitlab

GitLab-Repository

  • Schritt 6: Erstellen Sie eine Datei namens .gitlab-ci.yml und richten Sie eine GitLab Pipeline mit dem folgenden Template ein. Mehr zu GitLab Pipelines erfahren Sie unter CI/CD pipelines.
#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

  • STANDARDMÄSSIG werden GitLab-CI/CD-Pipelines automatisch ausgeführt, sobald neue Commits gepusht werden. Die Pipeline-Ausgabe finden Sie unter Build -> Pipelines.

gcp

Status des GitLab-Pipeline-Triggers

workload

Beispielhaftes GitLab-Job-Log

Das Job-Log zeigt: Authentifizierung und Autorisierung haben mit dem im Rahmen der Workload Identity Federation erzeugten kurzlebigen Token wie erwartet funktioniert.

Unterm Strich ist Workload Identity Federation ein wertvoller Service, mit dem Sie Ihre GitLab Pipelines absichern und Ihre Security-Posture verbessern. Wenn Sie Workload Identity Federation noch nicht einsetzen, kann ich Ihnen nur empfehlen, in Ihren Pipelines darauf zu setzen – statt auf Service-Account-Keys.