Cloud Build integration

This page provides an overview of how to set up Binary Authorization with Cloud Build. This setup helps ensure that only container images built and signed as part of the Cloud Build build process are automatically authorized to run in your deployment environment.

For information on adding vulnerability scanning to your Cloud Build build pipeline, see Vulnerability scanning with Container Analysis and Kritis Signer.

Overview

Cloud Build

Cloud Build (overview) takes source code stored in Cloud Source Repositories or another hosted repository, runs your builds and tests, and stores the resulting software outputs in Container Registry or another storage service on Google Cloud Platform.

Binary Authorization

Binary Authorization (overview) is a Google Cloud product that enforces deploy-time constraints on applications. Its Google Kubernetes Engine (GKE) integration allows users to enforce that containers deployed to a Kubernetes cluster are cryptographically signed by a trusted authority and verified by a Binary Authorization attestor.

You can configure Binary Authorization to require attestations based on the location of the source code to prevent container images built from unauthorized source from being deployed.

To learn more:

Architecture

The following diagram shows the components in a Binary Authorization/Cloud Build setup:

Cloud Build Binary Authorization attestation pipeline.
Figure 1. Diagram of a Cloud Build Binary Authorization attestation pipeline.

In figure 1, (1) Code is pushed to a repository. (2) A continuous integration (CI) pipeline, such as Cloud Build, builds and tests the container. (3) The newly built container image is submitted to Container Registry. (4) Cloud Key Management Service signs the container image, (5) creates an attestation and stores it in Binary Authorization.

The components are:

  • Cloud Source Repositories or another secure repository that contains the source code used to build a container image.

  • Cloud Build, which runs builds and tests, and outputs the container image to Container Registry or another software registry that stores your built images.

  • Container Registry, a private container image registry that runs on Google Cloud.

  • Cloud Key Management Service, which provides key management for the cryptographic key pair. The key pair comprises a private key and a public key. The private key is used to sign a container image. The resulting signature is then stored in a newly created attestation. At deploy time, the attestation is verified by an attestor comprising the public key from the key pair.

  • Binary Authorization, which enforces the policy requiring signed attestations before a container image can be deployed.

Create a Binary Authorization attestation using Cloud Build with Cloud Key Management Service

This section shows you how to implement the above architecture. It uses an open source custom build step from the Cloud Build community. The custom build step signs a container image, creates the attestation, and uploads it to Binary Authorization.

Configure Identity and Access Management

To use this build step, the Cloud Build service account needs the following IAM roles:

  • Binary Authorization Attestor Viewer
    • roles/binaryauthorization.attestorsViewer
  • Cloud KMS CryptoKey Signer/Verifier (if using key in KMS to sign attestation)
    • roles/cloudkms.signerVerifier
  • Container Analysis Notes Attacher
    • roles/containeranalysis.notes.attacher

The following commands can be used to add the roles to your project's Cloud Build Service Account:

  1. Enable Cloud Build:

    Enable the Cloud Build API in the target Cloud project.

  2. Save your project ID to an environment variable:

    PROJECT_ID=PROJECT_ID
    

    where PROJECT_ID is your Google Cloud project ID.

  3. Set the project gcloud command-line tool:

    gcloud config set project ${PROJECT}
    
  4. Get the project number:

    PROJECT_NUMBER=$(gcloud projects list --filter="${PROJECT}" --format="value(PROJECT_NUMBER)")
    
  5. Add Binary Authorization Attestor Viewer role to Cloud Build Service Account:

    gcloud projects add-iam-policy-binding ${PROJECT} \
      --member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
      --role roles/binaryauthorization.attestorsViewer
    
  6. Add Cloud KMS CryptoKey Signer/Verifier role to Cloud Build Service Account (KMS-based Signing):

    gcloud projects add-iam-policy-binding ${PROJECT} \
      --member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
      --role roles/cloudkms.signerVerifier
    
  7. Add Container Analysis Notes Attacher role to Cloud Build Service Account:

    gcloud projects add-iam-policy-binding ${PROJECT} \
      --member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
      --role roles/containeranalysis.notes.attacher
    

