使用 Secret Manager 中的 Secret

本页面介绍如何在 Cloud Build 中添加密码和 API 密钥等敏感信息。

Secret Manager 是一项 Google Cloud服务,可安全存储 API 密钥、密码和其他敏感数据。如需在构建中包含敏感信息,您可以将信息存储在 Secret Manager 中,然后将构建配置为从 Secret Manager 中访问信息。

准备工作

  • 启用 Cloud Build API 和 Secret Manager API。

    启用 API 所需的角色

    如需启用 API,您需要拥有 serviceusage.services.enable 权限。如果您创建了项目,则可能已经通过 Owner 角色 (roles/owner) 获得了此权限。否则,您可以通过 Service Usage Admin 角色 (roles/serviceusage.serviceUsageAdmin) 获得此权限。了解如何授予角色

    启用 API

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

  • 确保您已将 Secret 存储在 Secret Manager 中。如需了解相关说明,请参阅创建 Secret

    • 记下 Secret 的 Secret 名称和 Secret 版本。您需要使用此信息将 Cloud Build 配置为访问 Secret。

必需的 IAM 权限

向您用于 build 的服务账号授予对 Secret 的 Secret Manager Secret Accessor (roles/secretmanager.secretAccessor) IAM 角色:

  1. 在 Google Cloud 控制台中打开 Secret Manager 页面:

    转到 Secret Manager 页面

  2. 选中您要在构建中使用的 Secret 对应的复选框。

  3. 如果面板尚未打开,请点击显示信息面板将其打开。

  4. 在面板中的权限下,点击添加主账号

  5. 新主账号字段中,输入服务账号的电子邮件地址。

  6. 选择角色下拉框中,选择 Secret Manager Secret Accessor

  7. 点击保存

配置构建以从 Secret Manager 访问 UTF-8 Secret

  1. 在项目根目录中,创建一个名为 cloudbuild.yamlcloudbuild.json Cloud Build 配置文件。

  2. 在构建配置文件中:

    • 在所有 build steps 之后,添加一个包含 secretManager 字段的 availableSecrets 字段。secretManager 字段包含一个或多个 versionNameenv 字段对:

      • versionName:Secret Manager 中 Secret 的路径。 您可以在此字段的值中添加替换变量
      • env:构建步骤可用于引用 Secret 的本地名称(环境变量)。
    • 在您要指定 Secret 的构建步骤中:

      • 添加指向 bashentrypoint 字段,以在构建步骤中使用 bash 工具。这是引用 Secret 的环境变量所必需的。
      • 添加了 secretEnv 字段。此字段用于指定相应步骤中可使用的环境变量。
      • args 字段中,添加 -c 标志作为第一个参数。您在 -c 之后传递的任何字符串均被视为命令。如需详细了解如何使用 -c 运行 bash 命令,请参阅 bash 文档
      • args 字段中指定 Secret 时,请使用前缀为 $$.

    The following example build config file shows how to login to Docker using the Docker username and password stored in Secret Manager:

    YAML

    steps:
    - name: 'gcr.io/cloud-builders/docker'
      entrypoint: 'bash'
      args: ['-c', 'docker login --username=$$USERNAME --password=$$PASSWORD']
      secretEnv: ['USERNAME', 'PASSWORD']
    availableSecrets:
      secretManager:
      - versionName: projects/PROJECT_ID/secrets/DOCKER_PASSWORD_SECRET_NAME/versions/DOCKER_PASSWORD_SECRET_VERSION
        env: 'PASSWORD'
      - versionName: projects/PROJECT_ID/secrets/DOCKER_USERNAME_SECRET_NAME/versions/DOCKER_USERNAME_SECRET_VERSION
        env: 'USERNAME'
    

    JSON

    {
      "steps": [
      {
        "name": "gcr.io/cloud-builders/docker",
        "entrypoint": "bash",
        "args": [
          "-c",
          "docker login --username=$$USERNAME --password=$$PASSWORD"
        ],
        "secretEnv": [
          "USERNAME",
          "PASSWORD"
        ]
      }
      ],
      "availableSecrets": {
        "secretManager": [{
          "versionName": "projects/PROJECT_ID/secrets/DOCKER_PASSWORD_SECRET_NAME/versions/DOCKER_PASSWORD_SECRET_VERSION",
          "env": "PASSWORD"
      }, {
        "versionName": "projects/PROJECT_ID/secrets/DOCKER_USERNAME_SECRET_NAME/versions/DOCKER_USERNAME_SECRET_VERSION",
        "env": "USERNAME"
         }]
      }
    }
    

    Replace the placeholder values in the preceding commands with the following:

    • PROJECT_ID: The project ID or project number of the Google Cloud project where you've stored your secrets.
    • DOCKER_USERNAME_SECRET_NAME: The secret name corresponding to your Docker username. You can get the secret name from the Secret Manager page in the Google Cloud console.
    • DOCKER_USERNAME_SECRET_VERSION: The secret version of your Docker username. You can get the secret version by clicking on a secret name on the Secret Manager page in the Google Cloud console.
    • DOCKER_PASSWORD_SECRET_NAME: The secret name corresponding to your Docker password. You can get the secret name from the Secret Manager page in the Google Cloud console.
    • DOCKER_PASSWORD_SECRET_VERSION: The secret version of your Docker password. You can get the secret version by clicking on a secret name on the Secret Manager page in the Google Cloud console.
  3. Use the build config file to start a build using the command line or to automate builds using triggers.

