What is Notary

Notary is a tool for publishing and managing trusted collections of content. Publishers can digitally sign collections and consumers can verify integrity and origin of content. This ability is built on a straightforward key management and signing interface to create signed collections and configure trusted publishers.

With Notary anyone can provide trust over arbitrary collections of data. Using The Update Framework (TUF) as the underlying security framework, Notary takes care of the operations necessary to create, manage, and distribute the metadata necessary to ensure the integrity and freshness of your content.

Install Notary

You can download precompiled notary binary for 64 bit Linux or macOS from the Notary repository’s releases page on GitHub. Windows is not officially supported, but if you are a developer and Windows user, we would appreciate any insight you can provide regarding issues.

Understand Notary naming

Notary uses Globally Unique Names (GUNs) to identify trust collections. To enable Notary to run in a multi-tenant fashion, you must use this format when interacting with Docker Hub through the Notary client. When specifying Docker image names for the Notary client, the GUN format is:

For official images (identifiable by the “Official Repository” moniker), the image name as displayed on Docker Hub, prefixed with docker.io/library/. For example, if you would normally type docker pull ubuntu you must enter notary {cmd} docker.io/library/ubuntu.

For all other images, the image name as displayed on Docker Hub, prefixed by docker.io.

The Docker Engine client takes care of these name expansions for you so do not change the names you use with the Engine client or API. This is a requirement only when interacting with the same Docker Hub repositories through the Notary client.

Inspect a Docker Hub repository

The most basic operation is listing the available signed tags in a repository. The Notary client used in isolation does not know where the trust repositories are located. So, you must provide the -s (or long form --server) flag to tell the client which repository server it should communicate with.

The official Docker Hub Notary servers are located at https://notary.docker.io. If you would like to use your own Notary server, it is important to use the same or a newer Notary version as the client for feature compatibility (ex: client version 0.2, server/signer version >= 0.2). Additionally, Notary stores your own signing keys, and a cache of previously downloaded trust metadata in a directory, provided with the -d flag. When interacting with Docker Hub repositories, you must instruct the client to use the associated trust directory, which by default is found at .docker/trust within the calling user’s home directory (failing to use this directory may result in errors when publishing updates to your trust data):

The output shows us the names of the tags available, the hex encoded sha256 digest of the image manifest associated with that tag, the size of the manifest, and the Notary role that signed this tag into the repository. The “targets” role is the most common role in a simple repository. When a repository has (or expects) to have collaborators, you may see other “delegated” roles listed as signers, based on the choice of the administrator as to how they organize their collaborators.

When you run a docker pull command, Docker Engine is using an integrated Notary library (the same one as Notary CLI) to request the mapping of tag to sha256 digest for the one tag you are interested in (or if you passed the --all flag, the client will use the list operation to efficiently retrieve all the mappings). Having validated the signatures on the trust data, the client will then instruct the Engine to do a “pull by digest”. During this pull, the Engine uses the sha256 checksum as a content address to request and validate the image manifest from the Docker registry.

Delete a tag

Notary generates and stores signing keys on the host it’s running on. This means that the Docker Hub cannot delete tags from the trust data, they must be deleted using the Notary client. You can do this with the notary remove command. Again, you must direct it to speak to the correct Notary server (N.B. neither you nor the author has permissions to delete tags from the official alpine repository, the output below is for demonstration only):

In the preceding example, the output message indicates that only the removal was staged. When performing any write operations they are staged into a change list. This list is applied to the latest version of the trust repository the next time a notary publish is run for that repository.

You can see a pending change by running notary status for the modified repository. The status subcommand is an offline operation and as such, does not require the -s flag, however it will silently ignore the flag if provided. Failing to provide the correct value for the -d flag may show the wrong (probably empty) change list:

Configure the client

It is verbose and tedious to always have to provide the -s and -d flags manually to most commands. A simple way to create preconfigured versions of the Notary command is via aliases. Add the following to your .bashrc or equivalent: