This API and webapp add the capability to manage your Docker Content Trust and notary certificates.
It allows you to create new Target certificates for your Docker repositories, as well authorizing delegates for the repository.
This way the certificates can be stored in a secured environment where backups are managed.
This project makes use of a Notary sandbox which is an in progress development setup, which is intended to be contributed upstream. The Fork is by no means a hard Fork of Notary and is solely there to bridge a period of time to get this back in the upstream.
HTTP Method | URL | description |
---|---|---|
GET | https://localhost:8443/ping | return pong |
GET | https://localhost:8443/targets | retrieves all target keys |
POST | https://localhost:8443/targets | creates a new target and keys |
GET | https://localhost:8443/targets/{id} | retrieves a single target key |
GET | https://localhost:8443/targets/{id}/delegations | retrieves all delegate keys for a given target |
POST | https://localhost:8443/targets/{id}/delegations | add a new delegation to the given target |
DELETE | https://localhost:8443/targets/{id}/delegations/{delegation} | remove a delegation from the given target |
For a easier development workflow it is recommended to install CMake. To interact with Hashicorp Vault the vault cli
is convenient.
platform | install | url |
---|---|---|
Windows | choco install -y cmake |
cmake-3.16.2-win64-x64.msi |
MacOSX | brew install cmake |
cmake-3.16.2-Darwin-x86_64.dmg |
Windows | choco install -y vault |
vault_1.4.2_windows_amd64.zip |
MacOSX | brew install vault |
vault_1.4.2_darwin_amd64.zip |
For Google Chrome to accept the selfsigned certificates please enable the option allow-insecure-localhost
by navigating to in your address bar.
To only allow for the current certificate that is blocked type thisisunsafe
with focus on the Your connection is not private
page, the page will autorefresh once the full phrase is typed. In older versions of chrome you had to type badidea
or danger
.
To run in an isolated environment to do some testing you should run the sandbox. The sandbox connects to a notary server and registry in the docker-compose setup.
Initializing the notary git submodule.
git submodule update --init --recursive
Build the sandbox
make build-sandbox
Run the sandbox
make run-sandbox
To provision the notary sandbox with some signed images you can use the bootstrap-sandbox
make target (optional).
make bootstrap-sandbox
To play with the notary and docker trust cli you can open the shell for the sandbox. Signing docker images using docker content trust
docker-compose -f notary/docker-compose.sandbox.yml -f docker-compose.yml exec sandbox sh
To shutdown the sandbox you can run the stop-sandbox
make target.
make stop-sandbox
To boot the Hashicorp Vault development server run the following. Requires vault installed, (e.g. brew install vault
).
docker-compose -f vault/docker-compose.dev.yml up -d
vault/prepare.sh dev
prepare.sh
boots vault server and provisions the secret engine with required policies, secret engines etc.
The vault admin dashboard is available at http://localhost:8200.
The token can be found in the server logs.
docker-compose -f vault/docker-compose.dev.yml logs | grep "Root Token"
make build
To run the tests, make sure to run make stop-sandbox
first (tests are also reusing the same sandbox which require a clean env).
make test
Run the tests with coverage.
make coverage-out
Check the coverage report in your browser.
make coverage-html
The API utilizes Hashicorp vault to generate and store passwords for private keys. The endpoint to Hashicorp vault can be configured via the environment variable
VAULT_ADDR
or as a commandline flag. The default value points to http://localhost:8200 (the address of the development server).
Now you can start the API server as following:
# environment variable
export VAULT_ADDR=http://localhost:8200
bin/dctna-server --config .notary/config.json
Alternatively you provide the vault server address as parameter.
# commandline option
bin/dctna-server --vault-addr http://localhost:8200 --config .notary/config.json
NOTE: you can pass the sandbox
.notary/config.json
as above, without this setting the default notary folder will be used ($USER/.natary/config.json
).
Or via the Make shorthand which also builds the solution, which will use the sandbox config for notary.
make run
NOTE: via make we will also use our sandboxed
.notary/config.json
automatically to prevent you from messing arround with your current notary (Production) settings.
cd web
yarn install && yarn start
Now you can create new targets for signing docker images http://localhost:3000 using the webinterface.
E.g.:
- Target:
localhost:5000/nginx
- Target:
localhost:5000/stuff
Then on one of the targets we will authorize our personal delegation key. If you don't have one yet you can generate it via the docker trust cli.
docker trust key generate johndoe --dir ~/.docker/trust
Then simply copy the contents of the public key to your clipboard.
cat ~/.docker/trust/johndoe.pub | pbcopy
In the webinterface you can now add your delegation on the target localhost:5000/nginx
.
name | key |
---|---|
john_doe | paste_clipboard_contents |
Now to be able to sign an image all signing keys have to be available on your local system. In Notary v2 this will be improved to also be able to work with remote signing keys. You will only need the passphrase for your delegation key.
This will now allow us to sign docker images for localhost:5000/nginx
. In below example we first pull an image from the public registry. Then tag it to push to our sandbox registry. Then we enable content trust and configure our sandbox notary endpoint. Upon pushing to the repository you will be prompted for the password of your signing delegation key. Please note if you haven't added your delegation key in dctna, you will not be able to sign.
docker pull nginx:alpine
docker tag nginx:alpine localhost:5000/nginx:alpine
export DOCKER_CONTENT_TRUST=1 DOCKER_CONTENT_TRUST_SERVER=https://localhost:4443
docker push localhost:5000/nginx:alpine