Example: Accessing secrets from scripts and processes

In this example, a secret is defined in the build step so that it can be used later in a script:

YAML

steps:
- name: python:slim
  entrypoint: python
  args: ['main.py']
  secretEnv: ['MYSECRET']
availableSecrets:
  secretManager:
  - versionName: projects/$PROJECT_ID/secrets/mySecret/versions/latest
    env: 'MYSECRET'

JSON

{
  "steps": [
  {
    "name": "python:slim",
    "entrypoint": "python",
    "args": [
        "main.py"
    ],
    "secretEnv": [
        "MYSECRET"
    ]
}
],
"availableSecrets": {
  "secretManager": [
    {
        "versionName": "projects/$PROJECT_ID/secrets/mySecret/versions/latest",
        "env": "MYSECRET"
    }
  ]
}
}

The following contents of main.py prints the first five characters of the secret:

import os
print(os.environ.get("MYSECRET", "Not Found")[:5], "...")

Example: authenticating to Docker

In some situations, before interacting with Docker images, your build would need to authenticate to Docker. For example, Docker authentication is required for builds to pull private images and push private or public images to Docker Hub. In these cases, you can store your Docker username and password in Secret Manager and then configure Cloud Build to access the username and password from Secret Manager. For instructions on doing this see Interacting with Docker Hub images.

Example: GitHub pull request creation

Another example where you might want to configure your build to access a sensitive information from Secret Manager is for creating a GitHub pull request in response to builds. To do this:

  • Create a GitHub token.
  • Store the GitHub token in Secret Manager.
  • In your build config file:
    • After all the build steps, add an availableSecrets field to specify the secret version and the environment variable to use for the GitHub token.
    • Add a build step to invoke the command to create a GitHub pull request.
  • Create a GitHub app trigger and use the build config file to invoke the trigger.

The following example config file shows how to create a GitHub pull request using the GitHub token:

YAML

steps:
- name: 'launcher.gcr.io/google/ubuntu1604'
  id: Create GitHub pull request
  entrypoint: bash
  args:
  - -c
  - curl -X POST -H "Authorization:Bearer $$GH_TOKEN" -H 'Accept:application/vnd.github.v3+json' https://api.github.com/repos/GITHUB_USERNAME/REPO_NAME/pulls -d '{"head":"HEAD_BRANCH","base":"BASE_BRANCH", "title":"NEW_PR"}'
  secretEnv: ['GH_TOKEN']
