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
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
[KEYRING-NAME]is the name of the KeyRing to create
[KEY-NAME]is the name of the CryptoKey to create
global keyword is specified for the
--location flag. Cloud KMS
resources can be created in multiple geographic locations. Using
read operations are served from the data center closest to the requesting user
or service. However, write operations are served from multiple locations and
might be slower. For more information, refer to
Location in the Cloud KMS documentation.
Grant the Cloud Build service account access to the CryptoKey
To decrypt your resource during your build, you must grant the Cloud Build service account permission to access your CryptoKey. If it only needs to decrypt the file, you need only grant decrypt permission.
To grant permission:
- Visit the Cloud Console IAM menu.
- Copy the Cloud Build service account email address, which contains
- Visit the Cloud Console Encryption Keys menu.
- Select your KeyRing from the list.
- Click Show Info Panel to open the info panel.
- Click Permission.
- Click Add Member and fill the New members field with the service account email address.
- Under Select a role, choose Cloud KMS CryptoKey Decrypter.
- Click Save.
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:[PROJECT_NUMBER]@cloudbuild.gserviceaccount.com \ --role=roles/cloudkms.cryptoKeyDecrypter
To learn more about this command, see the
gcloud kms keys documentation.
If you do not know your Cloud Build service account email address,
visit the Google Cloud Console IAM menu.
The service account email address contains
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
secrets.json. The file must be no larger than 64 KiB.
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
the CryptoKey. The encrypted value is a base64-encoded string so you can easily
include the value in your build request. Ensure that you do not include any
extraneous characters, such as spaces or newlines, when encrypting the variable.
In the example above, the
-n flag instructs
echo not to include a
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]
[PROJECT_ID]is the ID for your project.
[base64-encoded encrypted secret]is the base64-encoded string of your password. The string should be specified as a single unbroken line in the build request.
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']
Only the environment variable's name is included in the
secretEnv field. If
you specify a value, or if there is a non-secret environment variable with the
same name, the build is rejected.
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
docker push the image from the user's repository to Dockerhub using those