Getting Started with Notary
Tags: cloudnative, security, docker, devops
Published: 2022-09-23 18:04:25

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**

- [Docker](https://www.docker.com/products/docker-desktop/)

## Setup the local container registry

Before you can begin, you'll need a container registry to push and pull images to and from. 

[Distribution](https://github.com/oras-project/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:

```bash
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:

```bash
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](https://github.com/notaryproject/notation) is the command line tool that does the heavy lifting. Run the following commands to install Notation.

Download the release files.

```bash
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

```bash
[ -d ~/bin ] || mkdir ~/bin
tar xvzf notation.tar.gz -C ~/bin notation
```

Add `~/bin` to the PATH variable

```bash
export PATH="$HOME/bin:$PATH"
```

Notation is likely to be made available with normal package managers after it's [RC release](https://github.com/orgs/notaryproject/projects/10/views/7).

## 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:

```bash
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:

```bash
notation sign --plain-http localhost:5000/net-monitor:v1 
```

To list all the signatures for the image, use the `notation list` command.

```bash
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:

```bash
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:

```bash
notation verify --plain-http localhost:5000/net-monitor:v1 
```

## Next steps

To learn more about the Notary, check out the [Notary Project](https://github.com/notaryproject) on GitHub.