
Tradizionalmente, per usare servizi come Google Cloud da un ambiente non-GCP (ad esempio una pipeline CI/CD di GitLab), gli sviluppatori dovevano affidarsi a chiavi di service account o ad altre credenziali a lunga durata per autenticarsi ai servizi Google Cloud. Un approccio che però comporta diversi rischi di sicurezza:
- Esposizione prolungata delle credenziali: le chiavi di service account sono credenziali a lunga durata, in genere valide finché non vengono revocate o ruotate manualmente. Conservarle nei repository del codice sorgente, nei file di configurazione o negli ambienti CI/CD aumenta il rischio di accessi non autorizzati in caso di compromissione.
- Privilege escalation: le chiavi di service account hanno spesso permessi molto ampi, pensati per svolgere svariate attività in Google Cloud. Se un attaccante riesce a impossessarsene, può raggiungere un ventaglio di risorse ben più esteso di quanto richiesto dalla singola applicazione o dal singolo workload.
- Gestione delle credenziali: ruotare regolarmente le chiavi di service account è una best practice fondamentale, ma la rotazione manuale è laboriosa e soggetta a errori, con il rischio concreto di lasciare falle nella sicurezza.
- Auditing e accountability limitati: con le chiavi di service account è spesso complicato attribuire un'azione specifica a un singolo utente o servizio. Questa scarsa granularità ostacola le attività di audit e rende più difficile risalire all'origine delle azioni.
La Workload Identity Federation di GCP risponde proprio a queste criticità: permette di sfruttare l'identity provider (IdP) già in uso per autenticarsi su Google Cloud Platform (GCP). Una soluzione particolarmente comoda per le pipeline GitLab, perché consente di usare le credenziali GitLab per autenticarsi su GCP senza dover gestire service account o credenziali separati.
I componenti chiave della Workload Identity Federation di GCP sono:
- Identity provider (IdP): è il sistema che autentica gli utenti e ne rilascia le credenziali. GCP supporta diversi identity provider, come Active Directory Federation Services (ADFS), Okta, Azure Active Directory o qualsiasi altro provider compatibile con OpenID Connect (OIDC) o SAML 2.0.
- Workload identity pool: un'entità che consente di gestire le identità esterne. Conviene creare un pool dedicato per ciascun ambiente non-Google Cloud che debba accedere alle risorse Google Cloud.
- Service account: in GCP i service account rappresentano i workloads. Per accedere alle risorse, le identità del pool devono ottenere l'autorizzazione su un service account: una volta concessa, queste identità potranno accedere a tutti i servizi Google Cloud raggiungibili da quel service account.
- Federated token: è un token rilasciato dall'IdP e scambiato con un token di service account. Il federated token consente al workload di autenticarsi su GCP impersonando il service account.
In questo articolo vediamo come configurare la Workload Identity Federation in GCP e accedere in modo sicuro ai servizi GCP usando token a breve durata nelle pipeline GitLab.
Prerequisiti
- Verifichi di disporre dei ruoli Workload Identity Pool Admin (
roles/iam.workloadIdentityPoolAdmin) e Service Account Admin (roles/iam.serviceAccountAdmin) sul progetto. - Abiliti le seguenti API.
#Update $GCP_PROJECT_ID valuegcloud services enable cloudresourcemanager.googleapis.com \iam.googleapis.com \iamcredentials.googleapis.com \sts.googleapis.com \--project $GCP_PROJECT_ID- Un account GitLab. Se necessario, ne crei uno nuovo.
Configurare la Workload Identity Federation
- Step 1: crei 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

configurazione del workload identity pool
- Step 2: aggiunga un workload identity pool provider per GitLab e usi le attribute conditions per limitare quali identità possono autenticarsi tramite il workload identity pool.
- La configurazione di attribute mapping è un tassello fondamentale del setup della workload identity federation. Permette di mappare gli attributi delle credenziali di autenticazione rilasciate da un identity provider esterno sugli attributi di Google Cloud, come
subjectedemail. Alcuni identity provider chiamano questi attributi "claims". - Ogni identity provider esterno può esporre attributi diversi. Per AWS, Google fornisce mapping di default che coprono la maggior parte degli scenari più comuni. È inoltre possibile definire mapping personalizzati.
- Per i provider OIDC come GitLab, i mapping vanno forniti manualmente. Per costruirli, consulti la documentazione del provider con l'elenco degli attributi presenti nelle credenziali. Per GitLab, faccia riferimento all'ID Token payload per i claim inclusi in ciascun ID token GitLab.
L'attribute condition seguente limita l'accesso alle sole identità del mio namespace GitLab personale. Consulti la documentazione su Gitlab Namespace per capire se sta visualizzando un namespace di gruppo o personale.
#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
esempio di output del comando gcloud

provider GitLab aggiunto al workload identity pool

configurazione dell'identity provider GitLab
- A questo punto è possibile autenticarsi da un job GitLab CI/CD verso Google Cloud, ma non si dispone ancora di alcun permesso su Google Cloud (autorizzazione).
- Step 3: crei un service account che l'identità esterna GitLab possa impersonare.
#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- Step 4: conceda all'identità esterna GitLab i permessi per impersonare il service account, in modo che un job GitLab CI/CD possa autorizzarsi su Google Cloud tramite Service Account impersonation. Questo step assegna il permesso IAM sul service account stesso, conferendo all'identità esterna l'autorità di operare come tale service account.
Il comando seguente consente a tutte le identità del pool di accedere alle risorse GCP tramite service account impersonation; raccomandiamo però di limitare l'impersonation a specifiche identità esterne in base ai loro attributi.
Faccia riferimento a https://cloud.google.com/iam/docs/workload-identity-federation#impersonation per gli scenari più comuni di assegnazione dei ruoli.
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/*"
service account collegato al workload identity pool
Testare la Workload Identity Federation in una GitLab Pipeline
Negli step precedenti abbiamo configurato il workload identity pool perché si fidi delle identità del mio namespace GitLab personale. Non serve modificare la configurazione del Suo account GitLab: è possibile abilitare la workload identity federation per i singoli job CI/CD e adattare il setup alle proprie esigenze.
- Step 5: crei un progetto GitLab vuoto oppure ne usi uno esistente.

repo GitLab
- Step 6: crei un file chiamato
.gitlab-ci.ymle configuri una pipeline GitLab a partire dal template seguente. Per approfondire le pipeline GitLab, consulti la documentazione sulle pipeline 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
- PER IMPOSTAZIONE PREDEFINITA, le pipeline GitLab CI/CD si avviano automaticamente al push di nuovi commit. Controlli l'output della pipeline in Build -> Pipelines.

stato di avvio della pipeline GitLab

esempio di log di un job GitLab
Il log del job conferma che autenticazione e autorizzazione hanno funzionato come previsto, grazie al token a breve durata generato dalla Workload Identity Federation.
In sintesi, la Workload Identity Federation è un servizio di grande valore per mettere in sicurezza le Sue pipeline GitLab e rafforzare la security posture. Se non la sta ancora utilizzando, le consigliamo di adottarla nelle Sue pipeline al posto delle chiavi di service account.