使用 X.509 证书配置 Workload Identity Federation

本指南介绍了如何将工作负载身份联合与由证书颁发机构 (CA) 颁发的 X.509 证书结合使用,以向 Google Cloud 进行身份验证并访问 Google Cloud 资源。

如果您的工作负载拥有 mTLS 客户端证书,您可以将一个或多个 CA 注册到工作负载身份联合作为信任锚,从而向Google Cloud 进行身份验证。您还可以注册中间 CA。

通过使用工作负载身份联合,您可以让这些工作负载通过双向 TLS (mTLS) 连接获取短期有效的 Google Cloud 凭据。工作负载可以使用这些短期有效的凭据访问Google Cloud API。

概念

基于 X.509 证书的联合身份验证概念包括:

  • 信任锚是指被视为信任根的 CA 证书。任何客户端证书链都应链接到其中一个信任锚点。

  • 中间 CA 是可选的证书授权机构证书,可帮助构建客户端证书链。

  • 信任库包含用于验证客户端证书链的信任锚证书和中间 CA 证书。CA 会为客户端颁发可信证书。

    您可以将以下类型的客户端证书上传到受信任证书存储区:

    • 您选择的第三方 CA 颁发的证书
    • 您的私有 CA 颁发的证书
    • 签名证书,如创建自签名证书中所述

准备工作

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

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

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  2. 我们建议您使用专用项目来管理工作负载身份池和提供方
  3. Verify that billing is enabled for your Google Cloud project.

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

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the APIs

所需的角色

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

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

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

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

创建受信任证书存储区

本部分介绍了如何创建受信任证书存储区。概括来讲,需要执行以下步骤:

生成自签名证书

本部分介绍了如何生成密钥和创建签名证书。如果您已创建证书,则可以跳过此部分,然后继续执行设置证书格式

本部分使用 openssl 命令创建根证书和中间证书。

如需生成具有有效 keyUsageextendedKeyUsage 字段的根证书和已签名中间证书,请执行以下操作:

  1. 创建 openssl 配置文件以创建签名证书。该文件至少应类似于以下内容,但您可以根据需要设置其他字段。

    cat > example.cnf << EOF
    [req]
    distinguished_name = empty_distinguished_name
    [empty_distinguished_name]
    # Kept empty to allow setting via -subj command-line argument.
    [ca_exts]
    basicConstraints=critical,CA:TRUE
    keyUsage=keyCertSign
    extendedKeyUsage=clientAuth
    [leaf_exts]
    keyUsage=critical,Digital Signature, Key Encipherment
    basicConstraints=critical, CA:FALSE
    EOF
    
  2. 创建根证书。

    openssl req -x509 \
        -new -sha256 -newkey rsa:2048 -nodes \
        -days 3650 -subj '/CN=root' \
        -config example.cnf \
        -extensions ca_exts \
        -keyout root.key -out root.cert
    
  3. 为中间证书创建签名请求。

    openssl req \
        -new -sha256 -newkey rsa:2048 -nodes \
        -subj '/CN=int' \
        -config example.cnf \
        -extensions ca_exts \
        -keyout int.key -out int.req
    
  4. 创建中间证书。

    openssl x509 -req \
        -CAkey root.key -CA root.cert \
        -set_serial 1 \
        -days 3650 \
        -extfile example.cnf \
        -extensions ca_exts \
        -in int.req -out int.cert
    
  5. 为叶证书创建签名请求。

    openssl req -new -sha256 -newkey rsa:2048 -nodes \
        -subj '/CN=example' \
        -config example.cnf \
        -extensions leaf_exts \
        -keyout leaf.key -out leaf.req
    
  6. 创建由中间方颁发的叶证书。

    openssl x509 -req \
        -CAkey int.key -CA int.cert \
        -set_serial 1 -days 3650 \
        -extfile example.cnf \
        -extensions leaf_exts \
        -in leaf.req -out leaf.cert
    

设置证书格式

如需在受信任证书存储区中添加新证书或现有证书,请将证书格式设置为单行字符串,并将它们存储在环境变量中。证书必须采用 PEM 格式。如需设置证书格式并将其存储在环境变量中,请执行以下操作:

  1. 将根证书保存为单行字符串。

    export ROOT_CERT=$(cat root.cert | sed 's/^[ ]*//g' | sed -z '$ s/\n$//' | tr '\n' $ | sed 's/\$/\\n/g')
    
  2. 将中间证书保存为单行字符串。

    export INTERMEDIATE_CERT=$(cat int.cert | sed 's/^[ ]*//g' | sed -z '$ s/\n$//' | tr '\n' $ | sed 's/\$/\\n/g')
    

