Utiliser des secrets depuis Secret Manager

Cette page explique comment inclure des informations sensibles telles que des mots de passe et des clés API dans Cloud Build.

Secret Manager est un service Google Cloud qui stocke de manière sécurisée des clés API, des mots de passe et d'autres données sensibles. Pour inclure des informations sensibles dans vos compilations, vous pouvez les stocker dans Secret Manager, puis configurer votre compilation pour accéder aux informations de Secret Manager.

Avant de commencer

  • Activer les API Cloud Build and Secret Manager.

    Activer les API

  • Pour utiliser les exemples de ligne de commande de ce guide, installez et configurez la Google Cloud CLI.

  • Assurez-vous d'avoir stocké le secret dans Secret Manager. Pour obtenir des instructions, consultez la section Créer un secret.

    • Notez le nom et la version du secret. Vous aurez besoin de ces informations pour configurer Cloud Build et lui permettre d'accéder au secret.

Autorisations IAM requises

Attribuez le rôle IAM Accesseur de secrets (roles/secretmanager.secretAccessor) pour le secret au compte de service que vous utilisez pour la compilation:

  1. Ouvrez la page Secret Manager dans la console Google Cloud:

    Accéder à la page Secret Manager

  2. Cochez la case correspondant au secret que vous souhaitez utiliser dans votre compilation.

  3. S'il n'est pas déjà ouvert, cliquez sur Afficher le panneau d'informations pour ouvrir celui-ci.

  4. Dans le panneau, sous Autorisations, cliquez sur Ajouter un compte principal.

  5. Dans le champ Nouveaux comptes principaux, saisissez l'adresse e-mail de votre compte de service.

  6. Dans la boîte déroulante Sélectionnez un rôle, choisissez Accesseur de secrets Secret Manager.

  7. Cliquez sur Enregistrer.

Configurer les compilations pour accéder à des secrets UTF-8 à partir de Secret Manager

  1. Dans le répertoire racine de votre projet, créez un fichier de configuration de compilation nommé cloudbuild.yaml ou cloudbuild.json.

  2. Dans le fichier de configuration de compilation :

    • Après toutes les étapes steps de la compilation, ajoutez un champ availableSecrets spécifiant la version du secret et les variables d'environnement à utiliser pour votre secret. Vous pouvez inclure des variables de substitution dans la valeur du champ secretVersion. Vous pouvez spécifier plusieurs secrets dans une compilation.
    • À l'étape de compilation où vous souhaitez spécifier le secret :
      • Ajoutez un champ entrypoint pointant vers bash pour utiliser l'outil bash dans l'étape de compilation. Ce champ est obligatoire pour faire référence à la variable d'environnement du secret.
      • Ajoutez un champ secretEnv spécifiant la variable d'environnement.
      • Dans le champ args, ajoutez une option -c en tant que premier argument. Toutes les chaînes que vous transmettez après -c sont traitées comme des commandes. Pour en savoir plus sur l'exécution des commandes bash avec -c, consultez la documentation bash.
      • Lorsque vous spécifiez le secret dans le champ args, spécifiez-le à l'aide de la variable d'environnement précédée de $$.

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

Remplacez les valeurs d'espace réservé dans les commandes ci-dessus par les éléments suivants :

  • PROJECT_ID: ID du projet Google Cloud dans lequel vous avez stocké vos secrets.
  • GITHUB_USERNAME : nom d'utilisateur GitHub du propriétaire du dépôt.
  • REPO_NAME : nom du dépôt GitHub.
  • HEAD_BRANCH : nom de la branche dans laquelle les modifications sont mises en œuvre. Pour les demandes d'extraction inter-dépôts dans le même réseau, espace de noms head avec un utilisateur semblable à celui-ci : username:branch.
  • BASE_BRANCH : nom de la branche dans laquelle vous souhaitez intégrer les modifications. Il doit s'agir d'une branche existante du dépôt actuel. Vous ne pouvez pas envoyer de demande d'extraction à un dépôt qui demande une fusion avec une base d'un autre dépôt.
  • GH_TOKEN_SECRET_NAME : nom du secret correspondant à votre jeton GitHub.
  • NEW_PR : nouvelle demande d'extraction que vous souhaitez créer.

Configurer les compilations pour accéder à des secrets non UTF-8 à partir de Secret Manager

  1. Dans votre fichier de configuration de compilation, ajoutez une étape de compilation pour accéder à la version du secret dans Secret Manager et la stocker dans un fichier. L'étape de compilation suivante accède à secret-name et le stocke dans un fichier nommé 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. Utilisez le fichier avec les données déchiffrées dans une étape de compilation. L'extrait de code suivant utilise decrypted-data.txt pour se connecter à un registre Docker privé :

    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. Utilisez le fichier de configuration de compilation pour démarrer une compilation sur la ligne de commande ou pour automatiser les compilations à l'aide de déclencheurs.

Étapes suivantes