Docker content trust: how it works

Docket content trust is a security mechanism that allows only images with a specific sign to run to our docker environment. This ensures…

Docket content trust is a security mechanism that allows only images with a specific sign to run to our docker environment. This ensures that we run secure images.

How to setup Docker content trust

We need first to login to our docker repository using the docker login command$ docker login

After a successful login we need to generate the certificate for our docker repository user, which in my case is ‘kpat’. Creating the certificate requires to generate a passphrase as well, don’t forget the passphrase, write it dwn.$ docker trust key generate kpat
Generating key for kpat...
Enter passphrase for new kpat key with ID 9b8c60e:
Repeat passphrase for new kpat key with ID 9b8c60e:
Successfully generated and loaded private key. Corresponding public key available: /home/kpatronas/kpat.pub

Now we need to add our user as a trusted user to a repository, we create a private repo called trust-test.

Also you will need to enter passphrases for the root key and the repository , write down those passphrases.$ docker trust signer add --key kpat.pub kpat kpat/trust-test
Adding signer "kpat" to kpat/trust-test...
Initializing signed repository for kpat/trust-test...
You are about to create a new root signing key passphrase. This passphrase
will be used to protect the most sensitive key in your signing system. Please
choose a long, complex passphrase and be careful to keep the password and the
key file itself secure and backed up. It is highly recommended that you use a
password manager to generate the passphrase and keep it safe. There will be no
way to recover this key. You can find the key in your config directory.
Enter passphrase for new root key with ID b356e13:
Repeat passphrase for new root key with ID b356e13:
Enter passphrase for new repository key with ID 5dbfbdd:
Repeat passphrase for new repository key with ID 5dbfbdd:
Successfully initialized "kpat/trust-test"
Successfully added signer: kpat to kpat/trust-test

Lets try Docker content trust

We will create a non signed image and we will try to run it, but first we need to ensure content trust on our docker host is off, to do this run the following$ export DOCKER_CONTENT_TRUST=0

Create the following DockerfileFROM busybox:latest
CMD echo Hello Docker

Build it, the “unsigned” tag doesn't matter is just for us to make sense.$ docker build -t kpat/trust-test:unsigned .
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM busybox:latest
---> b97242f89c8a
Step 2/2 : CMD echo Hello Docker
---> Running in 832d8ec39b11
Removing intermediate container 832d8ec39b11
---> 01b3a779cac7
Successfully built 01b3a779cac7
Successfully tagged kpat/trust-test:unsigned

And now push the image to the repository$ docker push kpat/trust-test:unsigned
The push refers to repository [docker.io/kpat/trust-test]
0064d0478d00: Mounted from library/busybox
unsigned: digest: sha256:67f002c61d287b407f1a4a4c605b23b4b5a23fdd078b8545f57d61e6c1410a73 size: 527

And finally run it$ docker run kpat/trust-test:unsigned
Hello Docker

Lets now turn on the content trust feature and re-run the command.$ export DOCKER_CONTENT_TRUST=1
$ docker run kpat/trust-test:unsigned
docker: No valid trust data for unsigned.
See 'docker run --help'.

Docker exits with this error message, this is because the image is not signed.

Lets create a signed image, we will use the same Dockerfile and we will do a slight modification to the tag, now will be called “signed”$ docker build -t kpat/trust-test:signed .
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM busybox@sha256:bde48e1751173b709090c2539fdf12d6ba64e88ec7a4301591227ce925f3c678
docker.io/library/busybox@sha256:bde48e1751173b709090c2539fdf12d6ba64e88ec7a4301591227ce925f3c678: Pulling from library/busybox
ea97eb0eb3ec: Pull complete
Digest: sha256:bde48e1751173b709090c2539fdf12d6ba64e88ec7a4301591227ce925f3c678
Status: Downloaded newer image for busybox@sha256:bde48e1751173b709090c2539fdf12d6ba64e88ec7a4301591227ce925f3c678
---> 219ee5171f80
Step 2/2 : CMD echo works
---> Running in 66115f778e33
Removing intermediate container 66115f778e33
---> 2df2f7d05777
Successfully built 2df2f7d05777
Successfully tagged kpat/trust-test:signed
Tagging busybox@sha256:bde48e1751173b709090c2539fdf12d6ba64e88ec7a4301591227ce925f3c678 as busybox:latest

And now we will sign the new image, note that signing an image also push it to the repository.$ docker trust sign kpat/trust-test:signed
Signing and pushing trust data for local image kpat/trust-test:signed, may overwrite remote trust data
The push refers to repository [docker.io/kpat/trust-test]
de168d3b8ec4: Mounted from library/busybox
signed: digest: sha256:be096c167e01a6bc8284caca6f32ce5a6e729f59f5eb2c076d7494b7e4d92654 size: 527
Signing and pushing trust metadata
Enter passphrase for kpat key with ID 9b8c60e:
Successfully signed docker.io/kpat/trust-test:signed

Lets try now to run the signed image$ docker run kpat/trust-test:signed
Hello Docker

We can see it works, to revert the change and allow not signed images to run enter$ export DOCKER_CONTENT_TRUST=0

I hope you found the article interesting :)

Join Medium with my referral link - Konstantinos Patronas
As a Medium member, a portion of your membership fee goes to writers you read, and you get full access to every story…