配置使用其他身份提供方的工作负载身份联合

本指南介绍了如何将工作负载身份联合与其他身份提供方 (IdP) 搭配使用。

在 Google Cloud 外部运行的工作负载可能有权访问特定于环境的现有凭据,例如:

  • 工作负载可能能够从同一环境中运行的身份提供商 (IdP) 获取 SAML 断言或 OpenID Connect (OIDC) 令牌。

    如需向 Google Cloud 进行身份验证,您可以使用工作负载身份联合,让工作负载将其特定于环境的凭据交换为短期有效的 Google Cloud 凭据。

  • 工作负载可能拥有 X.509 证书。如需了解详情,请参阅使用 X.509 证书配置工作负载身份联合(预览版)

  • 工作负载可能拥有其他类型的凭据。

    通过将工作负载身份联合与自定义令牌代理结合使用,您可以让工作负载使用其他类型的凭据来获取短期有效的 Google Cloud 凭据。

使用工作负载身份联合可以帮助您减少需要轮替的凭据数量

以下部分介绍了如何将工作负载身份联合与支持 OpenID Connect (OIDC) 或 SAML 身份验证协议的 IdP 搭配使用。

准备外部 IdP

您只需为每个 IdP 执行这些步骤一次。

在开始之前,请验证您的外部 IdP 是否满足以下要求:

OIDC

  • IdP 支持 OpenID Connect 1.0。

  • IdP 具有颁发者 URI。

  • 您可以通过以下方式之一提供 IdP 的 OIDC 元数据

    • 使用 SSL 和 TLS 进行保护的 JWKS 端点。端点网址必须以 https:// 开头,并且端点可通过互联网公开访问。

      Google Cloud 会使用这些端点下载您的 IdP 的密钥集,并使用此密钥集验证令牌。

      Google Cloud 不支持使用自签名证书保护的端点。具体而言,不支持 x5cx5t 字段,并且必须将其从 OIDC JWK 中移除。

    • 上传到 Google Cloud 的 OIDC JWKS 文件。使用此方法时,端点无需公开。

SAML

  • IdP 支持 SAML 2.0。

  • IdP 提供 SAML SP 元数据文档,其中描述了 SAML 服务提供商配置,并包含 IdP 的签名证书。

    Google Cloud 使用此证书来验证 SAML 断言和响应。

如果您的 IdP 符合这些条件,请执行以下操作:

OIDC

配置 IdP,使工作负载可以获取满足以下条件的 ID 令牌:

  • 令牌使用 RS256ES256 算法进行签名。
  • 令牌包含 aud 声明,其值如下:

    https://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID
    

    请替换以下内容:

    • PROJECT_NUMBER:您用于创建工作负载身份池的 Google Cloud 项目的编号
    • POOL_ID:您选择的工作负载 ID,用于标识工作负载身份池。稍后在创建工作负载身份池时,您必须使用相同的 ID。
    • PROVIDER_ID:您选择的工作负载 ID,用于标识工作负载身份池提供商。稍后在创建工作负载身份池提供程序时,必须使用相同的 ID。

    或者,您也可以将工作负载身份池提供方配置为采用自定义受众群体。

  • 令牌包含未来的 exp 声明和过去的 iat 声明。

    exp 的值必须大于 iat 的值,最多相差 24 小时。

通常,最好在执行令牌交换时使用 ID 令牌,因为 ID 令牌反映了用户的身份。如果您决定改用访问令牌,请确保访问令牌满足以下额外要求:

  • 访问令牌采用 JSON Web 令牌格式
  • 访问令牌包含 ISSUER 声明,以便网址 ISSUER/.well-known/openid-configuration 指向 IdP 的 OIDC 元数据端点。

  • 如需上传本地 JWK 密钥,请参阅管理 OIDC JWK

SAML

配置 IdP,使 SAML 断言包含满足以下条件的元素:

  • 设置为工作负载身份池提供方中配置的实体 ID 的 Issuer 元素。必须省略颁发者格式或将其设置为 urn:oasis:names:tc:SAML:2.0:nameid-format:entity
  • 包含以下各项的 Subject 元素:
    • NameID 元素。
    • 仅一个其 Method 设置为 urn:oasis:names:tc:SAML:2.0:cm:bearerSubjectConfirmation 元素。
    • NotOnOrAfter 设置为将来的时间戳并且没有 NotBefore 值的 SubjectConfirmationData 元素。
  • 包含以下各项的 Conditions 元素:

    • 被省略或在过去出现的 NotBefore
    • 被省略或在将来出现的 NotOnOrAfter
    • 格式如下的 Audience

      https://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID
      

      请替换以下内容:

      • PROJECT_NUMBER:您用于创建工作负载身份池的 Google Cloud 项目的编号
      • POOL_ID:您选择的工作负载 ID,用于标识工作负载身份池。稍后在创建工作负载身份池时,您必须使用相同的 ID。
      • PROVIDER_ID:您选择的工作负载 ID,用于标识工作负载身份池提供商。稍后在创建工作负载身份池提供程序时,必须使用相同的 ID。
  • 至少一个 AuthnStatement 元素。

  • 其时间戳在将来的 SessionNotOnOrAfter 元素。或者,省略该元素。

