Search code examples
dockersecuritynotarytuf

Docker Trust Initialization


When the initial trust on docker content trust with notary on tuf is initialized I understand how TUF, Notary and Content Trust works.

But what is not clear to me is, how the initial trust is setup.

How do I know, that the first pull is not a compromised one and the initial root.json is trustworthy?

So for example if I do docker pull with content-trust enabled, I will only get signed images. But how do I verify, that this image is signed by the right person?


Solution

  • Notary creator and maintainer here. Justin has already given a good account but I'll speak to trust initialization in TUF and Notary more broadly.

    Unless you communicate the root of trust through some out of band method, there will always be a point of download that you implicitly trust to deliver the root of trust. Some general case examples: we do this when we download an OS (i.e. any Linux distro), or grab somebody's GPG public key from a public key directory. Assuming the resources are delivered over a TLS connection and we believe that the publisher has secured their server, we trust we're receiving legitimate data, and use this to bootstrap trust on all future interactions. This is called Trust On First Use, or TOFU.

    The claim here is that people do keep their servers secure, and that it's difficult to perform a Man-in-the-middle (MiTM) attack, especially against a TLS secured connection. Therefore we can trust this initial download.

    Notary has a few ways one can initialize trust. The first is this TOFU mechanism. TUF has a defined update flow that ensures trust over all subsequent content after the initial download. Notary implements this update flow and ensures the publisher is consistent after the initial download.

    If you want to additionally ensure the publisher is a specific entity, Notary provides three different ways to bootstrap that trust. They are:

    1. Manually place the root.json, acquired out of band, in the correct location in the notary cache.
    2. Configure trust pinning to trust a specific root key ID for a Notary Globally Unique Name (GUN).
    3. Configure trust pinning to trust a CA for a specific Notary GUN or GUN prefix.

    More information on trust pinning can be found in our docs. Note all 3 options require an out of band communication in which you acquire either a root.json, the ID of the root key, or the CA certificate that was used to issue the root key.

    Implementing trust pinning under the docker trust command is in our TODO list, it's not there yet. However you can still use option 1 with docker trust. The cache is located at ~/.docker/trust/tuf/<GUN>/metadata/

    Additional context on option 3: Notary implements a feature that allows one to configure CAs for GUNs or GUN prefixes. The requirement in this instance is that the public root key is included in the root.json as an x509 certificate that chains to the configured CA. While CAs can be a controversial topic, nobody is forced to use this feature and in most attacker models it's strictly better than TOFU. Additionally TUF explicitly does not address how trust is bootstrapped.