3

I am new to the mechanism of Docker Content Trust (DCT) and a bit confused about the root key. The first time I add a signer to a new repository I am asked to enter passphrases for the root and repository key. After that a key file with the root key ID is generated in the directory ~/.docker/trust/private. So far so good, but when I execute docker trust inspect <repo name>, I get a different root key ID under the administrative keys section.

Can you please explain this to me?

Andrzej Sydor
  • 1,373
  • 4
  • 13
  • 28
Joe
  • 287
  • 3
  • 13
  • @Andrzej Sydor Even I am observing the same...Is this a valid scenario? Can you help us to understand if you would have got the knowledge already..thanks in advance – Monish Guru Jul 08 '21 at 12:04

3 Answers3

0

There are several keys:

  • Signer key
  • Repository key
  • Root key

You can open files in ~/.docker/trust/private to see the role of each key. Or you can run notary -d ~/.docker/trust key list

Pretty option is also cool for this: docker trust inspect --pretty <repo_name> to get the following result

Signatures for repo_name

SIGNED TAG   DIGEST                                                             SIGNERS
latest       def822f9851ca422481ec6fee59a9966f12b351c62ccb9aca841526ffaa9f748   test

List of signers and their keys for repo_name

SIGNER    KEYS
test       c990796d79a9

Administrative keys for repo_name

  Repository Key:   06362021113fed73dc5e08e6b5edbe04cf4316193b362b0d8335fab3285fc98b
  Root Key: 317f83b55c99e2b8f9d341a3c9a3fc4b1d65d97f52a553020a65cdee85940cf3
dmyz
  • 1
0

TLDR; : One root key is for the signer and another one is for the repository.

When I try to load a key to add the signer, it will ask me a passphrase to encrypt the private key (root).

$ docker trust key load --name arif key.pem
Loading key from "key.pem"...
Enter passphrase for new arif key with ID 2817c38: 
Repeat passphrase for new arif key with ID 2817c38: 
Successfully imported key from key.pem

You can find the encrypted root key in the .docker/trust/private like the following,

$ cat ../.docker/trust/private/2817c387b869ede57bd209e40a3dfce967b70eca1eb3739bc58afba44665aaef.key 
-----BEGIN ENCRYPTED PRIVATE KEY-----
role: arif

MIHuMEkGCSqGSIb3DQEFDTA8MBsGCSqGSIb3DQEFDDAOBAh/6HbWl/T/SAICCAAw
HQYJYIZIAWUDBAEqBBAZpJBc+C9ABYY6UbMT3YSRBIGgiNT5fX9QqCOrGJ3lb3qw
7JkC/4D0dtp75MYWaMbfYXvNm+muJXmVUpp5vh91onUW8Y8q+ymQTgDq3mN8+HLu
4iRp46wXxilEKUxmXsYln/mxQI+jU7UwTTiLiy6LpR1vpBKdO8hhd/WObW25P+ah
YjslB1P8fe9VeSsorAKM5zDnuaiVhHh7BjgVAiepDvmy/7zO3W7Rso4Kgg0UZkJn
SA==
-----END ENCRYPTED PRIVATE KEY-----

Then I am trying to add the signer in a repository and it will ask 2 things,

  1. New passphrase to encrypt root key for the repository I want to sign"
  2. New passphrase to encrypt **repository key ** for that exact repository.
$ docker trust signer add --key cert.pem arif ec2-3-67-179-58.eu-central-1.compute.amazonaws.com/docker/haproxy 
Adding signer "arif" to ec2-3-67-179-58.eu-central-1.compute.amazonaws.com/docker/haproxy...
Initializing signed repository for ec2-3-67-179-58.eu-central-1.compute.amazonaws.com/docker/haproxy...
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 06665b8: 
Repeat passphrase for new root key with ID 06665b8: 
Enter passphrase for new repository key with ID b040c66: 
Repeat passphrase for new repository key with ID b040c66: 
Successfully initialized "ec2-3-67-179-58.eu-central-1.compute.amazonaws.com/docker/haproxy"
Successfully added signer: arif to ec2-3-67-179-58.eu-central-1.compute.amazonaws.com/docker/haproxy

At the output above we can see the id for the two keys are 06665b8 and b040c66.

If I have look at my trust directory I will see two keys starting with these two ids. One for the root keys of the repository and another one for the target key.

$ grep role .docker/trust/private/06665b8*.key
role: root

