In this tutorial, you'll learn how to sign a Docker image using Notary.
Notary is a CNCF project that allows anyone to have trust over arbitrary collections of data. By using a pair of private and public keys Notary can sign and verify digital artifacts stored in OCI (Open Container Initiative) compliant registries such as container images, a software bill of materials, or scan results. Once signed those artifacts can be promoted across different OCI registries without losing trust in the integrity of the artifact.
Using Notary reduces your chances of introducing compromised artifacts into your environments.
Prerequisites
Setup the local container registry
Before you can begin, you'll need a container registry to push and pull images to and from.
Distribution is an Open-Source registry that supports storing container images using the OCI distribution specification. It provides a simple, secure, and scalable private registry perfect for demonstrating Notary.
Run the following command to start a local instance of a Distribution:
docker run -d -p 5000:5000 ghcr.io/oras-project/registry:v0.0.3-alpha
Build and push a container image
Once you have the Distribution registry up and running, your next step is to build and then push an image to it.
Run the following commands to build and push an image to the registry:
docker build -t localhost:5000/net-monitor:v1 https://github.com/wabbit-networks/net-monitor.git#main
NOTE: You can use any Docker image, but if you don't have one in mind feel free to use the
wabbit-networks/net-monitor
image.
Install Notation
Notary is the CNCF project name and is often referenced when referring to the process of signing digital artifacts, but Notation is the command line tool that does the heavy lifting. Run the following commands to install Notation.
Download the release files.
curl -Lo notation.tar.gz https://github.com/notaryproject/notation/releases/download/v0.10.0-alpha.3/notation_0.10.0-alpha.3_linux_amd64.tar.gz
Extract the binary
[ -d ~/bin ] || mkdir ~/bin
tar xvzf notation.tar.gz -C ~/bin notation
Add ~/bin
to the PATH variable
export PATH="$HOME/bin:$PATH"
Notation is likely to be made available with normal package managers after it's RC release.
Generate a certificate
Without a certificate Notation doesn't have a way to create new signatures or verify existing ones. And while Notation supports adding existing certificates, it also has a helper command that will generate a new local certificate for you.
Run the following command to generate a new local certificate:
notation cert generate-test --default "wabbit-networks.io"
Using the notation cert genereate-test
command automatically adds the key to the certificate to Notation to use for signing, but not the public key of the certificate.
Sign a container image
Now that you have a container image and a certificate to sign with, all that's left is to sign the container image stored on the registry.
Run the following command to sing the image:
notation sign --plain-http localhost:5000/net-monitor:v1
To list all the signatures for the image, use the notation list
command.
notation list --plain-http localhost:5000/net-monitor:v1
NOTE:
--plain-http
is used to access the registry with plain HTTP, by passing the need to provide a username and password or other authentication.
Verify the signature
The notation verify
command, as the name implies, verifies OCI artifacts by using the public key of the certificate to ensure the artifact hasn't been modified.
Before you can run the verify command, you'll need to add the public key of the certificate to your Notation configuration.
Run the following command to add the public key:
notation cert add --name "wabbit-networks.io" ~/.config/notation/localkeys/wabbit-networks.io.crt
By default, the notation cert genereate-test
command stores the certificates under ~/.config/notation/localkeys
.
Next, run the following commands to verify your container image:
notation verify --plain-http localhost:5000/net-monitor:v1
Next steps
To learn more about the Notary, check out the Notary Project on GitHub.