透過 AWS 或 Azure 設定 Workload Identity 聯盟

本指南說明如何使用 Workload Identity Federation,讓 AWS 和 Azure 工作負載向 Google Cloud 進行驗證,不必使用服務帳戶金鑰

透過 Workload Identity Federation,在 AWS EC2 和 Azure 上執行的工作負載可以將環境專屬憑證換成短期 Google CloudSecurity Token Service 權杖。

特定環境的憑證包括:

  • AWS EC2 執行個體可使用執行個體設定檔要求臨時憑證
  • Azure VM 可使用受控識別取得 Azure 存取權權杖。

設定 Workload Identity 聯盟後,這些工作負載就能以這些環境專屬的憑證,換取短期 Google Cloud 憑證。工作負載可使用這些短期憑證存取Google Cloud API。

事前準備

  • 設定驗證方法。

    Select the tab for how you plan to use the samples on this page:

    Console

    When you use the Google Cloud console to access Google Cloud services and APIs, you don't need to set up authentication.

    gcloud

      In the Google Cloud console, activate Cloud Shell.

      Activate Cloud Shell

      At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

      Python

      如要在本機開發環境中使用本頁的 Python 範例,請安裝並初始化 gcloud CLI,然後使用使用者憑證設定應用程式預設憑證。

      1. Install the Google Cloud CLI.

      2. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

      3. To initialize the gcloud CLI, run the following command:

        gcloud init
      4. If you're using a local shell, then create local authentication credentials for your user account:

        gcloud auth application-default login

        You don't need to do this if you're using Cloud Shell.

        If an authentication error is returned, and you are using an external identity provider (IdP), confirm that you have signed in to the gcloud CLI with your federated identity.

      詳情請參閱 Google Cloud 驗證說明文件中的「 為本機開發環境設定 ADC」。

準備外部識別資訊提供者

每個 Microsoft Entra ID 租戶或 AWS 帳戶只需執行一次這些步驟。

AWS

您不需要在 AWS 帳戶中進行任何設定變更。

設定工作負載身分集區,信任您的 AWS 帳戶後,AWS 使用者AWS 角色就能使用永久或暫時的 AWS 安全性憑證,取得短期 Google Cloud 憑證。

Azure

您必須在 Microsoft Entra ID 用戶群中建立新的 Microsoft Entra ID 應用程式,並設定該應用程式,以便用於工作負載身分識別聯盟。

設定工作負載身分集區以信任應用程式後,Azure 使用者和服務主體就能為該應用程式要求存取權杖,並以這些存取權杖換取短期 Google Cloud 憑證。

如要建立應用程式,請按照下列步驟操作:

  1. 建立 Microsoft Entra ID 應用程式和服務主體

  2. 為應用程式設定應用程式 ID URI。 您可以使用預設的應用程式 ID URI (APPID),也可以指定自訂 URI。

    稍後設定工作負載身分集區提供者時,需要應用程式 ID URI。

如要讓應用程式取得 Microsoft Entra ID 應用程式的存取權杖,可以使用受管理的身分

  1. 建立受管理的身分。 記下受控識別的物件 ID。稍後設定模擬時會用到。

  2. 將受管理的身分指派給虛擬機器或其他執行應用程式的資源。

設定 Workload Identity 聯盟

每個 AWS 帳戶或 Microsoft Entra ID 租戶只需執行一次這些步驟。然後,您就能在多個工作負載和多個 Google Cloud 專案中使用相同的工作負載身分識別集區和提供者。

如要開始設定 Workload Identity 聯盟,請按照下列步驟操作:

  1. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  2. 建議您 使用專案管理 workload identity pool 和提供者
  3. Make sure that billing is enabled for your Google Cloud project.

  4. Enable the IAM, Resource Manager, Service Account Credentials, and Security Token Service APIs.

    Enable the APIs

定義屬性對應和條件

AWS 或 Azure 工作負載的環境專屬憑證包含多個屬性,您必須決定要在 Google Cloud中使用哪個屬性做為主體 ID (google.subject)。

Google Cloud 會使用 Cloud 稽核記錄和主體 ID 中的主體 ID,不重複地識別 AWS 或 Azure 使用者或角色。

你也可以視需要對應其他屬性。 授予資源存取權時,您可以參考這些額外屬性。

AWS

屬性對應可以使用GetCallerIdentity 的回應欄位做為來源屬性。這些欄位包括:

  • account:AWS 帳戶號碼。
  • arn:外部實體的 AWS ARN。
  • userid:呼叫實體的專屬 ID。

如果應用程式是在附加角色的 Amazon Elastic Compute Cloud (EC2) 執行個體上執行,則可以使用下列屬性對應:

google.subject=assertion.arn
attribute.account=assertion.account
attribute.aws_role=assertion.arn.extract('assumed-role/{role}/')
attribute.aws_ec2_instance=assertion.arn.extract('assumed-role/{role_and_session}').extract('/{session}')

對應會執行下列作業:

  • 使用 ARN 做為主體 ID,例如: "arn:aws:sts::000000000000:assumed-role/ec2-my-role/i-00000000000000000
  • 導入自訂屬性 account,並指派 AWS 帳戶 ID
  • 導入自訂屬性 aws_role,並指派 AWS 角色名稱,例如:ec2-my-role
  • 導入自訂屬性 aws_ec2_instance,並指派 EC2 執行個體 ID 給該屬性,例如:i-00000000000000000