对于包含在 SAML 响应中的 SAML 断言,SAML 响应必须包含:

  • 仅一个满足本部分前面所述的 SAML 断言条件的断言。
  • 其值在过去 1 小时内的 IssueInstant 特性。
  • StatusCode urn:oasis:names:tc:SAML:2.0:status:Success

必须签署 SAML 断言和/或响应。

配置工作负载身份联合

您只需为每个 IdP 执行这些步骤一次。然后,您可以为多个工作负载以及多个 Google Cloud 项目使用相同的工作负载身份池和提供方。

如需开始配置工作负载身份联合,请执行以下操作:

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

    Go to project selector

  2. 最好使用专用项目来管理工作负载身份池和提供方
  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

管理 OIDC JWK(可选)

本部分介绍如何在工作负载身份池 oidc 提供方中管理自上传的 OIDC JWK。

创建提供方并上传 OIDC JWK

如需创建 OIDC JWK,请参阅 JWT、JWS、JWE、JWK 和 JWA 实现

如需在创建工作负载身份池提供方时上传 OIDC JWK 文件,请运行带有 --jwk-json-path="JWK_JSON_PATH"gcloud iam workload-identity-pools providers create-oidc 命令。将 JWK_JSON_PATH 替换为 JWK JSON 文件的路径。

此操作会使用文件中的密钥创建上传的密钥。

更新 OIDC JWK

如需更新 OIDC JWK,请运行带有 --jwk-json-path="JWK_JSON_PATH"gcloud iam workload-identity-pools provider update-oidc 命令。将 JWK_JSON_PATH 替换为 JWK JSON 文件的路径。

此操作会将所有现有的上传密钥替换为文件中的密钥。您无法恢复替换的密钥。

删除所有上传的 OIDC JWK

如需删除所有上传的 OIDC JWK 并改为使用颁发者 URI 提取密钥,请运行带有 --jwk-json-path="JWK_JSON_PATH"gcloud iam workload-identity-pools providers update-oidc 命令。将 JWK_JSON_PATH 替换为空文件的路径。使用 --issuer-uri 标志设置颁发者 URI。

此操作会删除所有现有上传密钥以及文件中的密钥。您无法恢复已删除的密钥。

定义特性映射和条件

您的 IdP 颁发的 OIDC 令牌或 SAML 断言可能包含多个特性,并且您必须确定要在 Google Cloud 中用作主体标识符 (google.subject) 的特性。

您也可以视需要映射其他特性。然后,您可以在授予对资源的访问权限时引用这些特性。

OIDC

特性映射可以使用嵌入在外部 IdP 颁发的 ID 令牌或访问令牌中的声明。

您必须将其中一个声明映射到 google.subject,以唯一标识用户。为了防止欺骗威胁,请选择具有不可更改的唯一值的声明。

许多 IdP 都会使用唯一且不可变的 ID 填充 sub 声明。对于这些 IdP,请考虑将 sub 声明映射到 google.subject

google.subject=assertion.sub

请避免使用 email 等声明来实现此目的。电子邮件地址通常可以重新分配或更改,因此不会唯一标识和永久标识用户。

SAML

特性映射可以使用嵌入在外部 IdP 颁发的断言中的 <Subject><Attribute> 元素。可以使用以下关键字来引用 SAML 特性:

  • assertion.subject 包含 <Subject> 元素中经过身份验证的用户的 NameID
  • assertion.attributes['ATTRIBUTE_NAME'] 包含类似名称 <Attribute> 的值列表。

您必须将其中一个声明映射到 google.subject,以唯一标识用户。为了防止欺骗威胁,请选择具有不可更改的唯一值的声明。

许多 IdP 都会使用唯一且不可变的 ID 填充 NameId。对于这些 IdP,请考虑将 NameId 特性映射到 google.subject

google.subject=assertion.subject

请避免使用 http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress 等特性来实现此目的。电子邮件地址通常可以重新分配或更改,因此不会唯一标识和永久标识用户。

