0

We are using notary service along with third party provider aujas for signing the docker images. I have a build machine from where we run the scripts to sign the images. So far so good.

When my customer pulls the image that we have signed, how can he be sure that the image is a signed image and can be trusted ?

I tested from a different machine (other than the build machine) and I am able to pull the image successfully when I unset DOCKER_CONTENT_TRUST. The moment I enable DOCKER_CONTENT_TRUST I get an error that

Error: remote trust data does not exist for docker.io/xxx/xxxx: notary.docker.io does not have trust data for docker.io/xxxx/xxxx

How do my customer trust that image he is pulling is signed ?

Thanks, Madhav

srinu259
  • 309
  • 4
  • 14

2 Answers2

2

Not all images have been signed by their maintainers. The error your are getting is because this particular image was not signed by the maintainer of that image.

An image that is signed for example is the nginx image.

$ docker trust inspect nginx:alpine
[
    {
        "Name": "nginx:alpine",
        "SignedTags": [
            {
                "SignedTag": "alpine",
                "Digest": "1e9c503db9913a59156f78c6420f6e2f01c8a3b71ceeeddcd7f604c4db0f045e",
                "Signers": [
                    "Repo Admin"
                ]
            }
        ],
        "Signers": [],
        "AdministrativeKeys": [
            {
                "Name": "Root",
                "Keys": [
                    {
                        "ID": "d2f02ea35ebffce87d31673efbff44c199b1af0be042989d4655a176e8aad40d"
                    }
                ]
            },
            {
                "Name": "Repository",
                "Keys": [
                    {
                        "ID": "ec92eb8e988506253f8590cb924b6becdbb0520f2fb430257d8879e2d3bed2cc"
                    }
                ]
            }
        ]
    }
]

Therefore you can pull this image with content trust enabled.

$ DOCKER_CONTENT_TRUST=true docker pull nginx:alpine
Pull (1 of 1): nginx:alpine@sha256:1e9c503db9913a59156f78c6420f6e2f01c8a3b71ceeeddcd7f604c4db0f045e
docker.io/library/nginx@sha256:1e9c503db9913a59156f78c6420f6e2f01c8a3b71ceeeddcd7f604c4db0f045e: Pulling from library/nginx
Digest: sha256:1e9c503db9913a59156f78c6420f6e2f01c8a3b71ceeeddcd7f604c4db0f045e
Status: Image is up to date for nginx@sha256:1e9c503db9913a59156f78c6420f6e2f01c8a3b71ceeeddcd7f604c4db0f045e
Tagging nginx@sha256:1e9c503db9913a59156f78c6420f6e2f01c8a3b71ceeeddcd7f604c4db0f045e as nginx:alpine
docker.io/library/nginx:alpine

However an image that is not signed can not be pulled with content trust enabled.

$ docker trust inspect docker/whalesay
[]
No signatures or cannot access docker/whalesay

As you can see then I will get the same error as you got.

$ DOCKER_CONTENT_TRUST=true docker pull docker/whalesay
Using default tag: latest
Error: remote trust data does not exist for docker.io/docker/whalesay: notary.docker.io does not have trust data for docker.io/docker/whalesay

If you would like to work with signed images a way to achieve that is by signing them yourself and push yo your own repository.

export DOCKER_CONTENT_TRUST=true # enable content trust globally
DOCKER_CONTENT_TRUST=false docker pull docker/whalesay # download unsiged image by disabling content trust
docker tag docker/whalesay marcofranssen/whalesay 
docker push marcofranssen/whalesay # pushes and signs the image in my own repository with my keys
docker trust inspect marcofranssen/whalesay
[
    {
        "Name": "marcofranssen/whalesay",
        "SignedTags": [
            {
                "SignedTag": "latest",
                "Digest": "4a79736c5f63638261bc21228b48e9991340ca6d977b73de3598be20606e5d87",
                "Signers": [
                    "marcofranssen"
                ]
            }
        ],
        "Signers": [
            {
                "Name": "marcofranssen",
                "Keys": [
                    {
                        "ID": "eb9dd99255f91efeba139941fbfdb629f11c2353704de07a2ad653d22311c88b"
                    }
                ]
            }
        ],
        "AdministrativeKeys": [
            {
                "Name": "Root",
                "Keys": [
                    {
                        "ID": "0428c356406a6ea3543012855c117d13d784774e49aa6db461cfbad5726d187b"
                    }
                ]
            },
            {
                "Name": "Repository",
                "Keys": [
                    {
                        "ID": "b635efeddff59751e8b6b59abb45383555103d702e7d3f46fbaaa9a8ac144ab8"
                    }
                ]
            }
        ]
    }
]

Now you can use your own repository with signed versions of the image. It goes without saying that you should only sign images after verifying it's contents.

Marco
  • 4,817
  • 5
  • 34
  • 75
0

Images that are pulled through Docker Content Trust can be trusted as their cryptographic signatures are automatically verified. From the Docker documentation:

Image consumers can enable DCT to ensure that images they use were signed. If a consumer enables DCT, they can only pull, run, or build with trusted images. Enabling DCT is a bit like applying a “filter” to your registry. Consumers “see” only signed image tags and the less desirable, unsigned image tags are “invisible” to them.

Stefan Zhelyazkov
  • 2,599
  • 4
  • 16
  • 41
  • I tested on a customer machine by enabling DOCKER_CONTENT_TRUST. But I keep getting the error message 'Error: remote trust data does not exist for docker.io/xxx/xxxx: notary.docker.io does not have trust data for docker.io/xxxx/xxxx' – srinu259 Apr 16 '21 at 11:02
  • Have you set `DOCKER_CONTENT_TRUST_SERVER` to point to your notary registry? This may be helpful: https://github.com/theupdateframework/notary/issues/1370#issuecomment-400782398 – Stefan Zhelyazkov Apr 16 '21 at 12:05