透過這項對應,您可以授予下列項目的存取權:

  • 特定 EC2 執行個體:

    principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/attribute.aws_ec2_instance/EC2_INSTANCE_ID
    

  • 角色中的所有使用者和執行個體:

    principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/attribute.aws_role/ROLE_NAME
    

Azure

屬性對應可使用內嵌在 Azure 存取權杖中的聲明 (包括自訂聲明) 做為來源屬性。在大多數情況下,最好使用 sub 聲明做為主體 ID:

google.subject=assertion.sub
當 `sub` 宣告超過 google.subject 的 127 個字元限制時,建議使用 [`extract` 函式](/iam/docs/conditions-attribute-reference#extract)衍生有意義的宣告,做為主體 ID:
google.subject=assertion.sub.extract('/eid1/c/pub/t/{sub_claim}')

如果是發給受控識別項的存取權杖,sub 聲明會包含受控識別項的物件 ID。如果您使用其他聲明,請確認該聲明是專屬聲明,且無法重新指派。

如果不確定可以參考哪些聲明,請按照下列步驟操作:

  1. 連線至已指派受控識別的 Azure VM。

  2. Azure 執行個體中繼資料服務 (IMDS) 取得存取權杖:

    Bash

    curl \
      "http://169.254.169.254/metadata/identity/oauth2/token?resource=APP_ID_URI&api-version=2018-02-01" \
      -H "Metadata: true" | jq -r .access_token
    

    這項指令會使用 jq 工具。Cloud Shell 預設提供 jq

    PowerShell

    $SubjectTokenType = "urn:ietf:params:oauth:token-type:jwt"
    $SubjectToken = (Invoke-RestMethod `
      -Uri "http://169.254.169.254/metadata/identity/oauth2/token?resource=APP_ID_URI&api-version=2018-02-01" `
      -Headers @{Metadata="true"}).access_token
    Write-Host $SubjectToken
    

    APP_ID_URI 替換為您為 Workload Identity 聯盟設定的應用程式應用程式 ID URI

  3. 在網路瀏覽器中前往 https://jwt.ms/,然後將存取權杖貼到欄位中。

  4. 按一下「Claims」,即可查看存取權權杖中內嵌的聲明清單。

如果是服務身分,通常不需要為 google.groups 或任何自訂屬性建立對應。

視需要定義屬性條件。屬性條件是 CEL 運算式,可檢查聲明屬性和目標屬性。如果屬性條件評估結果為 true,系統就會接受該憑證。否則系統會拒絕認證。

AWS

您可以使用屬性條件,限制哪些 IAM 使用者和角色可使用 Workload Identity Federation 取得短期權杖 Google Cloud。

舉例來說,下列條件會限制 AWS 角色存取權,並禁止其他 IAM 識別碼

assertion.arn.startsWith('arn:aws:sts::AWS_ACCOUNT_ID:assumed-role/')

Azure

您可以使用屬性條件,限制哪些使用者和服務主體可使用 Workload Identity Federation 取得短期 Google Cloud權杖。或者,您也可以設定 Microsoft Entra ID 應用程式,使用應用程式角色指派

建立工作負載身分集區和提供者

必要的角色

如要取得設定 Workload Identity 聯盟所需的權限,請要求管理員授予您專案的下列 IAM 角色:

如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和機構的存取權」。

您或許還可透過自訂角色或其他預先定義的角色取得必要權限。

或者,IAM 擁有者 (roles/owner) 基本角色也包含設定身分識別聯盟的權限。您不應在正式版環境中授予基本角色,但可以在開發或測試環境中授予。

您現在已收集建立 workload identity pool 和提供者所需的所有資訊:

主控台

  1. 前往 Google Cloud 控制台的「New workload provider and pool」(新的工作負載供應商和集區) 頁面。

    前往「New workload provider and pool」(新增工作負載提供者和集區)

  2. 在「建立身分集區」部分中,輸入下列內容:

    • 名稱:集區名稱。這個名稱也會用來做為集區 ID。 集區 ID 設定後即無法變更。
    • 說明:說明集區用途的文字。
  3. 按一下「繼續」

  4. 設定提供者設定:

    AWS

    設定下列提供者設定:

    • 選取供應商AWS
    • 供應商名稱:供應商的名稱。這個名稱也會做為提供者 ID。供應商 ID 設定後即無法變更。

    Azure

    設定下列提供者設定:

    • 選取供應商OpenID Connect (OIDC)
    • 供應商名稱:供應商的名稱。這個名稱也會做為提供者 ID。供應商 ID 設定後即無法變更。
    • 簽發者網址https://sts.windows.net/TENANT_ID。 將 TENANT_ID 替換為 Microsoft Entra ID 租戶的租戶 ID (GUID)。
    • 允許的對象:您在 Microsoft Entra ID 註冊應用程式時使用的應用程式 ID URI
  5. 按一下「繼續」

  6. 在「設定供應商屬性」部分,新增先前識別的屬性對應

  7. 在「屬性條件」部分,輸入您先前識別的屬性條件。如果沒有屬性條件,請將這個欄位留空。

  8. 按一下「儲存」,建立 workload identity pool 和提供者。

gcloud

  1. 建立新的 workload identity pool:

    gcloud iam workload-identity-pools create POOL_ID \
        --location="global" \
        --description="DESCRIPTION" \
        --display-name="DISPLAY_NAME"
    

    更改下列內容:

    • POOL_ID:集區的專屬 ID。
    • DISPLAY_NAME:集區名稱。
    • DESCRIPTION:集區的說明。授予集區身分的存取權時會顯示這項說明。
  2. 新增工作負載身分集區提供者:

    AWS

    如要為 AWS 建立 workload identity pool 提供者,請執行下列指令:

    gcloud iam workload-identity-pools providers create-aws PROVIDER_ID \
      --location="global" \
      --workload-identity-pool="POOL_ID" \
      --account-id="ACCOUNT_ID" \
      --attribute-mapping="MAPPINGS" \
      --attribute-condition="CONDITIONS"
    

    更改下列內容:

    範例:

    gcloud iam workload-identity-pools providers create-aws example-provider \
      --location="global" \
      --workload-identity-pool="pool-1" \
      --account-id="123456789000" \
      --attribute-mapping="google.subject=assertion.arn"

    Azure

    如要為 Azure 建立 workload identity pool 提供者,請執行下列指令:

    gcloud iam workload-identity-pools providers create-oidc PROVIDER_ID \
        --location="global" \
        --workload-identity-pool="POOL_ID" \
        --issuer-uri="ISSUER_URI" \
        --allowed-audiences="APPLICATION_ID_URI" \
        --attribute-mapping="MAPPINGS" \
        --attribute-condition="CONDITIONS"
    

    更改下列內容:

    • PROVIDER_ID:供應商的專屬 ID。
    • POOL_ID:集區的 ID。
    • ISSUER_URI:Microsoft Entra ID 租戶的租戶 ID (GUID),有時格式為 https://sts.windows.net/TENANT_ID。核發者 URI 可能會有所不同,如要找出核發者 URI,可以使用 JWT.io 偵錯 JWT。
    • APPLICATION_ID_URI您在 Microsoft Entra ID 註冊應用程式時使用的「應用程式 ID URI」
    • MAPPINGS:以逗號分隔的屬性對應清單,也就是您先前識別的屬性。
    • CONDITIONS:(選用) 先前識別的屬性條件

    範例:

    gcloud iam workload-identity-pools providers create-oidc example-provider \
        --location="global" \
        --workload-identity-pool="pool-1" \
        --issuer-uri="https://sts.windows.net/00000000-1111-2222-3333-444444444444" \
        --allowed-audiences="api://my-app" \
        --attribute-mapping="google.subject=assertion.sub,google.groups=assertion.groups"

驗證工作負載

您必須為每個工作負載執行這些步驟一次。

允許外部工作負載存取 Google Cloud 資源

如要授予工作負載資源存取權,建議您直接授予主體資源存取權。 Google Cloud 在本例中,主體是聯合使用者。部分 Google Cloud 產品有 Google Cloud API 限制。如果工作負載呼叫的 API 端點設有限制,您可以改用服務帳戶模擬功能。在本例中,主體是Google Cloud 服務帳戶,也就是身分。您授予資源的服務帳戶存取權。

直接存取資源

您可以使用 Google Cloud 控制台或 gcloud CLI,直接在資源上授予聯盟身分存取權。

控制台

如要使用 Google Cloud 控制台直接在資源上授予 IAM 角色,請前往資源頁面,然後授予角色。下列範例說明如何前往 Cloud Storage 頁面,並直接在 Cloud Storage bucket 上,將「Storage 物件檢視者」(roles/storage.objectViewer) 角色授予同盟身分。

  1. 在 Google Cloud 控制台,前往「Cloud Storage bucket」頁面。

    前往「Buckets」(值區) 頁面

  2. 在 bucket 清單中,點選要授予角色的 bucket 名稱。

  3. 選取靠近頁面上方的 [Permissions] (權限) 分頁標籤。

  4. 按一下「授予存取權」按鈕。

    系統會顯示「新增主體」對話方塊。

  5. 在「New principals」(新增主體) 欄位中,輸入需要存取值區的一或多個身分。

    依科目

    principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/SUBJECT
    

    更改下列內容:

    • PROJECT_NUMBER:專案編號
    • POOL_ID:工作負載集區 ID
    • SUBJECT:從 IdP 對應的個別主體,例如 administrator@example.com

    依群組

    principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/group/GROUP
    

    更改下列內容:

    • PROJECT_NUMBER:專案編號
    • WORKLOAD_POOL_ID:工作負載集區 ID
    • :從 IdP 對應的群組,例如: administrator-group@example.comGROUP

    依屬性

    principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/attribute.ATTRIBUTE_NAME/ATTRIBUTE_VALUE
    

    更改下列內容:

    • PROJECT_NUMBER:專案編號
    • WORKLOAD_POOL_ID:工作負載集區 ID
    • ATTRIBUTE_NAME:從 IdP 對應的其中一個屬性
    • ATTRIBUTE_VALUE:屬性的值
  6. 從「Select a role」(請選取角色) 下拉式選單中選取一或多個角色。您選取的角色會顯示在面板中,系統還會針對這些角色所授予的權限提供簡短說明。

  7. 按一下 [儲存]

gcloud

如要使用 gcloud CLI 授予專案中資源的 IAM 角色,請執行下列操作:

  1. 取得定義資源的專案編號。

    gcloud projects describe $(gcloud config get-value core/project) --format=value\(projectNumber\)
    
  2. 授予資源存取權。

    如要使用 gcloud CLI 將 Storage 物件檢視者 (roles/storage.objectViewer) 角色授予符合特定條件的外部身分,請執行下列指令。

    依科目

    gcloud storage buckets add-iam-policy-binding BUCKET_ID \
        --role=roles/storage.objectViewer \
        --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/SUBJECT"

    依群組

    gcloud storage buckets add-iam-policy-binding BUCKET_ID \
        --role=roles/storage.objectViewer \
        --member="principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/group/GROUP"

    依屬性

    gcloud storage buckets add-iam-policy-binding BUCKET_ID \
        --role=roles/storage.objectViewer \
        --member="principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/attribute.ATTRIBUTE_NAME/ATTRIBUTE_VALUE"

    更改下列內容:

    • BUCKET_ID:要授予存取權的值區
    • PROJECT_NUMBER:含有 workload identity pool 的專案專案編號
    • POOL_ID:工作負載身分集區的集區 ID
    • SUBJECT您已對應google.subject 的屬性預期值
    • GROUP您已對應google.groups 的屬性預期值
    • ATTRIBUTE_NAME屬性對應中的自訂屬性名稱
    • ATTRIBUTE_VALUE:屬性對應中自訂屬性的值

    您可以在任何支援 IAM 允許政策的 Google Cloud 資源上授予角色。

服務帳戶模擬

  1. 如要為外部工作負載建立服務帳戶,請按照下列步驟操作:

    1. Enable the IAM, Security Token Service, and Service Account Credentials APIs.

      Enable the APIs

    2. 建立服務帳戶,代表工作負載。建議您為每個工作負載使用專屬服務帳戶。服務帳戶不必與工作負載身分集區位於同一專案,但您必須參照包含服務帳戶的專案。

    3. 授予服務帳戶存取權,允許外部身分存取資源。

  2. 如要允許聯合身分模擬服務帳戶,請執行下列操作:

控制台

如要使用 Google Cloud 控制台,將 IAM 角色授予具有服務帳戶的同盟身分,請按照下列步驟操作:

同一專案中的服務帳戶

  1. 如要使用服務帳戶模擬功能,為同一專案中的服務帳戶授予存取權,請執行下列步驟:

    1. 前往「Workload Identity Pools」(工作負載身分集區) 頁面。

      前往「Workload Identity Pools」(工作負載身分集區)

    2. 選取「授予存取權」

    3. 在「授予服務帳戶存取權」對話方塊中,選取「透過服務帳戶模擬功能授予存取權」

    4. 在「服務帳戶」清單中,選取要讓外部身分模擬的服務帳戶,然後執行下列操作:

    5. 如要選擇集區中的哪些身分可以模擬服務帳戶,請執行下列其中一項操作:

      • 如要只允許工作負載身分識別集區的特定身分模擬服務帳戶,請選取「只顯示符合篩選條件的身分」

      • 在「屬性名稱」清單中,選取要篩選的屬性。

      • 在「屬性值」欄位中,輸入屬性的預期值;舉例來說,如果您使用屬性對應 google.subject=assertion.sub,請將「屬性」名稱設為 subject,並將「屬性值」設為外部身分識別提供者核發的權杖中 sub 聲明的值。

    6. 如要儲存設定,請依序按一下「儲存」和「關閉」

其他專案中的服務帳戶

  1. 如要使用服務帳戶模擬功能,為其他專案中的服務帳戶授予存取權,請按照下列步驟操作:

    1. 前往「Service Accounts」(服務帳戶) 頁面

      前往「Service Accounts」(服務帳戶) 頁面

    2. 選取要模擬的服務帳戶。

    3. 按一下「管理存取權」

    4. 按一下「新增主體」

    5. 在「New principal」(新增主體) 欄位中,輸入下列其中一個主體 ID,以指定集區中的身分,這些身分將模擬服務帳戶。

      依科目

      principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/SUBJECT
      

      更改下列內容:

      • PROJECT_NUMBER:專案編號
      • POOL_ID:工作負載集區 ID
      • SUBJECT:從 IdP 對應的個別主體,例如 administrator@example.com

      依群組

      principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/group/GROUP
      

      更改下列內容:

      • PROJECT_NUMBER:專案編號
      • WORKLOAD_POOL_ID:工作負載集區 ID
      • :從 IdP 對應的群組,例如: administrator-group@example.comGROUP

      依屬性

      principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/attribute.ATTRIBUTE_NAME/ATTRIBUTE_VALUE
      

      更改下列內容:

      • PROJECT_NUMBER:專案編號
      • WORKLOAD_POOL_ID:工作負載集區 ID
      • ATTRIBUTE_NAME:從 IdP 對應的其中一個屬性
      • ATTRIBUTE_VALUE:屬性的值

      依集區

      principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/*
      

      更改下列內容:

      • PROJECT_NUMBER:專案編號
      • WORKLOAD_POOL_ID:工作負載集區 ID
    6. 在「Select a role」(選取角色) 欄位,選取 Workload Identity User 角色 (roles/iam.workloadIdentityUser)。

    7. 如要儲存設定,請按一下「儲存」

gcloud

如要將 Workload Identity 使用者角色 (roles/iam.workloadIdentityUser) 授予已同盟主體或主體集,請執行下列指令。如要進一步瞭解 Workload Identity 聯盟主體 ID,請參閱「主體類型」。

依科目

gcloud iam service-accounts add-iam-policy-binding SERVICE_ACCOUNT_EMAIL \
    --role=roles/iam.workloadIdentityUser \
    --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/SUBJECT"

依群組

gcloud iam service-accounts add-iam-policy-binding SERVICE_ACCOUNT_EMAIL \
    --role=roles/iam.workloadIdentityUser \
    --member="principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/group/GROUP"

依屬性

gcloud iam service-accounts add-iam-policy-binding SERVICE_ACCOUNT_EMAIL \
    --role=roles/iam.workloadIdentityUser \
    --member="principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/attribute.ATTRIBUTE_NAME/ATTRIBUTE_VALUE"

更改下列內容:

  • SERVICE_ACCOUNT_EMAIL: 服務帳戶的電子郵件地址
  • PROJECT_NUMBER:含有 workload identity pool 的專案專案編號
  • POOL_ID:工作負載身分集區的集區 ID
  • SUBJECT您已對應google.subject 的屬性預期值
  • GROUP您已對應google.groups 的屬性預期值
  • ATTRIBUTE_NAME屬性對應中的自訂屬性名稱
  • ATTRIBUTE_VALUE:屬性對應中自訂屬性的值

下載或建立憑證設定

Cloud 用戶端程式庫、gcloud CLI 和 Terraform 可以自動取得外部憑證,並使用這些憑證模擬服務帳戶。如要讓程式庫和工具完成這項程序,您必須提供憑證設定檔。這個檔案定義了下列項目:

  • 如何取得外部憑證
  • 要使用的 workload identity pool 和提供者
  • 要模擬哪個服務帳戶

如要建立憑證設定檔,請按照下列步驟操作:

主控台

如要在 Google Cloud 控制台中下載憑證設定檔,請按照下列步驟操作:

  1. 前往 Google Cloud 控制台的「Workload Identity Pools」頁面。

    前往「Workload Identity Pools」(工作負載身分集區)

  2. 找出要使用的 IdP 的工作負載身分集區,然後按一下。

  3. 如果您選擇使用直接資源存取權,請按照下列步驟操作:

    1. 按一下「授予存取權」

    2. 選取「使用聯合身分授予存取權 (建議)」

    3. 點選 [下載]

    4. 請按照操作說明,繼續設定「設定應用程式」對話方塊,這項程序稍後會說明。

  4. 如果您選擇使用服務帳戶模擬,請完成下列步驟:

    1. 選取「已連結的服務帳戶」

    2. 找到要使用的服務帳戶,然後按一下「下載」

    3. 請按照操作說明,繼續設定「設定應用程式」對話方塊,這項程序稍後會說明。

  5. 在「設定應用程式」對話方塊中,選取包含外部身分識別的提供者。

  6. 提供下列其他設定:

    AWS

    無須額外設定。

    Azure

    應用程式 ID 網址:Azure 應用程式的應用程式 ID URI

  7. 選取「下載設定」,下載憑證設定檔,然後按一下「關閉」

gcloud

如要使用 gcloud iam workload-identity-pools create-cred-config 建立憑證設定檔,請按照下列步驟操作:

AWS

如要建立憑證設定檔,讓程式庫從 EC2 執行個體中繼資料取得存取權杖,請按照下列步驟操作:

gcloud iam workload-identity-pools create-cred-config \
    projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID \
    --service-account=SERVICE_ACCOUNT_EMAIL \
    --service-account-token-lifetime-seconds=SERVICE_ACCOUNT_TOKEN_LIFETIME \
    --aws \
    --output-file=FILEPATH.json

更改下列內容:

  • PROJECT_NUMBER:包含 workload identity pool 的專案專案編號
  • POOL_ID:工作負載身分集區的 ID。
  • PROVIDER_ID:工作負載身分集區提供者的 ID。
  • SERVICE_ACCOUNT_EMAIL:如果您使用服務帳戶模擬功能,請改用服務帳戶的電子郵件地址。如果您未使用服務帳戶模擬功能,請省略這個旗標。
  • SERVICE_ACCOUNT_TOKEN_LIFETIME:如果您使用服務帳戶模擬,請以服務帳戶存取權杖的生命週期 (以秒為單位) 取代;如果未提供,預設為一小時。如果您未使用服務帳戶模擬功能,請省略這個旗標。如要指定超過一小時的生命週期,請設定constraints/iam.allowServiceAccountCredentialLifetimeExtension 機構政策限制
  • FILEPATH:要儲存設定的檔案。

如果您使用 AWS IMDSv2,則必須在 gcloud iam workload-identity-pools create-cred-config 指令中加入額外的 --enable-imdsv2 標記:

gcloud iam workload-identity-pools create-cred-config \
    projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID \
    --service-account=SERVICE_ACCOUNT_EMAIL \
    --aws \
    --enable-imdsv2 \
    --output-file=FILEPATH.json

如果無法使用 AWS 中繼資料伺服器,可以透過下列 AWS 環境變數提供 AWS 安全性憑證:

  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY
  • AWS_REGIONAWS_DEFAULT_REGION
  • 自由參加:AWS_SESSION_TOKEN

如果 AWS 中繼資料伺服器無法使用,gcloud CLI 和程式庫就會使用這些 AWS 環境變數。

Azure

建立憑證設定檔,讓程式庫從 Azure 執行個體中繼資料服務 (IMDS) 取得存取權杖:

gcloud iam workload-identity-pools create-cred-config \
    projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID \
    --service-account=SERVICE_ACCOUNT_EMAIL \
    --service-account-token-lifetime-seconds=SERVICE_ACCOUNT_TOKEN_LIFETIME \
    --azure \
    --app-id-uri APPLICATION_ID_URI \
    --output-file=FILEPATH.json

更改下列內容:

  • PROJECT_NUMBER:包含 workload identity pool 的專案專案編號。
  • POOL_ID:工作負載身分集區的 ID。
  • PROVIDER_ID:工作負載身分集區提供者的 ID。
  • SERVICE_ACCOUNT_EMAIL:如果您使用服務帳戶模擬功能,請改用服務帳戶的電子郵件地址。如果您未使用服務帳戶模擬功能,請省略這個旗標。
  • APPLICATION_ID_URI:Azure 應用程式的應用程式 ID URI。
  • SERVICE_ACCOUNT_TOKEN_LIFETIME:如果您使用服務帳戶模擬,請以秒為單位指定服務帳戶存取權杖的生命週期。如果未提供,預設為一小時。如果您未使用服務帳戶模擬功能,請省略這個旗標。如要指定超過一小時的生命週期,請設定constraints/iam.allowServiceAccountCredentialLifetimeExtension 機構政策限制
  • FILEPATH:要儲存設定的檔案。

使用憑證設定存取 Google Cloud

如要讓工具和用戶端程式庫使用憑證設定,請在 AWS 或 Azure 環境中執行下列操作:

  1. 初始化環境變數 GOOGLE_APPLICATION_CREDENTIALS,並指向憑證設定檔:

    Bash

      export GOOGLE_APPLICATION_CREDENTIALS=`pwd`/FILEPATH.json
      
    其中 FILEPATH 是憑證設定檔的相對路徑。

    PowerShell

      $env:GOOGLE_APPLICATION_CREDENTIALS = Resolve-Path 'FILEPATH.json'
      
    其中 FILEPATH 是憑證設定檔的相對路徑。
  2. 使用支援 Workload Identity 聯盟且可自動尋找憑證的用戶端程式庫或工具:

    C++

    v2.6.0 版起,Google Cloud C++ 用戶端程式庫支援 Workload Identity Federation。如要使用 Workload Identity 聯盟,您必須使用 1.36.0 以上版本的 gRPC 建構用戶端程式庫。

    Go

    如果 Go 的用戶端程式庫使用 golang.org/x/oauth2 模組的 v0.0.0-20210218202405-ba52d332ba99 以上版本,即可支援 Workload Identity Federation。

    如要查看用戶端程式庫使用的這個模組版本,請執行下列指令:

    cd $GOPATH/src/cloud.google.com/go
    go list -m golang.org/x/oauth2
    

    Java

    如果 Java 適用的用戶端程式庫使用 com.google.auth:google-auth-library-oauth2-http構件 0.24.0 以上版本,即可支援 Workload Identity 聯盟。

    如要查看用戶端程式庫使用的構件版本,請在應用程式目錄中執行下列 Maven 指令:

    mvn dependency:list -DincludeArtifactIds=google-auth-library-oauth2-http
    

    Node.js

    如果 Node.js 適用的用戶端程式庫使用 google-auth-library 套件 7.0.2 以上版本,即可支援 Workload Identity Federation。

    如要查看用戶端程式庫使用的套件版本,請在應用程式目錄中執行下列指令:

    npm list google-auth-library
    

    建立 GoogleAuth 物件時,您可以指定專案 ID,也可以允許 GoogleAuth 自動尋找專案 ID。如要自動找出專案 ID,設定檔中的服務帳戶必須在專案中具備「瀏覽器」角色 (roles/browser),或是其他具備同等權限的角色。詳情請參閱 google-auth-library 套件的README

    Python

    如果 Python 適用的用戶端程式庫使用 google-auth 套件 1.27.0 以上版本,即可支援 Workload Identity Federation。

    如要查看用戶端程式庫使用的套件版本,請在安裝套件的環境中執行下列指令:

    pip show google-auth
    

    如要為驗證用戶端指定專案 ID,可以設定 GOOGLE_CLOUD_PROJECT 環境變數,也可以允許用戶端自動尋找專案 ID。如要自動尋找專案 ID,設定檔中的服務帳戶必須在專案中具備「瀏覽器」角色 (roles/browser),或具備同等權限的角色。詳情請參閱google-auth 套件的使用者指南

    gcloud

    如要使用 Workload Identity 聯盟進行驗證,請使用 gcloud auth login 指令:

    gcloud auth login --cred-file=FILEPATH.json
    

    FILEPATH 替換為憑證設定檔的路徑。

    gcloud CLI 363.0.0 以上版本支援 gcloud CLI 中的 Workload Identity Federation。

    Terraform

    如果您使用 3.61.0 以上版本,Google Cloud 供應商支援工作負載身分聯盟:

    terraform {
      required_providers {
        google = {
          source  = "hashicorp/google"
          version = "~> 3.61.0"
        }
      }
    }
    

    bq

    如要使用 Workload Identity 聯盟進行驗證,請使用 gcloud auth login 指令,如下所示:

    gcloud auth login --cred-file=FILEPATH.json
    

    FILEPATH 替換為憑證設定檔的路徑。

    如要在 bq 中使用 Workload Identity Federation,請使用 gcloud CLI 390.0.0 以上版本

    如果無法使用支援工作負載身分聯盟的用戶端程式庫,可以使用 REST API 透過程式驗證

進階情境

使用 REST API 驗證工作負載

如果無法使用用戶端程式庫,請按照下列步驟操作,讓外部工作負載使用 REST API 取得短期存取權杖:

  1. 從外部 IdP 取得憑證:

    AWS

    建立 JSON 文件,其中包含您通常會在對 AWS GetCallerIdentity() 端點提出的要求中加入的資訊,包括有效的要求簽章

    Workload Identity Federation 將這個 JSON 文件稱為 GetCallerIdentity 權杖。Workload Identity Federation 可透過這個權杖驗證身分,不必公開 AWS 私密存取金鑰。

    GetCallerIdentity 權杖類似以下內容:

    {
      "url": "https://sts.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15",
      "method": "POST",
      "headers": [
        {
          "key": "Authorization",
          "value" : "AWS4-HMAC-SHA256 Credential=AKIASOZTBDV4D7ABCDEDF/20200228/us-east-1/sts/aws4_request, SignedHeaders=host;x-amz-date,Signature=abcedefdfedfd"
        },
        {
          "key": "host",
          "value": "sts.amazonaws.com"
        },
        {
          "key": "x-amz-date",
          "value": "20200228T225005Z"
        },
        {
          "key": "x-goog-cloud-target-resource",
          "value": "//iam.googleapis.com/projects/12345678/locations/global/workloadIdentityPools/my-pool/providers/my-aws-provider"
        },
        {
          "key": "x-amz-security-token",
          "value": "GizFWJTqYX...xJ55YoJ8E9HNU="
        }
      ]
    }
    

    權杖包含下列欄位:

    • url:AWS STS 端點的網址 (適用於 GetCallerIdentity()),並將標準 GetCallerIdentity() 要求的本文附加為查詢參數。例如:https://sts.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15。建議您使用區域 STS 端點,並為工作負載設計可靠的基礎架構。詳情請參閱「區域 AWS STS 端點」。
    • method:HTTP 要求方法:POST
    • headers:HTTP 要求標頭,必須包含:
      • Authorization:要求簽章。
      • hosturl 欄位的主機名稱,例如 sts.amazonaws.com
      • x-amz-date:您傳送要求的時間,格式為 ISO 8601 Basic 字串。這個值通常會設為目前時間,用於防範重送攻擊。
      • x-goog-cloud-target-resource:身分識別提供者的完整資源名稱,不含 https: 前置字元。例如:
        //iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID
        
      • x-amz-security-token:工作階段符記。如果您使用臨時安全憑證,才需要提供這項資訊。

    下列範例會建立經過網址編碼的 GetCallerIdentity 權杖。 擷取網址編碼的權杖,以供日後使用。此外,系統也會建立可供您參考的易讀權杖:

    import json
    import urllib
    
    import boto3
    from botocore.auth import SigV4Auth
    from botocore.awsrequest import AWSRequest
    
    
    def create_token_aws(project_number: str, pool_id: str, provider_id: str) -> None:
        # Prepare a GetCallerIdentity request.
        request = AWSRequest(
            method="POST",
            url="https://sts.amazonaws.com/?Action=GetCallerIdentity&Version=2011-06-15",
            headers={
                "Host": "sts.amazonaws.com",
                "x-goog-cloud-target-resource": f"//iam.googleapis.com/projects/{project_number}/locations/global/workloadIdentityPools/{pool_id}/providers/{provider_id}",
            },
        )
    
        # Set the session credentials and Sign the request.
        # get_credentials loads the required credentials as environment variables.
        # Refer:
        # https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html
        SigV4Auth(boto3.Session().get_credentials(), "sts", "us-east-1").add_auth(request)
    
        # Create token from signed request.
        token = {"url": request.url, "method": request.method, "headers": []}
        for key, value in request.headers.items():
            token["headers"].append({"key": key, "value": value})
    
        # The token lets workload identity federation verify the identity without revealing the AWS secret access key.
        print("Token:\n%s" % json.dumps(token, indent=2, sort_keys=True))
        print("URL encoded token:\n%s" % urllib.parse.quote(json.dumps(token)))
    
    
    def main() -> None:
        # TODO(Developer): Replace the below credentials.
        # project_number: Google Project number (not the project id)
        project_number = "my-project-number"
        pool_id = "my-pool-id"
        provider_id = "my-provider-id"
    
        create_token_aws(project_number, pool_id, provider_id)
    
    
    if __name__ == "__main__":
        main()

    初始化下列變數:

    Bash

    SUBJECT_TOKEN_TYPE="urn:ietf:params:aws:token-type:aws4_request"
    SUBJECT_TOKEN=TOKEN
    

    PowerShell

    $SubjectTokenType = "urn:ietf:params:aws:token-type:aws4_request"
    $SubjectToken = "TOKEN"
    

    其中 TOKEN 是指令碼產生的網址編碼 GetCallerIdentity權杖。

    Azure

    連線至已指派受控身分的 Azure VM,並從 Azure 執行個體中繼資料服務 (IMDS) 取得存取權杖

    Bash

    SUBJECT_TOKEN_TYPE="urn:ietf:params:oauth:token-type:jwt"
    SUBJECT_TOKEN=$(curl \
      "http://169.254.169.254/metadata/identity/oauth2/token?resource=APP_ID_URI&api-version=2018-02-01" \
      -H "Metadata: true" | jq -r .access_token)
    echo $SUBJECT_TOKEN
    

    這項指令會使用 jq 工具。Cloud Shell 預設提供 jq

    PowerShell

    $SubjectTokenType = "urn:ietf:params:oauth:token-type:jwt"
    $SubjectToken = (Invoke-RestMethod `
      -Uri "http://169.254.169.254/metadata/identity/oauth2/token?resource=APP_ID_URI&api-version=2018-02-01" `
      -Headers @{Metadata="true"}).access_token
    Write-Host $SubjectToken
    

    其中 APP_ID_URI 是您為 Workload Identity 聯盟設定的應用程式應用程式 ID URI

  2. 使用 Security Token Service API 換取短期存取權杖:

    Bash

    STS_TOKEN=$(curl https://sts.googleapis.com/v1/token \
        --data-urlencode "audience=//iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID" \
        --data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \
        --data-urlencode "requested_token_type=urn:ietf:params:oauth:token-type:access_token" \
        --data-urlencode "scope=https://www.googleapis.com/auth/cloud-platform" \
        --data-urlencode "subject_token_type=$SUBJECT_TOKEN_TYPE" \
        --data-urlencode "subject_token=$SUBJECT_TOKEN" | jq -r .access_token)
    echo $STS_TOKEN
    

    PowerShell

    [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12
    $StsToken = (Invoke-RestMethod `
        -Method POST `
        -Uri "https://sts.googleapis.com/v1/token" `
        -ContentType "application/json" `
        -Body (@{
            "audience"           = "//iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID"
            "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"   = $SubjectTokenType
            "subjectToken"       = $SubjectToken
        } | ConvertTo-Json)).access_token
    Write-Host $StsToken
    

    替換下列值:

    • PROJECT_NUMBER:含有工作負載身分集區的專案專案編號
    • POOL_ID:工作負載身分集區的 ID
    • PROVIDER_ID:工作負載身分集區提供者的 ID
  3. 如果您使用服務帳戶模擬,請使用 Security Token Service 的權杖,叫用 IAM Service Account Credentials APIgenerateAccessToken 方法,取得存取權杖。

Cloud Run 服務的權杖

存取 Cloud Run 服務時,您必須使用 ID 權杖。

Bash

TOKEN=$(curl -0 -X POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SERVICE_ACCOUNT_EMAIL:generateIdToken \
    -H "Content-Type: text/json; charset=utf-8" \
    -H "Authorization: Bearer $STS_TOKEN" \
    -d @- <<EOF | jq -r .token
    {
        "audience": "SERVICE_URL"
    }
EOF
)
echo $TOKEN

PowerShell

$Token = (Invoke-RestMethod `
    -Method POST `
    -Uri "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SERVICE_ACCOUNT_EMAIL:generateIdToken" `
    -Headers @{ "Authorization" = "Bearer $StsToken" } `
    -ContentType "application/json" `
    -Body (@{
        "audience" = "SERVICE_URL"
    } | ConvertTo-Json)).token
Write-Host $Token

取代下列項目:

  • SERVICE_ACCOUNT_EMAIL:服務帳戶的電子郵件地址。
  • SERVICE_URL:服務的網址,例如 https://my-service-12345-us-central1.run.app。您也可以將其設為自訂服務端點。詳情請參閱「瞭解自訂目標對象」。

其他平台的權杖

存取其他服務時,您必須使用存取權杖。

Bash

TOKEN=$(curl -0 -X POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SERVICE_ACCOUNT_EMAIL:generateAccessToken \
    -H "Content-Type: text/json; charset=utf-8" \
    -H "Authorization: Bearer $STS_TOKEN" \
    -d @- <<EOF | jq -r .accessToken
    {
        "scope": [ "https://www.googleapis.com/auth/cloud-platform" ]
    }
EOF
)
echo $TOKEN

PowerShell

$Token = (Invoke-RestMethod `
    -Method POST `
    -Uri "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SERVICE_ACCOUNT_EMAIL:generateAccessToken" `
    -Headers @{ "Authorization" = "Bearer $StsToken" } `
    -ContentType "application/json" `
    -Body (@{
        "scope" = , "https://www.googleapis.com/auth/cloud-platform"
    } | ConvertTo-Json)).accessToken
Write-Host $Token

取代下列項目:

  • SERVICE_ACCOUNT_EMAIL:服務帳戶的電子郵件地址。

後續步驟