Using Encrypted Resources

This page explains how to use encrypted resources in your build requests. You can use encrypted resources like files or variables to pass sensitive information, such as authorization tokens, to your build steps.

You can encrypt and decrypt resources using Cloud Key Management Service (Cloud KMS) CryptoKeys, which allow you to flexibly and easily manage access to and rotation of encryption keys. CryptoKeys are stored in KeyRings, which are groupings of CryptoKeys for organizational purposes.

You should complete the Cloud KMS Quickstart to become familiar with Cloud KMS and to enable the Cloud KMS API.

Creating a Cloud KMS KeyRing and CryptoKey

You can create KeyRings and CryptoKeys using the gcloud kms keyrings create and gcloud kms keys create commands.

To create a KeyRing, run the following command in your shell or terminal window:

gcloud kms keyrings create [KEYRING-NAME] \
  --location=global

To create a CryptoKey:

gcloud kms keys create [KEY-NAME] \
  --location=global \
  --keyring=[KEYRING-NAME] \
  --purpose=encryption

where:

  • [KEYRING-NAME] is the name of the KeyRing to create
  • [KEY-NAME] is the name of the CryptoKey to create

Grant the Container Builder service account access to the CryptoKey

To decrypt your resource during your build, you must grant the Container Builder service account permission to access your CryptoKey. If it only needs to decrypt the file, you need only grant decrypt permission.

To grant permission:

Console

  1. Visit the GCP Console IAM menu.
  2. Copy the Container Builder service account email address, which contains @cloudbuild.gserviceaccount.com.
  3. Visit the GCP Console Encryption Keys menu.
  4. Select your KeyRing from the list, then click Permission.
  5. Fill the Add members field with the service account email address.
  6. From the Roles drop-down menu, choose Cloud KMS CryptoKey Decrypter.
  7. Click Add.

gcloud

Run the following command from your shell or terminal window:

gcloud kms keys add-iam-policy-binding \
    [KEY-NAME] --location=global --keyring=[KEYRING-NAME] \
    --member=serviceAccount:[SERVICE-ACCOUNT]@cloudbuild.gserviceaccount.com \
    --role=roles/cloudkms.cryptoKeyEncrypterDecrypter

To learn more about this command, see the gcloud kms keys documentation.

If you do not know your Container Builder service account email address, visit the Google Cloud Platform Console IAM menu. The service account email address contains @cloudbuild.gserviceaccount.com.

To learn more about granting access to keys, refer to Using IAM with Cloud KMS in the Cloud KMS documentation.

Encrypting a file using the CryptoKey

To encrypt a file, run the following command in your shell or terminal window:

gcloud kms encrypt \
  --plaintext-file=secrets.json \
  --ciphertext-file=secrets.json.enc \
  --location=global \
  --keyring=[KEYRING-NAME] \
  --key=[KEY-NAME]

This produces an encrypted file named secrets.json.enc, which contains the contents of secrets.json.

Storing the encrypted file

Once you've encrypted your file, you can store it in the same location as your source code, such as in a Cloud Source Repository or in a connected GitHub or Bitbucket repository.

For example, to add and commit the encrypted file to your Git repository:

git add secrets.json.enc
git commit -am "Add encrypted secrets.json.enc"
git push

To avoid committing the plaintext secrets.json file to your repository, add the file name to your repository's .gitignore file.

echo "secrets.json" >> .gitignore
git commit -am "Add secrets.json to .gitignore"
git push

Decrypting the file during your build

Now that your file is encrypted with an encryption key that your builder service account can access, you can add a build step to decrypt the contents of the encrypted file.

In your build request, before any build steps that interact with the decrypted secrets.json file, add a build step that calls the gcloud builder to decrypt secrets.json.enc using the encryption key. This build step is similar to the commands used to encrypt the file.

steps:
- name: gcr.io/cloud-builders/gcloud
  args:
  - kms
  - decrypt
  - --ciphertext-file=secrets.json.enc
  - --plaintext-file=secrets.json
  - --location=global
  - --keyring=[KEYRING-NAME]
  - --key=[KEY-NAME]
# more steps here

After this step completes, any subsequent steps can use the decrypted secrets.json file in the workspace directory.

For example, you can use the secrets in this file to fetch external dependencies or to include secret tokens in Docker container images you build.

Encrypting an environment variable using the CryptoKey

To encrypt an environment variable, run the following command in your shell or terminal window:

echo -n $MY_SECRET | gcloud kms encrypt \
  --plaintext-file=- \  # - reads from stdin
  --ciphertext-file=- \  # - writes to stdout
  --location=global \
  --keyring=[KEYRING-NAME] \
  --key=[KEY-NAME] | base64

This command encrypts the value of the environment variable $MY_SECRET using the CryptoKey. The encrypted value is a base64-encoded string so you can easily include the value in your build request.

Using the encrypted variable in build requests

In your build request, include a secrets field, which specifies the encrypted value, and the CryptoKey to use to decrypt it:

secrets:
- kmsKeyName: projects/[PROJECT-ID]/locations/global/keyRings/[KEYRING-NAME]/cryptoKeys/[KEY-NAME]
  secretEnv:
    MY_SECRET: <base64-encoded encrypted secret>

In your build steps, specify that the decrypted value should be made available as an environment variable:

steps:
- name: 'my-builder-image'
  args: ['my', 'args']
  env: ['FOO=foo', 'BAR=bar']
  secretEnv: ['MY_SECRET']

Example build request using an encrypted variable

The following example build request pushes a Docker image to Dockerhub using an encrypted Dockerhub password:

steps:

# Pull a public image from Dockerhub.
- name: 'gcr.io/cloud-builders/docker'
  args: ['pull', 'ubuntu']

# Retag the image into a user's repository.
- name: 'gcr.io/cloud-builders/docker'
  args: ['tag', 'ubuntu', '[MY-USER]/myubuntu']

# Login to provide credentials for the push.
# PASSWORD is decrypted before this step runs.
# Note: You need a shell to resolve environment variables with $$
- name: 'gcr.io/cloud-builders/docker'
  entrypoint: 'bash'
  args: ['-c', 'docker login --username=[MY-USER] --password=$$PASSWORD']
  secretEnv: ['PASSWORD']

# Push the image to Dockerhub.
- name: 'gcr.io/cloud-builders/docker'
  args: ['push', '[MY-USER]/myubuntu']

secrets:
- kmsKeyName: projects/[PROJECT-ID]/locations/global/keyRings/[KEYRING-NAME]/cryptoKeys/[KEY-NAME]
  secretEnv:
    PASSWORD: <base64-encoded encrypted Dockerhub password>

In this example, the docker login step logs in to Dockerhub using the specified username and the decrypted Dockerhub password, so that the next step can docker push the image from the user's repository to Dockerhub using those credentials.

What's next

Was this page helpful? Let us know how we did:

Send feedback about...

Cloud Container Builder