您可以视需要定义特性条件。 属性条件是可以检查断言属性和目标属性的 CEL 表达式。如果给定凭据的特性条件评估结果为 true,则接受凭据。否则,凭据会被拒绝。

OIDC

您可以使用属性条件来限制哪些用户可以使用工作负载身份联合获取短期有效的 Google Cloud 令牌。

例如,以下条件限制对包含值为 true 的自定义 service_account 声明的令牌的访问权限:

assertion.service_account==true

SAML

您可以使用属性条件来限制哪些用户可以使用工作负载身份联合获取短期有效的 Google Cloud 令牌。

例如,以下条件会限制对包含值为 true 的自定义 https://example.com/SAML/Attributes/AllowGcpFederation 特性的断言的访问权限:

assertion.attributes['https://example.com/SAML/Attributes/AllowGcpFederation'][0]=='true'

创建工作负载身份池和提供商

所需的角色

如需获得配置工作负载身份联合所需的权限,请让您的管理员为您授予项目的以下 IAM 角色:

如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限

您也可以通过自定义角色或其他预定义角色来获取所需的权限。

此外,IAM Owner (roles/owner) 基本角色还具有配置身份联合的权限。您不应在生产环境中授予基本角色,但可以在开发或测试环境中授予这些角色。

现在,您已收集了创建工作负载身份池和提供方所需的全部信息:

控制台

  1. 在 Google Cloud 控制台中,前往新建工作负载提供方和池页面。

    转到“新建工作负载提供商和池”

  2. 创建身份池下,输入以下内容:

    • 名称:池的名称。该名称还用作池 ID。池 ID 创建后便无法更改。
    • 说明:描述池用途的文本。
  3. 点击继续

  4. 按如下方式配置提供方设置:

    OIDC

    • 选择提供方中,选择 OpenID Connect (OIDC)
    • 提供方名称中,输入提供方的名称。该名称还用作提供方 ID。创建提供方后,您将无法更改提供方 ID。
    • 颁发者网址中,输入您的 IdP 的颁发者网址。该网址必须以 https:// 开头
    • 可选:在 JWK 文件 (JSON) 中,选择要上传的 JWK 文件。如果未提供此字段,则 Google Cloud 会尝试从颁发者提取 JWK。
    • 允许的受众群体:ID 令牌的预期受众群体。

    SAML

    • 选择提供方中,选择 SAML
    • 提供方名称中,输入提供方的名称。该名称还用作提供方 ID。创建提供方后,您将无法更改提供方 ID。
    • IDP 元数据文件 (XML) 中,上传您的身份提供方提供的 SAML 元数据 XML 文档。
  5. 点击继续

  6. 配置提供方特性下,添加您在本指南前面部分中确定的特性映射

  7. 特性条件下,输入您在本指南前面部分中确定的特性条件。如果您没有特性条件,请将该字段留空。

  8. 如需创建工作负载身份池和提供方,请点击保存