availableSecrets:
  secretManager:
  - versionName: projects/PROJECT_ID/secrets/GH_TOKEN_SECRET_NAME/versions/latest
    env: GH_TOKEN
 的环境变量指定该 Secret。

JSON

{
  "steps": [
  {
    "name": "launcher.gcr.io/google/ubuntu1604",
    "id": "Create GitHub pull request",
    "entrypoint": "bash",
    "args": [
      "-c",
       "curl -X POST -H \"Authorization:Bearer $$GH_TOKEN\" -H 'Accept:application/vnd.github.v3+json' https://api.github.com/repos/GITHUB_USERNAME/REPO_NAME -d '{\"head\":\"HEAD_BRANCH\",\"base\":\"BASE_BRANCH\", \"title\":\"NEW_PR\"}'
    ],
    "secretEnv": ['GH_TOKEN']
}
],
"availableSecrets": {
  "secretManager": [
  {
    "versionName": "projects/PROJECT_ID/secrets/GH_TOKEN_SECRET_NAME/versions/latest",
    "env": "GH_TOKEN"
  }
  ]
}
}

Replace the placeholder values in the preceding commands with the following:

  • PROJECT_ID: The project ID or project number of the Google Cloud project where you've stored your secrets.
  • GITHUB_USERNAME: The GitHub username of the repository owner.
  • REPO_NAME: The name of the GitHub repository.
  • HEAD_BRANCH: The name of the branch where the changes are implemented. For cross-repository pull requests in the same network, namespace head with a user like this: username:branch.
  • BASE_BRANCH: The name of the branch you want the changes pulled into. This should be an existing branch on the current repository. You cannot submit a pull request to one repository that requests a merge to a base of another repository.
  • GH_TOKEN_SECRET_NAME: The secret name corresponding to your GitHub token.
  • NEW_PR: The new pull request you want to create.

Configuring builds to access non-UTF-8 secrets from Secret Manager

  1. In your build config file, add a build step to access the secret version in Secret Manager and store it in a file. The following build step accesses secret-name and stores it in a file named decrypted-data.txt:

    YAML

    steps:
    - name: gcr.io/cloud-builders/gcloud
      entrypoint: 'bash'
      args: [ '-c', "gcloud secrets versions access latest --secret=secret-name --format='get(payload.data)' | tr '_-' '/+' | base64 -d > decrypted-data.txt" ]
    

    JSON

    {
      "steps": [
      {
        "name": "gcr.io/cloud-builders/gcloud",
        "entrypoint": "bash",
        "args": [
          "-c",
          "gcloud secrets versions access latest --secret=secret-name --format='get(payload.data)' | tr '_-' '/+' | base64 -d > decrypted-data.txt"
        ]
      }
      ]
    }
    
  2. Use the file with the decrypted data in a build step. The following code snippet uses decrypted-data.txt to login to a private Docker registry:

    YAML

    steps:
    - name: gcr.io/cloud-builders/gcloud
      entrypoint: 'bash'
      args: [ '-c', "gcloud secrets versions access latest --secret=secret-name --format='get(payload.data)' | tr '_-' '/+' | base64 -d > decrypted-data.txt" ]
    - name: gcr.io/cloud-builders/docker
      entrypoint: 'bash'
      args: [ '-c', 'docker login --username=my-user --password-stdin < decrypted-data.txt']
    

    JSON

    {
      "steps": [
      {
        "name": "gcr.io/cloud-builders/gcloud",
        "entrypoint": "bash",
        "args": [
          "-c",
          "gcloud secrets versions access latest --secret=secret-name --format='get(payload.data)' | tr '_-' '/+' | base64 -d > password.txt"
         ]
      },
      {
        "name": "gcr.io/cloud-builders/docker",
        "entrypoint": "bash",
        "args": [
          "-c",
          "docker login --username=my-user --password-stdin < decrypted-data.txt"
         ]
      }
      ]
    }