创建受信任证书存储区

在本部分中,您将使用 YAML 格式的文件创建一个受信任证书存储区,该文件包含信任锚和中间 CA。

此文件包含您在设置证书格式中创建的环境变量的证书内容。如需添加其他信任锚点,请在 trustStore 下添加其他 trustAnchors 条目。如需添加其他中间 CA 证书,请在 trustStore 下添加其他 intermediateCas 条目。

如需创建受信任证书存储区文件,请运行以下命令:

cat << EOF > trust_store.yaml
trustStore:
  trustAnchors:
  - pemCertificate: "${ROOT_CERT}"
  intermediateCas:
  - pemCertificate: "${INTERMEDIATE_CERT}"
EOF

定义特性映射和条件

客户端 X.509 证书可以包含多个属性。您必须选择要用作主题标识符的属性,方法是将 Google Cloud 中的 google.subject 映射到证书中的属性。例如,如果证书中的属性是主题公用名,则映射如下所示:google.subject=assertion.subject.dn.cn

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

您的属性映射可以使用客户端证书中的属性,包括:

  • serialNumberHex:序列号
  • subject.dn.cn:主题通用名称
  • subject.dn.o:主题组织名称
  • subject.dn.ou:主题的最后一个组织部门
  • issuer.dn.cn:颁发机构的通用名称
  • issuer.dn.o:发卡组织名称
  • issuer.dn.ou:颁发机构的最后一个组织部门
  • san.dns:主题备用名称的第一个 DNS 名称
  • san.uri:主题备用名称的第一个 URI
  • sha256Fingerprint:SHA256 叶证书哈希 (Base64)

您必须将其中一个属性映射到 google.subject,以唯一标识主题。为了防止欺骗威胁,请选择具有不可更改的唯一值的属性。默认情况下,google.subject 标识符会设置为客户端证书主题常用名称 assertion.subject.dn.cn

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

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

例如,以下条件会限制对包含 SPIFFE ID spiffe://example/path 的客户端证书的访问权限:

assertion.san.uri=="spiffe://example/path"

配置工作负载身份联合

本部分介绍如何配置工作负载身份池和工作负载身份池提供方。您只需为每个信任库执行这些步骤一次。然后,您可以为多个工作负载以及多个 Google Cloud 项目使用相同的工作负载身份池和提供方。

创建工作负载身份池

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

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

    替换以下内容:

    • POOL_ID:池的唯一 ID。
    • DISPLAY_NAME:池的名称。
    • DESCRIPTION:您选择的池的说明。当您授予对池身份的访问权限时,系统会显示此说明。

创建工作负载身份池提供方

  1. 如需添加 X.509 工作负载身份池提供方,请运行以下命令:

    gcloud iam workload-identity-pools providers create-x509 PROVIDER_ID \
        --location=global \
        --workload-identity-pool="POOL_ID" \
        --trust-store-config-path="TRUST_STORE_CONFIG" \
        --attribute-mapping="MAPPINGS" \
        --attribute-condition="CONDITIONS"
    

    替换以下内容:

    • PROVIDER_ID:您选择的唯一工作负载身份池提供方 ID。
    • POOL_ID:您之前创建的工作负载身份池 ID。
    • TRUST_STORE_CONFIG:信任库 YAML 文件。
    • MAPPINGS:您在本指南前面部分中创建的以英文逗号分隔的属性映射列表。 例如 google.subject=assertion.subject.dn.cn
    • CONDITIONS:可选。您在本指南前面部分中创建的属性条件。如果您没有特性条件,请移除该参数。

对工作负载进行身份验证

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

允许外部工作负载访问 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.

      Roles required to enable APIs

      To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

      Enable the APIs

    2. 创建一个服务账号以代表工作负载。我们建议您为每个工作负载使用专用服务账号。该服务账号不需要与工作负载身份池位于同一项目中,但您必须引用包含该服务账号的项目。

    3. 向服务账号授予对您希望外部身份访问的资源的访问权限

  2. 如需让联合身份模拟服务账号,请执行以下操作:

