2015-07-30 01:16:43 +00:00
|
|
|
<!--[metadata]>
|
|
|
|
+++
|
|
|
|
title = "Content trust in Docker"
|
|
|
|
description = "Enabling content trust in Docker"
|
|
|
|
keywords = ["content, trust, security, docker, documentation"]
|
|
|
|
[menu.main]
|
|
|
|
parent= "smn_content_trust"
|
|
|
|
weight=-1
|
|
|
|
+++
|
|
|
|
<![end-metadata]-->
|
|
|
|
|
|
|
|
# Content trust in Docker
|
|
|
|
|
|
|
|
When transferring data among networked systems, *trust* is a central concern. In
|
|
|
|
particular, when communicating over an untrusted medium such as the internet, it
|
2016-04-21 06:05:44 +00:00
|
|
|
is critical to ensure the integrity and the publisher of all the data a system
|
|
|
|
operates on. You use Docker Engine to push and pull images (data) to a public or private registry. Content trust
|
|
|
|
gives you the ability to verify both the integrity and the publisher of all the
|
2015-09-13 20:22:04 +00:00
|
|
|
data received from a registry over any channel.
|
2015-07-30 01:16:43 +00:00
|
|
|
|
2015-09-13 20:22:04 +00:00
|
|
|
## Understand trust in Docker
|
2015-07-30 01:16:43 +00:00
|
|
|
|
|
|
|
Content trust allows operations with a remote Docker registry to enforce
|
|
|
|
client-side signing and verification of image tags. Content trust provides the
|
|
|
|
ability to use digital signatures for data sent to and received from remote
|
|
|
|
Docker registries. These signatures allow client-side verification of the
|
2015-09-13 20:22:04 +00:00
|
|
|
integrity and publisher of specific image tags.
|
2015-07-30 01:16:43 +00:00
|
|
|
|
2016-03-17 18:27:56 +00:00
|
|
|
Currently, content trust is disabled by default. You must enable it by setting
|
2015-10-26 23:54:47 +00:00
|
|
|
the `DOCKER_CONTENT_TRUST` environment variable. Refer to the
|
|
|
|
[environment variables](../../reference/commandline/cli.md#environment-variables)
|
|
|
|
and [Notary](../../reference/commandline/cli.md#notary) configuration
|
|
|
|
for the docker client for more options.
|
2015-07-30 01:16:43 +00:00
|
|
|
|
|
|
|
Once content trust is enabled, image publishers can sign their images. Image consumers can
|
2016-08-15 12:14:41 +00:00
|
|
|
ensure that the images they use are signed. Publishers and consumers can be
|
2015-07-30 01:16:43 +00:00
|
|
|
individuals alone or in organizations. Docker's content trust supports users and
|
2015-09-13 20:22:04 +00:00
|
|
|
automated processes such as builds.
|
2015-07-30 01:16:43 +00:00
|
|
|
|
|
|
|
### Image tags and content trust
|
|
|
|
|
|
|
|
An individual image record has the following identifier:
|
|
|
|
|
|
|
|
```
|
|
|
|
[REGISTRY_HOST[:REGISTRY_PORT]/]REPOSITORY[:TAG]
|
|
|
|
```
|
|
|
|
|
|
|
|
A particular image `REPOSITORY` can have multiple tags. For example, `latest` and
|
|
|
|
`3.1.2` are both tags on the `mongo` image. An image publisher can build an image
|
2015-09-13 20:22:04 +00:00
|
|
|
and tag combination many times changing the image with each build.
|
2015-07-30 01:16:43 +00:00
|
|
|
|
|
|
|
Content trust is associated with the `TAG` portion of an image. Each image
|
|
|
|
repository has a set of keys that image publishers use to sign an image tag.
|
|
|
|
Image publishers have discretion on which tags they sign.
|
|
|
|
|
|
|
|
An image repository can contain an image with one tag that is signed and another
|
|
|
|
tag that is not. For example, consider [the Mongo image
|
|
|
|
repository](https://hub.docker.com/r/library/mongo/tags/). The `latest`
|
|
|
|
tag could be unsigned while the `3.1.6` tag could be signed. It is the
|
|
|
|
responsibility of the image publisher to decide if an image tag is signed or
|
|
|
|
not. In this representation, some image tags are signed, others are not:
|
|
|
|
|
2015-10-09 23:50:41 +00:00
|
|
|
![Signed tags](images/tag_signing.png)
|
2015-07-30 01:16:43 +00:00
|
|
|
|
|
|
|
Publishers can choose to sign a specific tag or not. As a result, the content of
|
|
|
|
an unsigned tag and that of a signed tag with the same name may not match. For
|
|
|
|
example, a publisher can push a tagged image `someimage:latest` and sign it.
|
|
|
|
Later, the same publisher can push an unsigned `someimage:latest` image. This second
|
2015-09-13 20:22:04 +00:00
|
|
|
push replaces the last unsigned tag `latest` but does not affect the signed `latest` version.
|
2015-07-30 01:16:43 +00:00
|
|
|
The ability to choose which tags they can sign, allows publishers to iterate over
|
|
|
|
the unsigned version of an image before officially signing it.
|
|
|
|
|
|
|
|
Image consumers can enable content trust to ensure that images they use were
|
|
|
|
signed. If a consumer enables content trust, they can only pull, run, or build
|
|
|
|
with trusted images. Enabling content trust is like wearing a pair of
|
|
|
|
rose-colored glasses. Consumers "see" only signed images tags and the less
|
|
|
|
desirable, unsigned image tags are "invisible" to them.
|
|
|
|
|
2015-10-09 23:50:41 +00:00
|
|
|
![Trust view](images/trust_view.png)
|
2015-07-30 01:16:43 +00:00
|
|
|
|
2016-04-21 06:05:44 +00:00
|
|
|
To the consumer who has not enabled content trust, nothing about how they
|
2015-07-30 01:16:43 +00:00
|
|
|
work with Docker images changes. Every image is visible regardless of whether it
|
|
|
|
is signed or not.
|
|
|
|
|
|
|
|
|
|
|
|
### Content trust operations and keys
|
|
|
|
|
|
|
|
When content trust is enabled, `docker` CLI commands that operate on tagged images must
|
|
|
|
either have content signatures or explicit content hashes. The commands that
|
|
|
|
operate with content trust are:
|
|
|
|
|
|
|
|
* `push`
|
|
|
|
* `build`
|
2015-09-13 20:22:04 +00:00
|
|
|
* `create`
|
2015-07-30 01:16:43 +00:00
|
|
|
* `pull`
|
2015-09-13 20:22:04 +00:00
|
|
|
* `run`
|
2015-07-30 01:16:43 +00:00
|
|
|
|
|
|
|
For example, with content trust enabled a `docker pull someimage:latest` only
|
|
|
|
succeeds if `someimage:latest` is signed. However, an operation with an explicit
|
|
|
|
content hash always succeeds as long as the hash exists:
|
|
|
|
|
|
|
|
```bash
|
|
|
|
$ docker pull someimage@sha256:d149ab53f8718e987c3a3024bb8aa0e2caadf6c0328f1d9d850b2a2a67f2819a
|
|
|
|
```
|
|
|
|
|
2015-09-17 06:23:12 +00:00
|
|
|
Trust for an image tag is managed through the use of signing keys. A key set is
|
2016-03-18 23:11:37 +00:00
|
|
|
created when an operation using content trust is first invoked. A key set consists
|
|
|
|
of the following classes of keys:
|
2015-07-30 01:16:43 +00:00
|
|
|
|
2016-05-08 01:36:10 +00:00
|
|
|
- an offline key that is the root of content trust for an image tag
|
2016-03-18 23:11:37 +00:00
|
|
|
- repository or tagging keys that sign tags
|
|
|
|
- server-managed keys such as the timestamp key, which provides freshness
|
|
|
|
security guarantees for your repository
|
2015-07-30 01:16:43 +00:00
|
|
|
|
|
|
|
The following image depicts the various signing keys and their relationships:
|
|
|
|
|
2015-10-09 23:50:41 +00:00
|
|
|
![Content trust components](images/trust_components.png)
|
2015-07-30 01:16:43 +00:00
|
|
|
|
2015-10-09 19:14:46 +00:00
|
|
|
>**WARNING**: Loss of the root key is **very difficult** to recover from.
|
2015-07-30 01:16:43 +00:00
|
|
|
>Correcting this loss requires intervention from [Docker
|
|
|
|
>Support](https://support.docker.com) to reset the repository state. This loss
|
|
|
|
>also requires **manual intervention** from every consumer that used a signed
|
2015-09-13 20:22:04 +00:00
|
|
|
>tag from this repository prior to the loss.
|
2015-07-30 01:16:43 +00:00
|
|
|
|
2015-10-09 19:14:46 +00:00
|
|
|
You should backup the root key somewhere safe. Given that it is only required
|
2016-04-21 06:05:44 +00:00
|
|
|
to create new repositories, it is a good idea to store it offline in hardware.
|
2016-03-18 23:11:37 +00:00
|
|
|
For details on securing, and backing up your keys, make sure you
|
|
|
|
read how to [manage keys for content trust](trust_key_mng.md).
|
2015-07-30 01:16:43 +00:00
|
|
|
|
|
|
|
## Survey of typical content trust operations
|
|
|
|
|
|
|
|
This section surveys the typical trusted operations users perform with Docker
|
2016-06-13 16:22:36 +00:00
|
|
|
images. Specifically, we will be going through the following steps to help us exercise
|
|
|
|
these various trusted operations:
|
|
|
|
|
|
|
|
* Build and push an unsigned image
|
|
|
|
* Pull an unsigned image
|
|
|
|
* Build and push a signed image
|
|
|
|
* Pull the signed image pushed above
|
|
|
|
* Pull unsigned image pushed above
|
2015-07-30 01:16:43 +00:00
|
|
|
|
2015-09-13 20:22:04 +00:00
|
|
|
### Enable and disable content trust per-shell or per-invocation
|
2015-07-30 01:16:43 +00:00
|
|
|
|
2015-09-13 20:22:04 +00:00
|
|
|
In a shell, you can enable content trust by setting the `DOCKER_CONTENT_TRUST`
|
|
|
|
environment variable. Enabling per-shell is useful because you can have one
|
|
|
|
shell configured for trusted operations and another terminal shell for untrusted
|
|
|
|
operations. You can also add this declaration to your shell profile to have it
|
|
|
|
turned on always by default.
|
2015-07-30 01:16:43 +00:00
|
|
|
|
|
|
|
To enable content trust in a `bash` shell enter the following command:
|
|
|
|
|
|
|
|
```bash
|
|
|
|
export DOCKER_CONTENT_TRUST=1
|
|
|
|
```
|
|
|
|
|
2015-09-13 20:22:04 +00:00
|
|
|
Once set, each of the "tag" operations requires a key for a trusted tag.
|
|
|
|
|
|
|
|
In an environment where `DOCKER_CONTENT_TRUST` is set, you can use the
|
|
|
|
`--disable-content-trust` flag to run individual operations on tagged images
|
|
|
|
without content trust on an as-needed basis.
|
|
|
|
|
2016-06-13 16:22:36 +00:00
|
|
|
Consider the following Dockerfile that uses an untrusted base image:
|
|
|
|
|
|
|
|
```
|
|
|
|
$ cat Dockerfile
|
|
|
|
FROM docker/trusttest:latest
|
|
|
|
RUN echo
|
|
|
|
```
|
|
|
|
|
|
|
|
In order to build a container successfully using this Dockerfile, one can do:
|
|
|
|
|
|
|
|
```
|
|
|
|
$ docker build --disable-content-trust -t <username>/nottrusttest:latest .
|
|
|
|
Sending build context to Docker daemon 42.84 MB
|
|
|
|
...
|
|
|
|
Successfully built f21b872447dc
|
|
|
|
```
|
|
|
|
|
|
|
|
The same is true for all the other commands, such as `pull` and `push`:
|
|
|
|
|
|
|
|
```
|
|
|
|
$ docker pull --disable-content-trust docker/trusttest:latest
|
|
|
|
...
|
|
|
|
$ docker push --disable-content-trust <username>/nottrusttest:latest
|
|
|
|
...
|
2015-09-13 20:22:04 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
To invoke a command with content trust enabled regardless of whether or how the `DOCKER_CONTENT_TRUST` variable is set:
|
|
|
|
|
|
|
|
```bash
|
2016-06-13 16:22:36 +00:00
|
|
|
$ docker build --disable-content-trust=false -t <username>/trusttest:testing .
|
2015-09-13 20:22:04 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
All of the trusted operations support the `--disable-content-trust` flag.
|
2015-07-30 01:16:43 +00:00
|
|
|
|
|
|
|
|
|
|
|
### Push trusted content
|
|
|
|
|
2015-09-13 20:22:04 +00:00
|
|
|
To create signed content for a specific image tag, simply enable content trust
|
|
|
|
and push a tagged image. If this is the first time you have pushed an image
|
|
|
|
using content trust on your system, the session looks like this:
|
2015-07-30 01:16:43 +00:00
|
|
|
|
|
|
|
```bash
|
2016-06-13 16:22:36 +00:00
|
|
|
$ docker push <username>/trusttest:testing
|
|
|
|
The push refers to a repository [docker.io/<username>/trusttest] (len: 1)
|
2015-09-13 20:22:04 +00:00
|
|
|
9a61b6b1315e: Image already exists
|
|
|
|
902b87aaaec9: Image already exists
|
2015-07-30 01:16:43 +00:00
|
|
|
latest: digest: sha256:d02adacee0ac7a5be140adb94fa1dae64f4e71a68696e7f8e7cbf9db8dd49418 size: 3220
|
|
|
|
Signing and pushing trust metadata
|
2015-10-09 19:14:46 +00:00
|
|
|
You are about to create a new root signing key passphrase. This passphrase
|
2015-07-30 01:16:43 +00:00
|
|
|
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.
|
2015-10-09 19:14:46 +00:00
|
|
|
Enter passphrase for new root key with id a1d96fb:
|
|
|
|
Repeat passphrase for new root key with id a1d96fb:
|
2016-06-13 16:22:36 +00:00
|
|
|
Enter passphrase for new repository key with id docker.io/<username>/trusttest (3a932f1):
|
|
|
|
Repeat passphrase for new repository key with id docker.io/<username>/trusttest (3a932f1):
|
|
|
|
Finished initializing "docker.io/<username>/trusttest"
|
2015-07-30 01:16:43 +00:00
|
|
|
```
|
2015-09-13 20:22:04 +00:00
|
|
|
When you push your first tagged image with content trust enabled, the `docker`
|
|
|
|
client recognizes this is your first push and:
|
|
|
|
|
2015-10-09 19:14:46 +00:00
|
|
|
- alerts you that it will create a new root key
|
2016-04-21 06:05:44 +00:00
|
|
|
- requests a passphrase for the root key
|
2015-10-09 19:14:46 +00:00
|
|
|
- generates a root key in the `~/.docker/trust` directory
|
2016-04-21 06:05:44 +00:00
|
|
|
- requests a passphrase for the repository key
|
2015-10-09 19:14:46 +00:00
|
|
|
- generates a repository key for in the `~/.docker/trust` directory
|
2015-07-30 01:16:43 +00:00
|
|
|
|
2016-04-21 06:05:44 +00:00
|
|
|
The passphrase you chose for both the root key and your repository key-pair
|
2015-09-13 20:22:04 +00:00
|
|
|
should be randomly generated and stored in a *password manager*.
|
|
|
|
|
2016-06-13 16:22:36 +00:00
|
|
|
> **NOTE**: If you omit the `testing` tag, content trust is skipped. This is true
|
2015-09-13 20:22:04 +00:00
|
|
|
even if content trust is enabled and even if this is your first push.
|
2015-07-30 01:16:43 +00:00
|
|
|
|
|
|
|
```bash
|
2016-06-13 16:22:36 +00:00
|
|
|
$ docker push <username>/trusttest
|
|
|
|
The push refers to a repository [docker.io/<username>/trusttest] (len: 1)
|
2015-09-13 20:22:04 +00:00
|
|
|
9a61b6b1315e: Image successfully pushed
|
|
|
|
902b87aaaec9: Image successfully pushed
|
2015-07-30 01:16:43 +00:00
|
|
|
latest: digest: sha256:a9a9c4402604b703bed1c847f6d85faac97686e48c579bd9c3b0fa6694a398fc size: 3220
|
|
|
|
No tag specified, skipping trust metadata push
|
|
|
|
```
|
|
|
|
|
|
|
|
It is skipped because as the message states, you did not supply an image `TAG`
|
|
|
|
value. In Docker content trust, signatures are associated with tags.
|
|
|
|
|
2015-10-09 19:14:46 +00:00
|
|
|
Once you have a root key on your system, subsequent images repositories
|
|
|
|
you create can use that same root key:
|
2015-07-30 01:16:43 +00:00
|
|
|
|
|
|
|
```bash
|
2016-06-13 16:22:36 +00:00
|
|
|
$ docker push docker.io/<username>/otherimage:latest
|
|
|
|
The push refers to a repository [docker.io/<username>/otherimage] (len: 1)
|
2015-09-13 20:22:04 +00:00
|
|
|
a9539b34a6ab: Image successfully pushed
|
|
|
|
b3dbab3810fc: Image successfully pushed
|
2015-07-30 01:16:43 +00:00
|
|
|
latest: digest: sha256:d2ba1e603661a59940bfad7072eba698b79a8b20ccbb4e3bfb6f9e367ea43939 size: 3346
|
|
|
|
Signing and pushing trust metadata
|
2015-10-09 19:14:46 +00:00
|
|
|
Enter key passphrase for root key with id a1d96fb:
|
2016-06-13 16:22:36 +00:00
|
|
|
Enter passphrase for new repository key with id docker.io/<username>/otherimage (bb045e3):
|
|
|
|
Repeat passphrase for new repository key with id docker.io/<username>/otherimage (bb045e3):
|
|
|
|
Finished initializing "docker.io/<username>/otherimage"
|
2015-07-30 01:16:43 +00:00
|
|
|
```
|
|
|
|
|
2015-10-09 19:14:46 +00:00
|
|
|
The new image has its own repository key and timestamp key. The `latest` tag is signed with both of
|
2015-07-30 01:16:43 +00:00
|
|
|
these.
|
|
|
|
|
|
|
|
|
|
|
|
### Pull image content
|
|
|
|
|
|
|
|
A common way to consume an image is to `pull` it. With content trust enabled, the Docker
|
2016-06-13 16:22:36 +00:00
|
|
|
client only allows `docker pull` to retrieve signed images. Let's try to pull the image
|
|
|
|
you signed and pushed earlier:
|
2015-07-30 01:16:43 +00:00
|
|
|
|
|
|
|
```
|
2016-06-13 16:22:36 +00:00
|
|
|
$ docker pull <username>/trusttest:testing
|
2015-07-30 01:16:43 +00:00
|
|
|
Using default tag: latest
|
2016-06-13 16:22:36 +00:00
|
|
|
Pull (1 of 1): <username>/trusttest:testing@sha256:d149ab53f871
|
2015-07-30 01:16:43 +00:00
|
|
|
...
|
2016-06-13 16:22:36 +00:00
|
|
|
Tagging <username>/trusttest@sha256:d149ab53f871 as docker/trusttest:testing
|
2015-07-30 01:16:43 +00:00
|
|
|
```
|
|
|
|
|
2016-06-13 16:22:36 +00:00
|
|
|
In the following example, the command does not specify a tag, so the system uses
|
|
|
|
the `latest` tag by default again and the `docker/trusttest:latest` tag is not signed.
|
2015-07-30 01:16:43 +00:00
|
|
|
|
|
|
|
```bash
|
2016-06-13 16:22:36 +00:00
|
|
|
$ docker pull docker/trusttest
|
2015-07-30 01:16:43 +00:00
|
|
|
Using default tag: latest
|
|
|
|
no trust data available
|
|
|
|
```
|
|
|
|
|
2016-06-13 16:22:36 +00:00
|
|
|
Because the tag `docker/trusttest:latest` is not trusted, the `pull` fails.
|
2015-07-30 01:16:43 +00:00
|
|
|
|
|
|
|
## Related information
|
|
|
|
|
2015-10-09 23:50:41 +00:00
|
|
|
* [Manage keys for content trust](trust_key_mng.md)
|
|
|
|
* [Automation with content trust](trust_automation.md)
|
2016-03-18 23:11:37 +00:00
|
|
|
* [Delegations for content trust](trust_delegation.md)
|
2015-10-09 23:50:41 +00:00
|
|
|
* [Play in a content trust sandbox](trust_sandbox.md)
|