Automated Image Signing Workflow for Docker Trusted Registry (DTR)

Just in case you are using a Docker trusted registry ( any image registry that supports docker content trust ) to establish a secure supply chain of docker images to your swarm or kubernetes cluster , this post may be of some help , because when we were doing this , we could not find a ready made recipe to automate the docker image signing process. There were lot and lot of documentation pages to read and those were just adding to the confusion how all of the process work and how to automate it.

Docker image singing is part of the docker content trust , and may be needed for a couple reasons , such as allowing only signed images to be run on the cluster , making sure that the image belong to a trusted source , and using it a way to restrict the docker registry to be used is that of your docker trusted registry instead of allowing images from public registries on the public internet.

Ok , you found that docker image signing is awesome , But you would not like to manually sign every image that you produce , or your CI build produces. Your build pipeline maybe producing hundreds of images a day and its not practical to sign each of those images manually.

There are many ways of signing images , and the image signing make use of notary client , not easy to use. Luckily you will find that docker has made it easy for you if you just use the docker trust command, but before using docker trust command you will need to setup the docker image repository trust meta data. This only needs to be done once per project/repo.

So , your image build pipeline will be using some docker client running on either a Jenkins node , or a Gitlab CI runner , or any such other CI/CD tool. You just need to configure that client once per project/repo , for using docker content trust ( DCT) , then you can use it in your build pipeline for pushing signed images to that repo forever.

Client Setup ( One time setup per project , this client cloud be a gitlab runner or Jenkins node or any node running your image build )

#### note that the actual values of secrets such as passwords and keys used, can come from the secret variables of you CI environment such as Gitlab , or Jenkins etc

export DTR=registry.example.com
export USER=<YOUR_USERNAME>
export PROJECT=$USER/<PROJECT_REPO_NAME>
export DTR_TOKEN=$YOUR_DTR_TOKEN
export DOCKER_CONTENT_TRUST_ROOT_PASSPHRASE=$SECRE_PASS_01
export DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE=$SECRET_PASS_02
docker login -u $USER -p $DTR_TOKEN $DTR
## key.pem and cert.pub comes from your docker UCP client cert bundle under your ucp profile

docker trust key load key.pem --name $USER
docker trust signer add --key cert.pub $USER $DTR/$PROJECT

Once the client is setup , then you just keep running your builds on that client, and use docker push command that will auto sign and push your image to DTR.

export CONTAINER_IMAGE=$DTR/$PROJECT

docker pull $CONTAINER_IMAGE:latest || true
docker build --cache-from $CONTAINER_IMAGE:latest --tag $CONTAINER_IMAGE:latest .

export DOCKER_CONTENT_TRUST_ROOT_PASSPHRASE=$SECRE_PASS_01
export DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE=$SECRET_PASS_02
export DOCKER_CONTENT_TRUST=1
docker push $CONTAINER_IMAGE:latest
docker logout $DTR

Once you are done with setting this up for first project , then you can just repeat these two lines for each of your new project , and auto signing will work. ( you can just use the same secrets and keys as trust metadata for all of your projects )

docker trust key load key.pem --name $USER
docker trust signer add --key cert.pub $USER $DTR/$PROJECT

Questions and Issues ? Please ask in the comments.

Leave a comment

Your email address will not be published. Required fields are marked *