Usa Secrets de Secret Manager

En esta página, se explica cómo incluir información sensible, como contraseñas y claves de API en Cloud Build.

Secret Manager es un servicio de Google Cloud que almacena de manera segura claves de API, contraseñas y otros datos sensibles. Para incluir información sensible en las compilaciones, puedes almacenarla en Secret Manager y, luego, configurar la compilación para que acceda a ella.

Antes de comenzar

  • Habilita las API de Cloud Build and Secret Manager.

    Habilita las API

  • Para usar los ejemplos de línea de comandos de esta guía, instala y configura Google Cloud CLI.

  • Asegúrate de haber almacenado el Secret en Secret Manager. Para obtener instrucciones, consulta Crea un secreto.

    • Anota el nombre y la versión del secreto de tu secreto. Necesitarás esta información para configurar Cloud Build a fin de acceder al secreto.

Permisos de IAM obligatorios

Otorga el rol de IAM Descriptor de acceso a secretos de Secret Manager (roles/secretmanager.secretAccessor) para el secreto a la cuenta de servicio que usas para la compilación:

  1. Abre la página de Secret Manager en la consola de Google Cloud:

    Ir a la página Secret Manager

  2. Selecciona la casilla de verificación del secreto que deseas usar en tu compilación.

  3. Si aún no está abierto, haz clic en Mostrar panel de información para abrir el panel.

  4. En el panel, en Permisos, haz clic en Agregar principal.

  5. En el campo Principales nuevas, ingresa la dirección de correo electrónico de tu cuenta de servicio.

  6. En el cuadro desplegable Selecciona un rol, selecciona Secret Manager Secret Accessor.

  7. Haz clic en Guardar.

Configura compilaciones para acceder a Secrets UTF-8 desde Secret Manager

  1. En el directorio raíz del proyecto, crea un archivo de configuración de compilación de Cloud llamado cloudbuild.yaml o cloudbuild.json.

  2. En el archivo de configuración de compilación:

    • Después de todos los steps de compilación, agrega un campo availableSecrets para especificar la versión del secreto y las variables de entorno que se usarán en tu secreto. Puedes incluir variables de sustitución en el valor del campo secretVersion. Puedes especificar más de un secreto en una compilación.
    • En el paso de compilación en el que deseas especificar el secreto:
      • Agrega un campo entrypoint que apunte a bash para usar la herramienta bash en el paso de compilación. Esto es obligatorio para hacer referencia a la variable de entorno del secreto.
      • Agrega un campo secretEnv que especifique la variable de entorno.
      • En el campo args, agrega una marca -c como primer argumento. Cualquier string que pases después de -c se trata como un comando. Para obtener más información sobre cómo ejecutar comandos de Bash con -c, consulta la documentación de Bash.
      • Cuando especifiques el secreto en el campo args, hazlo mediante la variable de entorno con el prefijo $$.

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

Reemplaza los valores de marcador de posición en los comandos anteriores por la siguiente información:

  • PROJECT_ID: Es el ID del proyecto de Google Cloud en el que almacenaste tus secretos.
  • GITHUB_USERNAME: Es el nombre de usuario de GitHub del propietario del repositorio.
  • REPO_NAME: Es el nombre del repositorio de GitHub.
  • HEAD_BRANCH: Es el nombre de la rama en la que se implementan los cambios. En el caso de las solicitudes de extracción entre repositorios en la misma red, usa el espacio de nombres head con un usuario como este: username:branch.
  • BASE_BRANCH: El nombre de la rama de la que deseas obtener los cambios Debería ser una rama existente en el repositorio actual. No puedes enviar una solicitud de extracción a un repositorio que solicita una combinación a una base de otro repositorio.
  • GH_TOKEN_SECRET_NAME: Es el nombre del secreto correspondiente a tu token de GitHub.
  • NEW_PR: La solicitud de extracción nueva que deseas crear.

Configura compilaciones para acceder a secretos que no sean UTF-8 desde Secret Manager

  1. En tu archivo de configuración de compilación, agrega un paso de compilación para acceder a la versión del secreto en Secret Manager y almacenarla en un archivo. En el siguiente paso de compilación, se accede a secret-name y se almacena en un archivo llamado 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. Usa el archivo con los datos desencriptados en un paso de compilación. En el siguiente fragmento de código, se usa decrypted-data.txt para acceder a un registro privado de 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. Usa el archivo de configuración de compilación para iniciar una compilación con la línea de comandos o para automatizar compilaciones con activadores.

¿Qué sigue?