gcloud

  1. 如需创建新的工作负载身份池,请执行以下命令:

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

    请替换以下内容:

    • POOL_ID:池的唯一 ID。
    • DISPLAY_NAME:池的名称。
    • DESCRIPTION:您选择的池的说明。当您授予对池身份的访问权限时,系统会显示此说明。
  2. 如需添加工作负载身份池提供方,请执行以下操作:

    OIDC

    如需添加 OIDC 工作负载身份池提供方,请执行以下命令:

    gcloud iam workload-identity-pools providers create-oidc PROVIDER_ID \
        --location="global" \
        --workload-identity-pool="POOL_ID" \
        --issuer-uri="ISSUER" \
        --allowed-audiences="AUDIENCE" \
        --attribute-mapping="MAPPINGS" \
        --attribute-condition="CONDITIONS"
        --jwk-json-path="JWK_JSON_PATH"
    

    请替换以下内容:

    • PROVIDER_ID:您选择的唯一工作负载身份池提供方 ID。
    • POOL_ID:您之前创建的工作负载身份池 ID。
    • ISSUER:OIDC 元数据中定义的颁发者 URI。
    • AUDIENCE:ID 令牌的预期受众群体,对于许多提供商而言,该受众群体与客户端 ID 匹配。
    • MAPPINGS:您在本指南前面部分中创建的以英文逗号分隔的属性映射列表。
    • CONDITIONS:您在本指南前面部分中创建的可选属性条件。如果您没有特性条件,请移除该参数。
    • JWK_JSON_PATH本地上传的 OIDC JWK 的可选路径。如果未提供此参数,Google Cloud 会改用您的 IdP 的 /.well-known/openid-configuration 路径来寻找包含公钥的 JWK。

    SAML

    如需添加 SAML 工作负载身份池提供方,请执行以下命令:

    gcloud iam workload-identity-pools providers create-saml PROVIDER_ID \
        --location="global" \
        --workload-identity-pool="POOL_ID" \
        --idp-metadata-path="IDP_METADATA_PATH" \
        --attribute-mapping="MAPPINGS" \
        --attribute-condition="CONDITIONS"
    

    请替换以下内容:

    • POOL_ID:池的 ID
    • IDP_METADATA_PATH:SAML IdP 的元数据文档的本地路径
    • MAPPINGS:您在本指南前面部分中创建的以英文逗号分隔的特性映射列表
    • CONDITIONS(可选):您在本指南前面部分中创建的特性条件

    注意:前缀 gcp- 已被保留,不能在池或提供方 ID 中使用。

    可选:接受来自 IdP 的加密 SAML 断言

    如需让您的 SAML 2.0 IdP 能够生成工作负载身份联合可接受的加密 SAML 断言,请执行以下操作:

    • 在工作负载身份联合中,执行以下操作:
      • 为您的工作负载身份池提供商创建非对称密钥对。
      • 下载包含公钥的证书文件。
      • 配置您的 SAML IdP,以使用公钥加密颁发的 SAML 断言。
    • 在 IdP 中,执行以下操作:
      • 启用断言加密(也称为令牌加密)。
      • 上传您在工作负载身份联合中创建的公钥。
      • 确认您的 IdP 生成加密的 SAML 断言。
    请注意,即使配置了 SAML 加密提供商密钥,工作负载身份联合仍然可以处理明文断言。

    创建工作负载身份联合 SAML 断言加密密钥

    本部分将指导您创建非对称密钥对,使工作负载身份联合能够接受加密的 SAML 断言。

    Google Cloud 使用私钥来解密 IdP 发出的 SAML 断言。如需创建用于 SAML 加密的非对称密钥对,请运行以下命令。如需了解详情,请参阅支持的 SAML 加密算法

    gcloud iam workload-identity-pools providers keys create KEY_ID \
        --workload-identity-pool WORKLOAD_POOL_ID \
        --provider PROVIDER_ID \
        --location global \
        --use encryption \
        --spec KEY_SPECIFICATION

    请替换以下内容:

    • KEY_ID:您选择的键名称
    • WORKLOAD_POOL_ID:池 ID
    • PROVIDER_ID:提供方 ID
    • KEY_SPECIFICATION:密钥规范,可以是 rsa-2048rsa-3072rsa-4096 之一。

    创建密钥对后,如需将公钥下载到证书文件中,请执行以下命令。只有工作负载身份联合可以访问私钥。

    gcloud iam workload-identity-pools providers keys describe KEY_ID \
        --workload-identity-pool WORKLOAD_POOL_ID \
        --provider PROVIDER_ID \
        --location global \
        --format "value(keyData.key)" \
        > CERTIFICATE_PATH

    请替换以下内容:

    • KEY_ID:密钥名称
    • WORKLOAD_POOL_ID:池 ID
    • PROVIDER_ID:提供方 ID
    • CERTIFICATE_PATH:要将证书写入的路径,例如 saml-certificate.cersaml-certificate.pem

    配置符合 SAML 2.0 标准的 IdP,以发出加密的 SAML 断言

    配置您的 SAML IdP,以使用上一步中下载的公共证书来加密颁发的 SAML 断言。如需了解具体说明,请咨询您的 IdP 团队。

    将 IdP 配置为加密 SAML 断言后,我们建议您检查以确保其生成的断言确实已加密。即使配置了 SAML 断言加密,工作负载身份联合仍然可以处理明文断言。

    删除工作负载身份联合加密密钥

    如需删除 SAML 加密密钥,请运行以下命令:
      gcloud iam workload-identity-pools providers keys delete KEY_ID \
          --workload-identity-pool WORKLOAD_POOL_ID \
          --provider PROVIDER_ID \
          --location global

    请替换以下内容:

    • KEY_ID:密钥名称
    • WORKLOAD_POOL_ID:池 ID
    • PROVIDER_ID:提供方 ID

    支持的 SAML 加密算法

    工作负载身份联合支持以下密钥传输算法:

    工作负载身份联合支持以下块加密算法:

对工作负载进行身份验证

您必须为每个工作负载执行这些步骤一次。

允许外部工作负载访问 Google Cloud 资源

