Using On-Demand Scanning as part of your Cloud Build pipeline allows you to block builds if the container image has vulnerabilities with a severity matching a predefined level.
This tutorial shows you how to use Cloud Build to build your container image from the source code, scan it for vulnerabilities, check the severity levels of the vulnerabilities, and push the image to Artifact Registry if there are no vulnerabilities of a specific severity level.
We recommend that you create a new Google Cloud project for this tutorial, and complete the steps in an isolated environment.
Prepare your source file
For this tutorial you are going to build an image from a Dockerfile. A Dockerfile is a source file that contains instructions for Docker to build an image.
Open a terminal, create a new directory named
ods-tutorial
, and navigate to it:mkdir ods-tutorial && cd ods-tutorial
Create a file named
Dockerfile
with the following contents:# Debian10 image FROM gcr.io/google-appengine/debian10:latest # Ensures that the built image is always unique RUN apt-get update && apt-get -y install uuid-runtime && uuidgen > /IAMUNIQUE
Create an Artifact Registry repository
Set the project ID to the same project where you enabled the APIs:
gcloud config set project PROJECT_ID
Create a Docker repository named
ods-build-repo
in the locationus-central1
:gcloud artifacts repositories create ods-build-repo --repository-format=docker \ --location=us-central1 --description="Repository for scan and build"
Verify that your repository was successfully created:
gcloud artifacts repositories list
Build and scan
In this section you will run your build pipeline using a build config file. A build config file instructs Cloud Build how to perform several tasks based on your specifications.
In the
ods-tutorial/
folder, create the filecloudbuild.yaml
with the following contents:steps: - id: build name: gcr.io/cloud-builders/docker entrypoint: /bin/bash args: - -c - | docker build -t us-central1-docker.pkg.dev/$_PROJECT_ID/ods-build-repo/ods-test:latest -f ./Dockerfile . && docker image inspect us-central1-docker.pkg.dev/$_PROJECT_ID/ods-build-repo/ods-test:latest --format \ '{{index .RepoTags 0}}@{{.Id}}' > /workspace/image-digest.txt && cat image-digest.txt - id: scan name: gcr.io/google.com/cloudsdktool/cloud-sdk entrypoint: /bin/bash args: - -c - | gcloud artifacts docker images scan us-central1-docker.pkg.dev/$_PROJECT_ID/ods-build-repo/ods-test:latest \ --format='value(response.scan)' > /workspace/scan_id.txt - id: severity check name: gcr.io/google.com/cloudsdktool/cloud-sdk entrypoint: /bin/bash args: - -c - | gcloud artifacts docker images list-vulnerabilities $(cat /workspace/scan_id.txt) \ --format='value(vulnerability.effectiveSeverity)' | if grep -Exq $_SEVERITY; \ then echo 'Failed vulnerability check' && exit 1; else exit 0; fi - id: push name: gcr.io/cloud-builders/docker entrypoint: /bin/bash args: - -c - | docker push us-central1-docker.pkg.dev/$_PROJECT_ID/ods-build-repo/ods-test:latest images: ['us-central1-docker.pkg.dev/$_PROJECT_ID/ods-build-repo/ods-test:latest']
This file includes the location and repository previously created in Artifact Registry. If you decide to use different values, modify the
cloudbuild.yaml
file accordingly. The values forPROJECT_ID
andSEVERITY
are passed to the script in the build command.Specify the vulnerability
SEVERITY
levels you want to block and start your build.You can use the following values for
SEVERITY
:CRITICAL
HIGH
MEDIUM
LOW
You can specify multiple severities by using a regular expression.
In the following example, you specify both the
CRITICAL
andHIGH
severity values. This instructs Cloud Build to check for vulnerabilities that are classified at or above theHIGH
severity level.gcloud builds submit --substitutions=_PROJECT_ID=PROJECT_ID,_SEVERITY='"CRITICAL|HIGH"' \ --config cloudbuild.yaml
Where
- PROJECT_ID is your project ID.
- SEVERITY allows you to set the severity levels that you want to block. If On-Demand Scanning finds vulnerabilities that match any of the specified severity levels, your build fails.
Understand your results
When you set your SEVERITY
value to CRITICAL|HIGH
, after On-Demand Scanning scans for vulnerabilities, it will see if there are any at the HIGH
level and the more severe CRITICAL
level. If no matching vulnerabilities are found in your image, your build succeeds and Cloud Build pushes your image to Artifact Registry.
The output is similar to the following:
DONE
--------------------------------------------------------------------------------------------------------------------------------------------
ID CREATE_TIME DURATION SOURCE IMAGES STATUS
abb3ce73-6ae8-41d1-9080-7d74a7ecd7bc 2021-03-15T06:50:32+00:00 1M48S gs://ods-tests_cloudbuild/source/1615791031.906807-a648d10faf4a46d695c163186a6208d5.tgz us-central1-docker.pkg.dev/ods-tests/ods-build-repo/ods-test (+1 more) SUCCESS
If On-Demand Scanning finds HIGH
or CRITICAL
vulnerabilities in your image, then the scan
build step fails, subsequent build steps do not start, and Cloud Build does not push an image to Artifact Registry.
The output is similar to the following:
Step #2 - "severity check": Failed vulnerability check
Finished Step #2 - "severity check"
ERROR
ERROR: build step 2 "gcr.io/cloud-builders/gcloud" failed: step exited with non-zero status: 1
In this tutorial, your results may vary, because the sample source code is a publicly available Linux distribution, debian10:latest
. Linux distributions and related vulnerability data receive updates on an ongoing basis.
To learn about additional Google Cloud tools and best practices to help protect your software supply chain, see Software supply chain security.
For more information on Linux vulnerability management best practices, you can use free online training provided by the Linux Foundation. See Developing Secure Software.