使用来自 Secret Manager 的 Secret

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

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

准备工作

  • 启用 Cloud Build and Secret Manager API。

    启用 API

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

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

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

必需的 IAM 权限

将 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. 在构建配置文件中:

    • 在所有构建 steps 之后,添加 availableSecrets 字段以指定用于密文的密文版本和环境变量。您可以在 secretVersion 字段的值中添加替代变量。您可以在构建中指定多个 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 above commands with the following:

    • PROJECT_ID: The ID 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

secretEnv field adds the value of the secret to the environment and you can access this value via environment variable from scripts or processes:

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"
  }
  ]
}
}

将上述命令中的占位值替换为以下内容:

  • PROJECT_ID:您存储 Secret 的 Google Cloud 项目的 ID。
  • GITHUB_USERNAME:代码库所有者的 GitHub 用户名。
  • REPO_NAME:GitHub 代码库的名称。
  • HEAD_BRANCH:在其中实现更改的分支的名称。对于同一网络中的跨代码库拉取请求,具有用户的命名空间 head 如下所示:username:branch
  • BASE_BRANCH:您希望将更改拉取到其中的分支的名称。此分支应该是当前代码库中的现有分支。您无法将拉取请求提交到一个请求与另一个代码库合并的代码库。
  • GH_TOKEN_SECRET_NAME:与您的 GitHub 令牌对应的 Secret 名称。
  • NEW_PR:您要创建的新拉取请求。

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

  1. 在构建配置文件中,添加构建步骤以访问 Secret Manager 中的密钥版本并将其存储在文件中。执行以下构建步骤可访问 secret-name 并将其存储在名为 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. 在构建步骤中使用包含解密后数据的文件。以下代码段使用 decrypted-data.txt 登录到私有 Docker 注册表:

    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"
         ]
      }
      ]
    }
    
  3. 使用构建配置文件通过命令行启动构建通过触发器自动执行构建

后续步骤