scout: refresh gha ci example

Fix incorrections, restructure, and call out policy evaluation

Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
This commit is contained in:
David Karlsson 2023-11-03 14:59:35 +01:00
parent e44791333e
commit 7bb69cd866
4 changed files with 84 additions and 63 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

View File

@ -4,21 +4,32 @@ keywords: supply chain, security, ci, continuous integration, github actions
title: Integrate Docker Scout with GitHub Actions
---
You can use [the Docker Scout GitHub action](https://github.com/docker/scout-action) to run Docker Scout CLI commands
as part of a workflow.
The following example shows how to set up a Docker Scout workflow with GitHub
Actions. Triggered by a pull request, the action builds the image and uses
Docker Scout to compare the new version to the version of that image running in
production.
The following example works in a repository containing a Docker image's
definition and contents. Triggered by a pull request, the action builds the
image and uses Docker Scout to compare the new version to the current published
version.
This workflow uses the
[docker/scout-action](https://github.com/docker/scout-action) GitHub Action to
run the `docker scout compare` command to visualize how images for pull request
stack up against the image you run in production.
First, set up the rest of the workflow. There's a lot that's not specific to
Docker Scout but needed to create the images to compare. For more details on
those actions and using GitHub Actions with Docker in general, see [the GitHub Actions documentation](../../../build/ci/github-actions/index.md).
## Prerequisites
- This example assumes that you have an existing image repository, in Docker Hub
or in another registry, where you've enabled Docker Scout.
- This example makes use of [environments](../environment/_index.md), to compare
the image built in the pull request with a different version of the same image
in an environment called `production`.
## Steps
First, set up the GitHub Action workflow to build an image. This isn't specific
to Docker Scout here, but you'll need to create build an image to have
something to compare with.
Add the following to a GitHub Actions YAML file:
```yaml
name: Docker
@ -31,8 +42,9 @@ on:
branches: ["**"]
env:
# Use docker.io for Docker Hub if empty
# Hostname of your registry
REGISTRY: docker.io
# Image repository, without hostname and tag
IMAGE_NAME: ${{ github.repository }}
SHA: ${{ github.event.pull_request.head.sha || github.event.after }}
@ -40,20 +52,8 @@ jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
```
pull_request: write
This sets up the workflow to run on pull requests and pushes to the `main`
branch, and sets up environment variables available to all workflow steps. It
then defines a job called `build` that runs on the latest Ubuntu image and sets
the permissions available to the job.
Add the following to the YAML file:
```yaml
steps:
- name: Checkout repository
uses: actions/checkout@v4
@ -63,17 +63,15 @@ steps:
- name: Setup Docker buildx
uses: docker/setup-buildx-action@v3
# Login against a Docker registry except on PR
# https://github.com/docker/login-action
- name: Log into registry ${{ env.REGISTRY }}
# Authenticate to the container registry
- name: Authenticate to registry ${{ env.REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PAT }}
username: ${{ secrets.REGISTRY_USER }}
password: ${{ secrets.REGISTRY_TOKEN }}
# Extract metadata (tags, labels) for Docker
# https://github.com/docker/metadata-action
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v5
@ -85,40 +83,56 @@ steps:
type=edge,branch=$repo.default_branch
type=semver,pattern=v{{version}}
type=sha,prefix=,suffix=,format=short
# Build and push Docker image with Buildx
# (don't push on PR, load instead)
- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@v5
with:
context: .
sbom: ${{ github.event_name != 'pull_request' }}
provenance: ${{ github.event_name != 'pull_request' }}
push: ${{ github.event_name != 'pull_request' }}
load: ${{ github.event_name == 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
```
This creates workflow steps to:
This creates workflow steps to checkout the repository, set up Docker buildx,
log into the Docker registry, and extract metadata from Git reference and GitHub
events to use in later steps.
1. Check out the repository
2. Set up Docker buildx
3. Authenticate to the registry
4. Extract metadata from Git reference and GitHub events.
5. Build and push the Docker image to the registry.
Add the following to the YAML file:
> **Note**
>
> This CI workflow runs a local analysis and evaluation of your image. To
> evaluate the image locally, you must ensure that the image is loaded the
> local image store of your runner.
>
> This comparison doesn't work if you push the image to a registry, or if you
> build an image that can't be loaded to the runner's local image store. For
> example, multi-platform images or images with SBOM or provenance attestation
> can't be loaded to the local image store.
With this setup out of the way, you can add the following steps to run the
image comparison:
```yaml
# Build and push Docker image with Buildx (don't push on PR)
# https://github.com/docker/build-push-action
- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@v5
# You can skip this step if Docker Hub is your registry
# and you already authenticated before
- name: Authenticate to Docker
uses: docker/login-action@v3
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
```
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PAT }}
This uses the extracted metadata from the previous step to build and push the
Docker image to Docker Hub. GitHub Actions skips this step on pull requests and
only runs when a pull request is merged.
Add the following to the YAML file:
```yaml
# Compare the image built in the pull request with the one in production
- name: Docker Scout
id: docker-scout
if: ${{ github.event_name == 'pull_request' }}
@ -126,19 +140,26 @@ Add the following to the YAML file:
with:
command: compare
image: ${{ steps.meta.outputs.tags }}
to: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:edge
to-env: production
ignore-unchanged: true
only-severities: critical,high
token: ${{ secrets.DOCKER_PAT }}
```
The compare command analyzes the image and evaluates policy compliance, and
cross-references the results with the corresponding image in the `production`
environment. This example only includes critical and high-severity
vulnerabilities, and excludes vulnerabilities that exist in both images,
showing only what's changed.
This final step uses the Docker Scout CLI to run [the `compare` command](../../../engine/reference/commandline/scout_compare.md), comparing the new
image to the published one. It only shows critical or high-severity
vulnerabilities and ignores vulnerabilities that haven't changed since the last
analysis.
The GitHub Action outputs the comparison results in a pull request comment by
default.
The GitHub Action outputs the comparison results as a table and a summary in the
action output.
![A screenshot showing the results of Docker Scout output in a GitHub Action](../../images/gha-output.webp)
![A screenshot showing the results of Docker Scout output in a GitHub Action](../../images/gha-output.png)
Expand the **Policies** section to view the difference in policy compliance
between the two images. Note that while the new image in this example isn't
fully compliant, the output shows that the standing for the new image has
improved compared to the baseline.
![GHA policy evaluation output](../../images/gha-policy-eval.webp)