控制台

如需使用 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

如需向联合主账号或主账号集授予 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:属性映射中的自定义属性的值

下载或创建凭据配置

Cloud 客户端库和 gcloud CLI 可以自动获取外部凭证,并使用这些凭证来模拟服务账号。如需让库和工具完成此过程,您必须提供凭证配置文件。此文件提供以下信息:

  • 从何处获取外部凭据
  • 要使用的工作负载身份池和提供商
  • 需要模拟的服务账号

此外,对于 X.509 证书联合,还需要提供证书配置文件。此文件包含 X.509 客户端证书和私钥文件的路径。

创建凭证和证书配置文件,让库可以使用 X.509 证书获取访问令牌。

直接资源访问权限

如需使用 gcloud iam workload-identity-pools create-cred-config 创建用于直接访问资源的凭据和证书配置文件,请执行以下操作:

gcloud iam workload-identity-pools create-cred-config \
  projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID \
    --credential-cert-path=CLIENT_CERT_PATH \
    --credential-cert-private-key-path=CLIENT_PRIVATE_KEY_PATH \
    --credential-cert-trust-chain-path=TRUST_CHAIN_PATH \
    --output-file=FILEPATH.json

替换以下内容:

  • PROJECT_NUMBER:包含工作负载身份池的项目的编号。
  • POOL_ID:工作负载身份池的 ID。
  • PROVIDER_ID:工作负载身份池提供方的 ID。
  • CLIENT_CERT_PATH:客户端证书文件的路径。
  • CLIENT_PRIVATE_KEY_PATH:客户端证书私钥文件的路径。
  • TRUST_CHAIN_PATH:可选。包含未在 x509 提供程序中配置的任何中间证书的信任链文件的路径。
  • FILEPATH:用于保存配置的文件。

运行此命令还会创建一个证书配置文件,并将其存储在默认的 gcloud CLI 位置:

  • Linux 和 macOS:~/.config/gcloud/certificate_config.json

  • Windows:%APPDATA%\gcloud\certificate_config.json

服务账号模拟

如需使用 gcloud iam workload-identity-pools create-cred-config 创建凭据和证书配置文件并模拟服务账号,请执行以下操作:

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 \
    --credential-cert-path=CLIENT_CERT_PATH \
    --credential-cert-private-key-path=CLIENT_KEY_PATH \
    --credential-cert-trust-chain-path=TRUST_CHAIN_PATH \
    --output-file=FILEPATH.json

替换以下内容:

  • PROJECT_NUMBER:包含工作负载身份池的项目的编号。
  • POOL_ID:工作负载身份池的 ID。
  • PROVIDER_ID:工作负载身份池提供方的 ID。
  • SERVICE_ACCOUNT_EMAIL:如果您使用服务账号模拟,请替换为服务账号的电子邮件地址。
  • SERVICE_ACCOUNT_TOKEN_LIFETIME:如果您使用服务账号模拟,则是服务账号访问令牌的有效期(以秒为单位)。如果省略,此有效期默认为一小时。如果您不使用服务账号模拟,请省略此标志。如需指定超过一小时的有效期,您必须配置 constraints/iam.allowServiceAccountCredentialLifetimeExtension 组织政策限制条件
  • CLIENT_CERT_PATH:客户端证书文件的路径。
  • CLIENT_PRIVATE_KEY_PATH:客户端证书私钥文件的路径。
  • TRUST_CHAIN_PATH:可选。包含未在 x509 提供程序中配置的任何中间证书的信任链文件的路径。
  • FILEPATH:用于保存配置的文件。

运行此命令还会创建一个证书配置文件,并将其存储在默认的 Google Cloud CLI 位置:

  • Linux 和 macOS:~/.config/gcloud/certificate_config.json

  • Windows:%APPDATA%\gcloud\certificate_config.json