为了向您的工作负载提供对 Google Cloud 资源的访问权限,我们建议您向该主账号授予直接资源访问权限。在这种情况下,主账号是联合身份用户。某些 Google Cloud 产品存在 Google Cloud API 限制。如果您的工作负载调用存在限制的 API 端点,您可以改用服务账号模拟。在这种情况下,主账号是 Google Cloud 服务账号,它充当身份。您可以向此服务账号授予资源的访问权限。

直接资源访问权限

您可以使用 Google Cloud 控制台或 gcloud CLI 向联合身份授予直接对资源的访问权限。

控制台

如需使用 Google Cloud 控制台授予直接对某个资源的 IAM 角色,您必须进入该资源的页面,然后授予该角色。以下示例展示了如何进入 Cloud Storage 页面,然后向联合身份授予直接对 Cloud Storage 存储桶的 Storage Object Viewer (roles/storage.objectViewer) 角色。

  1. 在 Google Cloud 控制台中,进入 Cloud Storage 存储桶页面。

    进入“存储桶”

  2. 在存储桶列表中,点击您要针对其授予角色的存储桶的名称。

  3. 选择页面顶部附近的权限标签。

  4. 点击 授予访问权限按钮。

    系统会显示“添加主账号”对话框。

  5. 新主账号字段中,输入需要访问您存储桶的一个或多个身份。

    按主体

    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
    • GROUP:从您的 IdP 映射的群组,例如:administrator-group@example.com

    按特性

    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. 选择角色下拉菜单中选择一个或多个角色。 您选择的角色将显示在窗格中,其中包含对角色授予的权限的简短说明。

  7. 点击保存

gcloud

