使用 Secret Manager 中的密鑰

本頁面說明如何在 Cloud Build 中加入密碼及 API 金鑰等機密資訊。

Secret Manager 是 Google Cloud服務,可安全地儲存 API 金鑰、密碼和其他機密資料。如要在建構中加入機密資訊,您可以將資訊儲存在 Secret Manager 中,然後設定建構項目,以便從 Secret Manager 存取資訊。

事前準備

  • Enable the Cloud Build and Secret Manager APIs.

    Enable the APIs

  • 如要使用本指南提供的指令列範例,請安裝並設定 Google Cloud CLI

  • 請確認您已將密鑰儲存在 Secret Manager 中。如需操作說明,請參閱「建立密鑰」。

    • 請記下密鑰的名稱和密鑰版本。您需要這些資訊才能設定 Cloud Build 存取機密。

必要的 IAM 權限

Secret Manager 密鑰存取者 (roles/secretmanager.secretAccessor) IAM 角色授予您用於建構的服務帳戶:

  1. 在 Google Cloud 控制台中開啟「Secret Manager」頁面:

    前往「Secret Manager」頁面

  2. 找出要用於版本的機密金鑰,然後勾選對應的核取方塊。

  3. 如果資訊面板尚未開啟,請按一下「Show info panel」來開啟面板。

  4. 在面板的「權限」下方,按一下「新增主體」

  5. 在「New principals」(新增主體) 欄位中,輸入服務帳戶的電子郵件地址。

  6. 在「Select a role」(請選擇角色) 下拉式方塊中,選取「Secret Manager Secret Accessor」(Secret Manager Secret Accessor)

  7. 按一下 [儲存]

設定版本,以便從 Secret Manager 存取 UTF-8 密鑰

  1. 在專案根目錄中,建立名為 cloudbuild.yamlcloudbuild.json 的 Cloud Build 設定檔。

  2. 在建構設定檔中:

    • 完成所有建構 steps 後,請新增 availableSecrets 欄位,指定要用於機密資料的機密資料版本和環境變數。您可以在 secretVersion 欄位的值中加入替換變數。您可以在建構中指定多個機密。
    • 在要指定機密金鑰的建構步驟中:
      • 新增指向 bashentrypoint 欄位,即可在建構步驟中使用 bash 工具。這是必要的做法,可參照機密金鑰的環境變數。
      • 新增指定環境變數的 secretEnv 欄位。
      • args 欄位中,新增 -c 標記做為第一個引數。您在 -c 後方傳遞的任何字串都會視為指令。如要進一步瞭解如何使用 -c 執行 bash 指令,請參閱 bash 說明文件
      • args 欄位中指定機密資料時,請使用前面加上 $$.

    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
 的環境變數指定

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:您儲存祕密的 Google Cloud 專案 ID。
  • GITHUB_USERNAME:存放區擁有者的 GitHub 使用者名稱。
  • REPO_NAME:GitHub 存放區的名稱。
  • HEAD_BRANCH:變更實作所在的分支名稱。如果是同一個網路中的跨存放區提取要求,請使用命名空間 head 和使用者,例如:username:branch
  • BASE_BRANCH:您要將變更項目拉取至的子系名稱。這個分支版本必須是目前存放區中現有的分支版本。您無法向存放區提交提取要求,要求將合併至另一個存放區的基礎。
  • GH_TOKEN_SECRET_NAME:與 GitHub 權杖相對應的祕密名稱。
  • NEW_PR:您要建立的新拉取要求。

設定版本,以便從 Secret Manager 存取非 UTF-8 密鑰

  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. 使用建構設定檔透過指令列啟動建構作業,或使用觸發條件自動化建構作業

後續步驟