Gitlab CI 透過 GCP Workload Identity Federation 進行部署

2025/11/15

GCP Workload Identity Federation

 

本篇情境為使用 Gitlab CI 透過 GCP workload identity

以 service account 身份使用 gcloud command 操作 cloud storage 

 

使用 console 設定 Workload Identity Pool / Provider

Pool就不多說,名稱、ID、敘述即可建立

而 Provider (Identity Provider) 則是都建立在這個 Pool 底下

 

Provider 基本設定(ref)

這邊可參考 Gitlab 提供的文件

gcp-workload-identity-provider-basic-configuration

 

Provider attribute 設定(ref)

這邊稍微複雜

簡單來說就是把 Gitlab OIDC token claim 設定

跟 GCP Workload Identity 做好 mapping

以供後續做條件限制設定(attribute condition)

一開始可以設定簡單一點

  • google.subject <-> assertion.sub
  • attribute.project_path <-> assertion.project_path

 

後續如果要做更複雜的設定

可以參考 Gitlab OIDC 提供的 custom claims

後面限制就可以指定 namespace / ref / 指定 user 來操作

  • attribute.namespace_path <-> assertion.namespace_path
  • attribute.ref <-> assertion.ref
  • attibute.user_email <-> assertion.user_email

 

provider-attribute-mapping-configuration

 

Provider attribute condition 設定(ref)

像這樣設定就可以限制只有指定的 project 才能操作 service account

這邊使用的是 Google 規範的 CEL expression 

assertion.project_path in ['ciao-lab/workload-identity-demo']

workload-identity-provider-attibute-condition-configuration

 

建立完成就會長這樣

workload-identity-created-result

 

允許 workload identity pool 存取 service account (ref)

存取權管理方式有很多種

可加入單一身份、整個 group 等許多方式

我這邊只綁進單一 service account 示範

讓 workload identity provider principal 可使用 roles/iam.workloadIdentityUser role 存取 service account

principal 格式可參考上方文件中的 principal type

這邊使用格式為 principalSet://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/${LOCATION}/workloadIdentityPools/${POOL_ID}/*

workload-identity-access-service-account

 

設定 service account 可存取 GCP 資源的權限

這邊單純只是要測試是否有權限可代表 service account 操作 GCP 資源

因此我就很簡單的建立一個 bucket 名稱為 ciao-sandbox-bucket

並在裡面放幾個測試檔案

接著讓 service account 可讀取這個 bucket 內的檔案 (storage object viewer role)

方便待會在 gitlab ci 測試用

grant-access-to-service-account-for-view-objects-of-cloud-storage-bucket

 

Gitlab CI 測試存取(ref)

在 gitlab ci 中使用 gcloud auth login --cred-file command 以 service account 身份

並執行簡單的 gcloud 操作(查看指定 bucket 內的 objects)

 

stages:
  - deploy

workload-identity:
  stage: deploy
  image: google/cloud-sdk:slim
  id_tokens:
    GITLAB_OIDC_TOKEN:
      aud: https://gitlab.com
  variables:
    GCP_PROJECT_ID: your-project-name
    GCP_PROJECT_NUMBER: your-project-number
    POOL_ID: web-service-deployment-pool
    PROVIDER_ID: gitlab
    SERVICE_ACCOUNT_EMAIL: gcs-readonly-sa@example.iam.gserviceaccount.com
    WORKLOAD_IDENTITY_PROVIDER: projects/$GCP_PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/providers/$PROVIDER_ID
  script:
    - echo $WORKLOAD_IDENTITY_PROVIDER
    - echo "$GITLAB_OIDC_TOKEN" > .gitlab_oidc_token_file
    - |
      cat > .gcp_temp_cred.json <<JSON
      {
        "type":"external_account",
        "audience":"//iam.googleapis.com/projects/$GCP_PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/providers/$PROVIDER_ID",
        "subject_token_type":"urn:ietf:params:oauth:token-type:jwt",
        "token_url":"https://sts.googleapis.com/v1/token",
        "service_account_impersonation_url":"https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/$SERVICE_ACCOUNT_EMAIL:generateAccessToken",
        "credential_source":{"file":".gitlab_oidc_token_file"}
      }
      JSON
    - cat .gcp_temp_cred.json
    - gcloud auth login --cred-file=$(pwd)/.gcp_temp_cred.json --project=$GCP_PROJECT_ID
    - gcloud auth list
    - rm -f .gcp_temp_cred.json
    - gcloud storage ls --recursive gs://ciao-sandbox-bucket

 

相關資訊

 

參考影片