如需使用 gcloud CLI 针对项目中的资源授予 IAM 角色,请执行以下操作:

  1. 获取定义资源的项目的编号。

    gcloud projects describe $(gcloud config get-value core/project) --format=value\(projectNumber\)
    
  2. 授予对资源的访问权限。

    如需使用 gcloud CLI 向符合特定条件的外部身份授予 Storage Object Viewer 角色 (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:包含工作负载身份池的项目的编号
    • 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. 向服务账号授予对您希望外部身份访问的资源的访问权限

    4. 向服务账号授予 Workload Identity User 角色 (roles/iam.workloadIdentityUser)。

  2. 如需使用 Google Cloud 控制台或 gcloud CLI 通过服务账号模拟向联合身份授予访问权限,请执行以下操作:

控制台

如需使用 Google Cloud 控制台向具有服务账号的联合身份授予 IAM 角色,请执行以下操作:

同一项目中的服务账号

  1. 如需使用服务账号模拟为同一项目中的服务账号授予访问权限,请执行以下操作:

    1. 进入工作负载身份池页面。

      转到“工作负载身份池”

    2. 选择授予访问权限

    3. 向服务账号授予访问权限对话框中,选择使用服务账号模拟授予访问权限

    4. 服务账号列表中,选择要模拟的外部身份的服务账号,然后执行以下操作:

    5. 如需选择池中的哪些身份可以模拟服务账号,请执行以下操作之一:

      • 如需仅允许工作负载身份池的特定身份模拟服务账号,请选择仅限与过滤条件匹配的身份

      • 属性名称列表中,选择您要作为过滤依据的属性。

      • 属性值字段中,输入属性的预期值;例如,如果您使用属性映射 google.subject=assertion.sub,请将属性名称设置为 subject,并将属性值设置为外部身份提供方颁发的令牌中 sub 声明的值。

    6. 如需保存配置,请点击保存,然后点击关闭

不同项目中的服务账号

  1. 如需使用服务账号模拟为不同项目中的服务账号授予访问权限,请执行以下操作:

    1. 转到服务账号页面。

      转到“服务账号”

    2. 选择要模拟的服务账号。

    3. 点击管理访问权限

    4. 点击添加主账号

    5. 新建主账号字段中,为身份池中要模拟服务账号的身份输入以下主账号标识符之一。

      按主体

      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
      • GROUP:从您的 IdP 映射的群组,例如:administrator-group@example.com

      按特性

      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. 选择角色中,选择 Workload Identity User 角色 (roles/iam.workloadIdentityUser)。

    7. 如需保存配置,请点击保存

gcloud

如需使用 gcloud CLI 向符合特定条件的外部身份授予 Workload Identity User 角色 (roles/iam.workloadIdentityUser),请运行以下命令。

按主体

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:包含工作负载身份池的项目的编号
  • POOL_ID:工作负载身份池的池 ID
  • SUBJECT已映射google.subject 的特性的预期值
  • GROUP已映射google.groups 的特性的预期值
  • ATTRIBUTE_NAME特性映射中的自定义特性的名称
  • ATTRIBUTE_VALUE:属性映射中的自定义属性的值

下载凭据配置

本部分介绍了如何使用 Google Cloud 控制台下载凭据配置。

如需让您的工作负载访问客户端库,您必须先执行以下操作来下载并配置应用默认凭据 (ADC)

  1. 在 Google Cloud 控制台中,转到 Workload Identity 池页面。

    转到“工作负载身份池”
  2. 在表中,选择池以进入池的详情页面。

  3. 点击授予访问权限

  4. 选择使用联合身份授予访问权限(推荐)

  5. 如需下载应用默认凭据 (ADC) 以便您的工作负载可以访问客户端库,请执行以下操作:

    1. 点击下载配置

    2. 配置您的应用对话框中,执行以下操作:

      1. 提供方下拉列表中,选择您的提供方。

      2. OIDC token pathSAML assertion path 中,输入此令牌或断言所在的路径。

      3. 格式类型下拉列表中,选择格式。

    3. 点击下载配置,然后记下保存该文件的路径。

创建凭据配置

Cloud 客户端库、gcloud CLI 和 Terraform 可以自动获取外部凭据,并使用这些凭据来访问 Google Cloud。为了让库和工具完成此过程,您必须提供凭据配置文件。此文件定义以下内容:

  • 从何处获取外部凭据
  • 要使用的工作负载身份池和提供商
  • 模拟哪个服务账号(如果您使用服务账号模拟)

通过运行本地可执行文件,Cloud 客户端库可从本地文件(即 HTTP 网址)获取外部凭据:

  • 可执行文件溯源凭据:库在每当需要新凭据时都会启动可执行文件。如果可执行文件成功获取新的外部凭据,则必须将 JSON 文档写入如下所示的 STDOUT

    OIDC

    {
      "version": 1,
      "success": true,
      "token_type": "urn:ietf:params:oauth:token-type:id_token",
      "id_token": "HEADER.PAYLOAD.SIGNATURE",
      "expiration_time": 1620499962
    }
    

    如果可执行文件无法获取新凭据,则必须将 JSON 文档写入如下所示的 STDOUT

    {
      "version": 1,
      "success": false,
      "code": "401",
      "message": "Caller not authorized."
    }
    

    JSON 文档使用以下字段:

    • version:JSON 输出的版本。 仅支持版本 1。
    • success:响应的状态。

      如果为 true,则响应必须包含字段 id_tokentoken_type。可执行文件必须以退出代码 0 退出。

      如果为 false,则响应必须包含字段 codemessage,并以非零值退出。

    • token_type:外部凭据的令牌类型。支持的值包括

      • urn:ietf:params:oauth:token-type:id_token
      • urn:ietf:params:oauth:token-type:jwt
    • id_token:外部凭据。

    • expiration_time:OIDC 令牌到期时间(与 UNIX 计时原点之间相隔的秒数)。仅当在凭据配置中指定了输出文件时,才需要填写此字段。

    • code:错误代码字符串。

    • message:错误消息。

    SAML

    {
      "version": 1,
      "success": true,
      "token_type": "urn:ietf:params:oauth:token-type:saml2",
      "saml_response": "...",
      "expiration_time": 1620499962
    }
    

    如果可执行文件无法获取新凭据,则必须将 JSON 文档写入如下所示的 STDOUT

    {
      "version": 1,
      "success": false,
      "code": "401",
      "message": "Caller not authorized."
    }
    

    JSON 文档使用以下字段:

    • version:JSON 输出的版本。 仅支持版本 1。
    • success:响应的状态。

      如果为 true,则响应必须包含字段 id_tokentoken_type。可执行文件必须以退出代码 0 退出。

      如果为 false,则响应必须包含字段 codemessage,并以非零值退出。

    • token_type:外部凭据的令牌类型。必须为 urn:ietf:params:oauth:token-type:saml2

    • saml_response:SAML 响应或 base64 编码的 SAML 断言。

    • expiration_time:断言到期时间(与 UNIX 计时原点之间相隔的秒数)。仅当在凭据配置中指定了输出文件时,才需要填写此字段。

    • code:错误代码字符串。

    • message:错误消息。

    启动可执行文件时,客户端库会设置以下环境变量:

    • GOOGLE_EXTERNAL_ACCOUNT_AUDIENCE:凭据配置中的目标对象。始终存在。
    • GOOGLE_EXTERNAL_ACCOUNT_TOKEN_TYPE:预期的主体令牌类型。始终存在。
    • GOOGLE_EXTERNAL_ACCOUNT_IMPERSONATED_EMAIL:服务账号电子邮件地址。仅当使用服务账号模拟时存在。
    • GOOGLE_EXTERNAL_ACCOUNT_OUTPUT_FILE:凭据配置中的输出文件位置。仅当在凭据配置中指定了该位置时存在。

    如需使用可执行文件溯源凭据,您必须将环境变量 GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES 设置为 1

  • 文件溯源凭据:库从本地纯文本或 JSON 文件中读取外部凭据。例如:

    JSON

    {
      "mytoken": "ey...
    }
    

    文本

    ey...
    

    外部凭据可以是:

    • OIDC 令牌
    • SAML 响应
    • base64 编码的 SAML 断言

    您必须定期更新该文件,以使其始终包含有效的凭据。例如,如果 OIDC 令牌或 SAML 断言的有效期为 1 小时,您必须每小时至少刷新一次该文件。

  • 网址溯源凭据:库在每当需要新凭据时都会对 HTTP 端点执行 GET 请求。端点必须返回与文件溯源凭据使用的格式等效的纯文本或 JSON 响应。

如需创建凭据配置文件,请执行以下操作:

可执行文件溯源凭据

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 \
    --output-file=FILEPATH.json \
    --executable-command=EXECUTABLE_COMMAND \
    --executable-timeout-millis=EXECUTABLE_TIMEOUT \
    --executable-output-file=EXECUTABLE_OUTPUT_FILE

替换以下内容:

  • PROJECT_NUMBER:包含工作负载身份池的项目的编号。
  • POOL_ID:工作负载身份池的 ID。
  • PROVIDER_ID:工作负载身份池提供方的 ID。
  • SERVICE_ACCOUNT_EMAIL:如果您使用服务账号模拟,请替换为服务账号的电子邮件地址。如果您不使用服务账号模拟,请省略此标志。
  • SERVICE_ACCOUNT_TOKEN_LIFETIME:如果您使用服务账号模拟,请替换为服务账号访问令牌的生命周期(以秒为单位);如果未提供,则默认为一小时。如果您不使用服务账号模拟,请省略此标志。如需指定超过一小时的生命周期,您必须配置 constraints/iam.allowServiceAccountCredentialLifetimeExtension 组织政策限制条件
  • FILEPATH:用于保存配置的文件。
  • EXECUTABLE_COMMAND:要运行来检索 OIDC ID 令牌的完整命令(包括参数),例如 --executable-command="/path/to/command --foo=bar"
  • EXECUTABLE_TIMEOUT:(可选)等待可执行文件运行的时长(以毫秒为单位,默认为 30 秒)。
  • EXECUTABLE_OUTPUT_FILE:指向由可执行文件生成的 3PI 凭据的路径。这对于缓存凭据很有用。通过指定此路径,Auth 库会先检查其是否存在,然后再运行可执行文件。

文件溯源凭据

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 \
    --output-file=FILEPATH.json \
    --credential-source-file=TOKEN_FILEPATH \
    --credential-source-type=SOURCE_TYPE \
    --credential-source-field-name=FIELD_NAME

替换以下内容:

  • PROJECT_NUMBER:包含工作负载身份池的项目的编号。
  • POOL_ID:工作负载身份池的 ID。
  • PROVIDER_ID:工作负载身份池提供方的 ID。
  • SERVICE_ACCOUNT_EMAIL:如果您使用服务账号模拟,请替换为服务账号的电子邮件地址。如果您不使用服务账号模拟,请省略此标志。
  • SERVICE_ACCOUNT_TOKEN_LIFETIME:如果您使用服务账号模拟,请替换为服务账号访问令牌的生命周期(以秒为单位);如果未提供,则默认为一小时。如果您不使用服务账号模拟,请省略此标志。如需指定超过一小时的生命周期,您必须配置 constraints/iam.allowServiceAccountCredentialLifetimeExtension 组织政策限制条件
  • FILEPATH:用于保存配置的文件。
  • TOKEN_FILEPATH:存储 OIDC ID 令牌的路径。
  • SOURCE_TYPE:OIDC ID 令牌文件的格式,设置为 text(默认)或 json
  • FIELD_NAME:包含此令牌的文本文件中的字段(如果 SOURCE_TYPEjson)。

网址溯源凭据

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 \
    --output-file=FILEPATH.json \
    --credential-source-url="TOKEN_URL" \
    --credential-source-headers="KEY_1=VALUE_1,KEY_2=VALUE_2" \
    --credential-source-type=SOURCE_TYPE \
    --credential-source-field-name=FIELD_NAME

替换以下内容:

  • PROJECT_NUMBER:包含工作负载身份池的项目的编号。
  • POOL_ID:工作负载身份池的 ID。
  • PROVIDER_ID:工作负载身份池提供方的 ID
  • SERVICE_ACCOUNT_EMAIL:如果您使用服务账号模拟,请替换为服务账号的电子邮件地址。如果您不使用服务账号模拟,请省略此标志。
  • SERVICE_ACCOUNT_TOKEN_LIFETIME:如果您使用服务账号模拟,请替换为服务账号访问令牌的生命周期(以秒为单位);如果未提供,则默认为一小时。如果您不使用服务账号模拟,请省略此标志。如需指定超过一小时的生命周期,您必须配置 constraints/iam.allowServiceAccountCredentialLifetimeExtension 组织政策限制条件
  • FILEPATH:用于保存配置的文件。
  • TOKEN_URL:要从中检索 OIDC ID 令牌的网址
  • KEY_nVALUE_n:要添加到对 TOKEN_URL 的 HTTP 请求中的自定义标头
  • SOURCE_TYPE:OIDC ID 令牌文件的格式,设置为 text(默认)或 json
  • FIELD_NAME:包含令牌的文本文件中的字段(如果 SOURCE_TYPEjson

使用凭据配置访问 Google Cloud

如需允许工具和客户端库使用您的凭据配置,请执行以下操作:

  1. 初始化环境变量 GOOGLE_APPLICATION_CREDENTIALS 并将其指向凭据配置文件:

    Bash

      export GOOGLE_APPLICATION_CREDENTIALS=`pwd`/FILEPATH.json
      
    其中,FILEPATH 是凭据配置文件的相对路径。

    PowerShell

      $env:GOOGLE_APPLICATION_CREDENTIALS = Resolve-Path 'FILEPATH.json'
      
    其中,FILEPATH 是凭据配置文件的相对路径。
  2. 使用支持工作负载身份联合并且可以自动查找凭据的客户端库或工具:

    C++

    v2.6.0 版开始,C++ 版 Google Cloud 客户端库支持工作负载身份联合。如需使用工作负载身份联合,您必须使用 1.36.0 版或更高版本的 gRPC 构建客户端库。

    Go

    如果 Go 客户端库使用 golang.org/x/oauth2 模块的 v0.0.0-20210218202405-ba52d332ba99 版本或更高版本,则客户端库支持工作负载身份联合。

    如要查看客户端库使用的模块版本,请运行以下命令:

    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 版或更高版本,则客户端支持工作负载身份联合。

    如需查看该客户端库使用的工件版本,请在应用目录中运行以下 Maven 命令:

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

    Node.js

    如果 Node.js 版客户端库使用 7.0.2 版或更高版本的 google-auth-library 软件包,则该客户端库支持工作负载身份联合。

    如要查看客户端库使用的软件包版本,请在应用目录中运行以下命令:

    npm list google-auth-library
    

    创建 GoogleAuth 对象时,您可以指定项目 ID,也可以允许 GoogleAuth 自动查找项目 ID。如要自动查找项目 ID,配置文件中的服务账号必须具有项目的 Browser 角色 (roles/browser) 或具有同等权限的角色。如需了解详情,请参阅 google-auth-library 软件包的 README

    Python

    如果 Python 客户端库使用 google-auth 软件包的 1.27.0 版本或更高版本,则客户端支持工作负载身份联合。

    如要检查客户端库使用的软件包版本,请在已安装该软件包的环境中运行以下命令:

    pip show google-auth
    

    如要为身份验证客户端指定项目 ID,您可以设置 GOOGLE_CLOUD_PROJECT 环境变量,也可以允许客户端自动查找项目 ID。如要自动查找项目 ID,配置文件中的服务账号必须具有项目的 Browser 角色 (roles/browser) 或具有同等权限的角色。如需了解详情,请参阅 google-auth 软件包用户指南

    gcloud

    如需使用工作负载身份联合进行身份验证,请使用 gcloud auth login 命令:

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

    FILEPATH 替换为凭据配置文件的路径。

    版本 363.0.0 及更高版本的 gcloud CLI 支持 gcloud CLI 中的工作负载身份联合。

    Terraform

    如果您使用 3.61.0 版或更高版本,则 Google Cloud 提供方支持工作负载身份联合:

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

    bq

    如需使用工作负载身份联合进行身份验证,请使用 gcloud auth login 命令,如下所示:

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

    FILEPATH 替换为凭据配置文件的路径。

    390.0.0 版及更高版本的 gcloud CLI 支持 bq 中的工作负载身份联合。

后续步骤