使用凭据配置访问 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. 确保客户端库可以找到证书配置文件。证书配置文件位于以下路径之一:

    • 默认的 gcloud CLI 路径:

      • Linux 和 macOS:~/.config/gcloud/certificate_config.json

      • Windows:%APPDATA%\gcloud\certificate_config.json

    • GOOGLE_API_CERTIFICATE_CONFIG 环境变量中设置的路径。

  3. 使用以下支持工作负载身份联合(使用 X.509 证书)的 Cloud 客户端库。

    Go

    如果 Go 客户端库使用 cloud.google.com/go/auth 模块的 0.16.0 版或更高版本和 google.golang.org/api 模块的 0.189.0 版,则支持 X.509 工作负载身份联合。

    如要查看客户端库使用的这些模块的版本,请在包含模块 go.mod 文件的目录中运行以下命令:

      go list -m cloud.google.com/go/auth
      go list -m cloud.google.com/api
    

    Python

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

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

      pip show google-auth
    

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

  4. 如果您的工作负载在 macOS 上运行,请设置 CLOUDSDK_PYTHON_SITEPACKAGES=1 以将 gcloud CLI 配置为使用其安装目录外部的 Python 库。

  5. 如需使用 gcloud CLI 进行身份验证,请运行以下命令:

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

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

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

使用纯文本请求获取访问 Google Cloud的访问令牌

创建信任链

此步骤将介绍如何创建信任链。在明文请求中调用 Security Token Service 时,您可以在 subject_token 字段中传递信任链。

将需要包含在链中的证书格式设置为 JSON 格式的列表,如 RFC 7515 中所指定。用于 mTLS 握手的叶证书必须指定为第一个项。软件包中的每个证书都应是 base64 编码的字符串。

  1. 将叶证书和中间证书保存为 base64 编码的字符串。

    export LEAF_CERT=$(openssl x509 -in leaf.cert -out leaf.der -outform DER && cat leaf.der | openssl enc -base64 -A)
    
    export INTERMEDIATE_CERT=$(openssl x509 -in int.cert -out int.der -outform DER && cat int.der | openssl enc -base64 -A)
    
  2. 创建 JSON 格式的字符串列表,该列表可以作为 subject_token 在 Security Token Service 调用中进行传递(请参阅本文档后面部分)

    export TRUST_CHAIN="[\\\"${LEAF_CERT}\\\", \\\"${INTERMEDIATE_CERT}\\\"]"
    

获取访问令牌

如需获取访问令牌,请执行以下操作:

  1. 通过 mTLS 和客户端证书执行令牌交换:

    curl --key CLIENT_CERT_KEY \
    --cert CLIENT_CERT \
    --request POST 'https://sts.mtls.googleapis.com/v1/token' \
    --header "Content-Type: application/json" \
    --data-raw '{
        "subject_token_type": "urn:ietf:params:oauth:token-type:mtls",
        "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
        "audience": "WORKLOAD_IDENTITY_POOL_URI",
        "requested_token_type": "urn:ietf:params:oauth:token-type:access_token",
        "scope": "https://www.googleapis.com/auth/cloud-platform",
        "subject_token": "TRUST_CHAIN"
    }'
    

    替换以下内容:

    • CLIENT_CERT_KEY:客户端证书私钥
    • CLIENT_CERT:客户端证书
    • WORKLOAD_IDENTITY_POOL_URI:工作负载身份池提供方的网址,格式如下:

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

    • TRUST_CHAIN:验证叶证书所需的信任链,必须至少包含 CLIENT_CERT 作为第一个项。如果您按照设置证书格式部分中的说明操作,请将 TRUST_CHAIN 替换为 '"${TRUST_CHAIN}"'

  2. 使用上一步中生成的载体访问令牌访问Google Cloud 资源,例如:

    curl -X GET 'https://storage.googleapis.com/my_object' -H "Authorization: Bearer $ACCESS_TOKEN"
    

限制

下表列出了限制。

限制 备注
信任锚数量 3 每个证书的大小不得超过 32KB。
中间证书数量 10 每个证书的大小不得超过 32KB。
根证书和中间证书验证期间允许的名称限制条件数量 10
共享相同主体和主体公钥信息的中间证书数量 5 这是每个信任库的限制。
证书链深度 5 证书链的深度上限,包括根证书和客户端证书。
在尝试构建信任链时,评估中间证书的最大次数。 100
从客户端上传和传递的证书密钥

RSA 密钥可为 2048 位到 4096 位

ECDSA 证书必须使用 P-256 或 P-384 曲线

建议在常规用例中使用 RSA-2048 和 P-256,在最佳安全实践中使用其他算法
叶证书的最长有效期 390 天 如果颁发的叶证书已超过 390 天,系统将拒绝该证书

后续步骤