授予服务到服务访问权限

如果您的架构使用了多项服务,您可能需要凭据才能在服务之间进行通信。Cloud Build 内置了对 OpenID Connect (OIDC) 标准的支持,以便在服务间进行安全的身份验证和授权。

您可以使用 Cloud Build 生成 ID 令牌。使用这些令牌,您可以从 Cloud Build 中调用安全端点。

例如,如果您运行的是无服务器平台应用(如 Cloud Functions、Cloud Run 或 App Engine),则可以在 Cloud Build 工作负载中与您的应用安全地进行交互。

准备工作

  • 启用 Cloud Build and IAM API。

    启用 API

  • 如果您打算使用此帐号创建短期有效凭据,则还需要启用 IAM Service Account Credentials API。

    启用 API

  • 如需使用本指南中的命令行示例,请安装并配置 Google Cloud CLI

  • 确保您已经创建了要使用的服务账号。 您必须在运行构建的同一 Google Cloud 项目中创建帐号。

必需的 IAM 权限

用户指定的服务帐号必须具有 iam.serviceAccounts.getOpenIdToken 权限。

如需了解如何向服务帐号授予 IAM 角色,请参阅管理对服务帐号的访问权限

获取 ID 令牌的方法

您可以通过以下两种方式配置构建步骤以获取 ID 令牌:

  • 使用 gcloud CLI
  • 向元数据服务器发送直接请求

通过 gcloud 获取 ID 令牌

在本部分中,以下代码段演示了如何使用 gcloud CLI 获取 ID 令牌:

YAML

steps:

- name: 'gcr.io/cloud-builders/gcloud'
  script: 'gcloud auth print-identity-token --audiences ${_TOKEN_AUDIENCE} > /workspace/identity_token.txt'
  env:
  - _TOKEN_AUDIENCE=${_TOKEN_AUDIENCE}
service_account: '$_SERVICE_ACCOUNT'
substitutions:
  _TOKEN_AUDIENCE: 'TOKEN_AUDIENCE'
  _SERVICE_ACCOUNT_ID: 'SERVICE_ACCOUNT_ID'
  _SERVICE_ACCOUNT: 'projects/${PROJECT_ID}/serviceAccounts/${_SERVICE_ACCOUNT_ID}'
logsBucket: 'LOGS_BUCKET_LOCATION'
options:
  logging: GCS_ONLY
  dynamic_substitutions: true

JSON

{
  "steps": [
      {
          "name": "gcr.io/cloud-builders/gcloud",
          "script": "gcloud auth print-identity-token --audiences ${_TOKEN_AUDIENCE} > /workspace/identity_token.txt"
          "env": [
              "_TOKEN_AUDIENCE=${_TOKEN_AUDIENCE}"
          ]
      }
  ],
  "service_account": "$_SERVICE_ACCOUNT",
  "substitutions": {
      "_TOKEN_AUDIENCE": "TOKEN_AUDIENCE",
      "_SERVICE_ACCOUNT_ID": "SERVICE_ACCOUNT_ID",
      "_SERVICE_ACCOUNT": "projects/${PROJECT_ID}/serviceAccounts/${_SERVICE_ACCOUNT_ID}"
  },
  "logsBucket": "LOGS_BUCKET_LOCATION",
  "options": {
      "logging": "GCS_ONLY",
      "dynamic_substitutions": true
  }
}

替换以下内容:

  • TOKEN_AUDIENCE 是要获取其 ID 令牌的网址或目标受众群体,例如 http://www.example.com
  • SERVICE_ACCOUNT_ID 是用户指定服务帐号的电子邮件地址或唯一 ID。例如 service-account-name@project-id.iam.gserviceaccount.com
  • LOGS_BUCKET_LOCATION 是用于存储构建日志的 Cloud Storage 存储桶。例如 gs://mylogsbucket

向元数据服务器发送直接请求

在本部分中,以下代码段演示了如何向元数据服务器发出直接请求以获取 ID 令牌:

YAML

steps:
- name: 'gcr.io/cloud-builders/curl'
  id: 'printTokenFromCurl'
  script: |
    curl -H 'Metadata-Flavor: Google' http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience=${_TOKEN_AUDIENCE} -o /workspace/identity_token.txt
  env:
  - _TOKEN_AUDIENCE=${_TOKEN_AUDIENCE}
service_account: '$_SERVICE_ACCOUNT'
substitutions:
  _TOKEN_AUDIENCE: 'TOKEN_AUDIENCE'
  _SERVICE_ACCOUNT_ID: 'SERVICE_ACCOUNT_ID'
  _SERVICE_ACCOUNT: 'projects/${PROJECT_ID}/serviceAccounts/${_SERVICE_ACCOUNT_ID}'
logsBucket: 'LOGS_BUCKET_LOCATION'
options:
  logging: GCS_ONLY
  dynamic_substitutions: true

JSON

{
  "steps": [
      {
          "name": "gcr.io/cloud-builders/curl",
          "id": "printTokenFromCurl"
          "script": "curl -H 'Metadata-Flavor: Google' http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience=${_TOKEN_AUDIENCE} -o /workspace/identity_token.txt"
          "env":
              "_TOKEN_AUDIENCE=${_TOKEN_AUDIENCE}"
      }
  ],
  "service_account": "$_SERVICE_ACCOUNT",
  "substitutions": {
      "_TOKEN_AUDIENCE": "TOKEN_AUDIENCE",
      "_SERVICE_ACCOUNT_ID": "SERVICE_ACCOUNT_ID",
      "_SERVICE_ACCOUNT": "projects/${PROJECT_ID}/serviceAccounts/${_SERVICE_ACCOUNT_ID}"
  },
  "logsBucket": "LOGS_BUCKET_LOCATION",
  "options": {
      "logging": "GCS_ONLY",
      "dynamic_substitutions": true
  }
}

替换以下内容:

  • TOKEN_AUDIENCE 是要获取其 ID 令牌的网址或目标受众群体,例如 http://www.example.com
  • SERVICE_ACCOUNT_ID 是用户指定服务帐号的电子邮件地址或唯一 ID。例如 service-account-name@project-id.iam.gserviceaccount.com
  • LOGS_BUCKET_LOCATION:用于存储构建日志的 Cloud Storage 存储桶。例如 gs://mylogsbucket

有关在工作负载中生成和使用 ID 令牌的其他说明,请参阅获取 ID 令牌的方法

后续步骤