Pushing the image

Now that a root key is available, it’s time to initialize the repository on the first push.

Consider this as your app:

  1. FROM alpine
  2. RUN true

Make sure you have all trusted metadata using the official Notary server when building the image by temporarily redefining the content trust server:

  1. DOCKER_CONTENT_TRUST_SERVER=https://notary.docker.io docker build -t <aws_account_id>.dkr.ecr.us-east-1.amazonaws.com/app:1.0.0 .

Then push it upstream, forcing Docker to initialize the signed repository:

  1. docker push <aws_account_id>.dkr.ecr.us-east-1.amazonaws.com/app:1.0.0
  2. The push refers to a repository [<aws_account_id>.dkr.ecr.us-east-1.amazonaws.com/app]
  3. 011b303988d2: Pushed
  4. 1.0.0: digest: sha256:475d897467451caf22f22ad9fd2856a5dd4a876b9eb2daab4d474185f4244e8d size: 2101
  5. Signing and pushing trust metadata
  6. Enter the User Pin for the attached Yubikey:
  7. Please touch the attached Yubikey to perform signing.
  8. Enter passphrase for new repository key with ID 9c738a6 (<aws_account_id>.dkr.ecr.us-east-1.amazonaws.com/app):
  9. Repeat passphrase for new repository key with ID 9c738a6 (<aws_account_id>.dkr.ecr.us-east-1.amazonaws.com/app):
  10. Enter the User Pin for the attached Yubikey:
  11. Please touch the attached Yubikey to perform signing.
  12. Finished initializing "<aws_account_id>.dkr.ecr.us-east-1.amazonaws.com/app"
  13. Successfully signed "<aws_account_id>.dkr.ecr.us-east-1.amazonaws.com/app":1.0.0

The repository key passphrase should be generated and stored by a password manager. This will be a personal key, i.e., not intended to be shared. It will be stored, in its encrypted form, under ~/.docker/trust. The repository key is will be generated with the targets role.

  1. notary -d ~/.docker/trust key list

Now edit the file and generate a new build:

  1. FROM alpine
  2. RUN true
  3. RUN uname

Build it:

  1. docker build -t <aws_account_id>.dkr.ecr.us-east-1.amazonaws.com/app:1.0.1 .

And push it:

  1. docker push <aws_account_id>.dkr.ecr.us-east-1.amazonaws.com/app:1.0.1
  2. The push refers to a repository [<aws_account_id>.dkr.ecr.us-east-1.amazonaws.com/app]
  3. 011b303988d2: Layer already exists
  4. 1.0.1: digest: sha256:afc214501f950ca11246ceb62fb5c07dd5856f359d6122a620e2c60071a484bc size: 2531
  5. Signing and pushing trust metadata
  6. Enter passphrase for repository key with ID 9c738a6 (<aws_account_id>.dkr.ecr.us-east-1.amazonaws.com/app):
  7. Successfully signed "<aws_account_id>.dkr.ecr.us-east-1.amazonaws.com/app":1.0.1

On the second push, only the passphrase of the repository key was required.

That’s it. Signed builds using an offline root key (Yubikey) and one online repository key.