$ grep role .docker/trust/private/b040c66*.key
role: targets

Now, if I inspect the repository I can see the following,

$ docker trust inspect ec2-3-67-179-58.eu-central-1.compute.amazonaws.com/docker/haproxy
[
    {
        "Name": "ec2-3-67-179-58.eu-central-1.compute.amazonaws.com/docker/haproxy",
        "SignedTags": [],
        "Signers": [
            {
                "Name": "arif",
                "Keys": [
                    {
                        "ID": "2817c387b869ede57bd209e40a3dfce967b70eca1eb3739bc58afba44665aaef"
                    }
                ]
            }
        ],
        "AdministrativeKeys": [
            {
                "Name": "Root",
                "Keys": [
                    {
                        "ID": "5ed03b461b330c6d722c319bdfaa87e3d8b289a1213569248bdaa616a1a399c6"
                    }
                ]
            },
            {
                "Name": "Repository",
                "Keys": [
                    {
                        "ID": "b040c663463612c99130eca98ec827ef32a3bab73d2976403888443ce87899c6"
                    }
                ]
            }
        ]
    }
]

So now, we have 3 keys. One is the signers root key, another one is the repository's root key and the last one is the target key.

$ ls .docker/trust/private/ -1 | wc -l
3

You can find all the metadata about these keys in the tuf directory,

$ cd .docker/trust/tuf/ec2-3-67-179-58.eu-central-1.compute.amazonaws.com/docker/haproxy/metadata/

$ ls 
root.json  snapshot.json  targets.json  timestamp.json

I hope it makes sense now.

arif
  • 579
  • 1
  • 7
  • 21
0

User-Signed images

There are two options for trust pinning user-signed images:

  • Notary Canonical Root Key ID (DCT Root Key) is an ID that describes just the root key used to sign a repository (or rather its respective keys). This is the root key on the host that originally signed the repository (i.e. your workstation). This can be retrieved from the workstation that signed the repository through $ grep -r "root" ~/.docker/trust/private/ (Assuming your trust data is at ~/.docker/trust/*). It is expected that this canonical ID has initiated multiple image repositories (mydtr/user1/image1 and mydtr/user1/image2).
# Retrieving Root ID
$ grep -r "root" ~/.docker/trust/private
/home/ubuntu/.docker/trust/private/0b6101527b2ac766702e4b40aa2391805b70e5031c04714c748f914e89014403.key:role: root

# Using a Canonical ID that has signed 2 repos (mydtr/user1/repo1 and mydtr/user1/repo2). Note you can use a Wildcard.

{
  "content-trust": {
    "trust-pinning": {
      "root-keys": {
         "mydtr/user1/*": [
           "0b6101527b2ac766702e4b40aa2391805b70e5031c04714c748f914e89014403"
         ]
      }
    },
    "mode": "enforced"
  }
}
  • Notary Root key ID (DCT Certificate ID) is an ID that describes the same, but the ID is unique per repository. For example, mydtr/user1/image1 and mydtr/usr1/image2 will have unique certificate IDs. A certificate ID can be retrieved through a $ docker trust inspect command and is labelled as a root-key (referring back to the Notary key name). This is designed for when different users are signing their own repositories, for example, when there is no central signing server. As a cert-id is more granular, it would take priority if a conflict occurs over a root ID.
# Retrieving Cert ID
$ docker trust inspect mydtr/user1/repo1 | jq -r '.[].AdministrativeKeys[] | select(.Name=="Root") | .Keys[].ID'
9430d6e31e3b3e240957a1b62bbc2d436aafa33726d0fcb50addbf7e2dfa2168

# Using Cert Ids, by specifying 2 repositories by their DCT root ID. Example for using this may be different DTRs or maybe because the repository was initiated on different hosts, therefore having different canonical IDs.

{
  "content-trust": {
    "trust-pinning": {
      "cert-ids": {
         "mydtr/user1/repo1": [
           "9430d6e31e3b3e240957a1b62bbc2d436aafa33726d0fcb50addbf7e2dfa2168"
         ],
         "mydtr/user2/repo1": [
           "544cf09f294860f9d5bc953ad80b386063357fd206b37b541bb2c54166f38d08"
         ]
      }
    },
    "mode": "enforced"
  }
}

http://www.myclass5.cn/engine/security/trust/content_trust/

Jian
  • 9
  • 1