Build and register the custom build step with Cloud Build

  1. Clone the Google Cloud build community repo:

    git clone https://github.com/GoogleCloudPlatform/cloud-builders-community.git
    
  2. Configure the Binary Authorization signer for Cloud Build:

    Before use, the code for the custom build step must be built into a container and pushed to Cloud Build. To do this, run the following commands:

    cd cloud-builders-community/binauthz-attestation
    gcloud builds submit . --config cloudbuild.yaml
    

    The custom build step was pushed to your current project's Google Container Registry and is now ready for use.

Create an attestor in Binary Authorization

Create an attestor that Binary Authorization will use at deploy time to verify the attestation.

Set up an attestor and Cloud Key Management Service key pair in Binary Authorization:

See Create an attestor using the CLI

Verify that the attestor was created

   gcloud --project="${ATTESTOR_PROJECT_ID}" container binauthz attestors list
   

Add a "create-attestation" step to your cloudbuild.yaml

To use the binauthz-attestation step, you must update your cloudbuild.yaml by adding the step that will sign the build that has been pushed to Container Registry.

Two methods are provided below:

  • Update your cloudbuild.yaml manually.

  • Run an example pipeline with the environment variables you set earlier.

Update your cloudbuild.yaml manually

  1. Update your cloudbuild.yaml manually by adding the build step below after the step where your container is uploaded to Container Registry. Note: you must replace ATTESTOR_NAME, KMS_KEY_LOCATION, KMS_KEYRING_NAME, KMS_KEY_NAME, and KMS_KEY_VERSION with your own values manually:

    - id: 'create-attestation'
      name: 'gcr.io/${PROJECT_ID}/binauthz-attestation:latest'
      args:
        - '--artifact-url'
        - 'gcr.io/${PROJECT_ID}/helloworld:latest'
        - '--attestor'
        - 'projects/${PROJECT_ID}/attestors/ATTESTOR_NAME'
        - '--keyversion'
        - 'projects/${PROJECT_ID}/locations/KMS_KEY_LOCATION/keyRings/KMS_KEYRING_NAME/cryptoKeys/KMS_KEY_NAME/cryptoKeyVersions/KMS_KEY_VERSION'
    

    The following is also valid:

    - id: 'create-attestation'
      name: 'gcr.io/${PROJECT_ID}/binauthz-attestation:latest'
      args:
        - '--artifact-url'
        - 'gcr.io/${PROJECT_ID}/helloworld:latest'
        - '--attestor'
        - 'ATTESTOR_NAME'
        - '--attestor-project'
        - '${PROJECT_ID}'
        - '--keyversion'
        - 'KEY_VERSION'
        - '--keyversion-project'
        - '${PROJECT_ID}'
        - '--keyversion-location'
        - 'KEY_LOCATION'
        - '--keyversion-keyring'
        - 'KEYRING_NAME'
        - '--keyversion-key'
        - 'KEY_NAME'
    

[Optional] Test the pipeline

To test an example Cloud Build attestation pipeline, perform the following steps:

  1. Create a cloudbuild.yaml file with the environment variables you set earlier:

    cd example
    cat <<EOM > cloudbuild_example.yaml
    steps:
      - id: 'build'
        name: 'gcr.io/cloud-builders/docker'
        args:
          - 'build'
          - '-t'
          - 'gcr.io/$PROJECT_ID/helloworld:latest'
          - '.'
      - id: 'publish'
        name: 'gcr.io/cloud-builders/docker'
        args:
          - 'push'
          - 'gcr.io/$PROJECT_ID/helloworld:latest'
      - id: 'create-attestation'
        name: 'gcr.io/$PROJECT_ID/binauthz-attestation:latest'
        args:
          - '--artifact-url'
          - 'gcr.io/$PROJECT_ID/helloworld:latest'
          - '--attestor'
          - 'projects/$PROJECT_ID/attestors/${ATTESTOR_NAME}'
          - '--keyversion'
          - 'projects/${PROJECT_ID}/locations/${KMS_KEY_LOCATION}/keyRings/${KMS_KEYRING_NAME}/cryptoKeys/${KMS_KEY_NAME}/cryptoKeyVersions/${KMS_KEY_VERSION}'
    tags: ['cloud-builders-community']
    
    EOM
    
  2. Run Cloud Build with the example cloudbuild_example.yaml:

    From the cloud-builders-community/binauthz-attestation/example directory, run the following commands:

    gcloud builds submit . --config cloudbuild_example.yaml
    

What's next