mirror of https://github.com/docker/docs.git
Add content trust docs from UCP 2.0 (#2656)
This commit is contained in:
parent
fa304dc832
commit
cff050336f
|
@ -1269,6 +1269,14 @@ manuals:
|
|||
title: Web-based access
|
||||
- path: /datacenter/ucp/2.1/guides/user/access-ucp/cli-based-access/
|
||||
title: CLI-based access
|
||||
- sectiontitle: Content trust
|
||||
section:
|
||||
- path: /datacenter/ucp/2.1/guides/user/content-trust/
|
||||
title: Run only images you trust
|
||||
- path: /datacenter/ucp/2.1/guides/user/content-trust/manage-trusted-repositories/
|
||||
title: Manage trusted repositories
|
||||
- path: /datacenter/ucp/2.1/guides/user/content-trust/continuous-integration/
|
||||
title: Use trusted images for continuous integration
|
||||
- sectiontitle: Deploy an application
|
||||
section:
|
||||
- path: /datacenter/ucp/2.1/guides/user/services/deploy-a-service/
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
---
|
||||
description: Set up and configure content trust and signing policy for use with a continuous integration system
|
||||
keywords: ucp, trust, notary, security, continuous integration
|
||||
title: Use trusted images for continuous integration
|
||||
---
|
||||
|
||||
The document provides a minimal example on setting up Docker Content Trust (DCT) in
|
||||
Universal Control Plane (UCP) for use with a Continuous Integration (CI) system. It
|
||||
covers setting up the necessary accounts and trust delegations to restrict only those
|
||||
images built by your CI system to be deployed to your UCP managed cluster.
|
||||
|
||||
## Set up UCP accounts and teams
|
||||
|
||||
The first step is to create a user account for your CI system. For the purposes of
|
||||
this document we will assume you are using Jenkins as your CI system and will therefore
|
||||
name the account "jenkins". As an admin user logged in to UCP, navigate to "User Management"
|
||||
and select "Add User". Create a user with the name "jenkins" and set a strong password.
|
||||
|
||||
Next, create a team called "CI" and add the "jenkins" user to this team. All signing
|
||||
policy is team based, so if we want only a single user to be able to sign images
|
||||
destined to be deployed on the cluster, we must create a team for this one user.
|
||||
|
||||
## Set up the signing policy
|
||||
|
||||
While still logged in as an admin, navigate to "Admin Settings" and select the "Content Trust"
|
||||
subsection. Select the checkbox to enable content trust and in the select box that appears,
|
||||
select the "CI" team we have just created. Save the settings.
|
||||
|
||||
This policy will require that every image that referenced in a `docker pull`, `docker run`,
|
||||
or `docker service create` must be signed by a key corresponding to a member of the "CI" team.
|
||||
In this case, the only member is the "jenkins" user.
|
||||
|
||||
## Create keys for the Jenkins user
|
||||
|
||||
The signing policy implementation uses the certificates issued in user client bundles
|
||||
to connect a signature to a user. Using an incognito browser window (or otherwise),
|
||||
log in to the "jenkins" user account you created earlier. Download a client bundle for
|
||||
this user. It is also recommended to change the description associated with the public
|
||||
key stored in UCP such that you can identify in the future which key is being used for
|
||||
signing.
|
||||
|
||||
N.B. each time a user retrieves a new client bundle, a new keypair is generated. It is therefore
|
||||
necessary to keep track of a specific bundle that a user chooses to designate as their signing bundle.
|
||||
|
||||
Once you have decompressed the client bundle, the only two files you need for the purposes
|
||||
of signing are `cert.pem` and `key.pem`. These represent the public and private parts of
|
||||
the user's signing identity respectively. We will load the `key.pem` file onto the Jenkins
|
||||
servers, and user `cert.pem` to create delegations for the "jenkins" user in our
|
||||
Trusted Collection.
|
||||
|
||||
## Prepare the Jenkins server
|
||||
|
||||
### Load `key.pem` on Jenkins
|
||||
|
||||
You will need to use the notary client to load keys onto your Jenkins server. Simply run
|
||||
`notary -d /path/to/.docker/trust key import /path/to/key.pem`. You will be asked to set
|
||||
a password to encrypt the key on disk. For automated signing, this password can be configured
|
||||
into the environment under the variable name `DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE`. The `-d`
|
||||
flag to the command specifies the path to the `trust` subdirectory within the server's `docker`
|
||||
configuration directory. Typically this is found at `~/.docker/trust`.
|
||||
|
||||
### Enable content trust
|
||||
|
||||
There are two ways to enable content trust: globally, and per operation. To enabled content
|
||||
trust globally, set the environment variable `DOCKER_CONTENT_TRUST=1`. To enable on a per
|
||||
operation basis, wherever you run `docker push` in your Jenkins scripts, add the flag
|
||||
`--disable-content-trust=false`. You may wish to use this second option if you only want
|
||||
to sign some images.
|
||||
|
||||
The Jenkins server is now prepared to sign images, but we need to create delegations referencing
|
||||
the key to give it the necessary permissions.
|
||||
|
||||
## Initialize a repository
|
||||
|
||||
Any commands displayed in this section should _not_ be run from the Jenkins server. You
|
||||
will most likely want to run them from your local system.
|
||||
|
||||
If this is a new repository, create it in Docker Trusted Registry (DTR) or Docker Hub,
|
||||
depending on which you use to store your images, before proceeding further.
|
||||
|
||||
We will now initialize the trust data and create the delegation that provides the Jenkins
|
||||
key with permissions to sign content. The following commands initialize the trust data and
|
||||
rotate snapshotting responsibilities to the server. This is necessary to ensure human involvement
|
||||
it not required to publish new content.
|
||||
|
||||
```
|
||||
notary -s https://my_notary_server.com -d ~/.docker/trust init my_repository
|
||||
notary -s https://my_notary_server.com -d ~/.docker/trust key rotate my_repository snapshot -r
|
||||
notary -s https://my_notary_server.com -d ~/.docker/trust publish my_repository
|
||||
```
|
||||
|
||||
N.B. the `-s` flag provides the server hosting a notary service. If you are operating against
|
||||
Docker Hub, this will be `https://notary.docker.io`. If you are operating against your own DTR
|
||||
instance, this will be the same hostname you use in image names when running docker commands preceded
|
||||
by the `https://` scheme. For example, if you would run `docker push my_dtr:4443/me/an_image` the value
|
||||
of the `-s` flag would be expected to be `https://my_dtr:4443`.
|
||||
|
||||
N.B. if you are using DTR, the name of the repository should be identical to the full name you use
|
||||
in a `docker push` command. If however you use Docker Hub, the name you use in a `docker push`
|
||||
must be preceded by `docker.io/`. i.e. if you ran `docker push me/alpine`, you would
|
||||
`notary init docker.io/me/alpine`.
|
||||
|
||||
For brevity, we will exclude the `-s` and `-d` flags from subsequent command, but be aware you
|
||||
will still need to provide them for the commands to work correctly.
|
||||
|
||||
Now that the repository is initialized, we need to create the delegations for Jenkins. Docker
|
||||
Content Trust treats a delegation role called `targets/releases` specially. It considers this
|
||||
delegation to contain the canonical list of published images for the repository. It is therefore
|
||||
generally desiable to add all users to this delegation with the following command:
|
||||
|
||||
```
|
||||
notary delegation add my_repository targets/releases --all-paths /path/to/cert.pem
|
||||
```
|
||||
|
||||
This solves a number of prioritization problems that would result from needing to determine
|
||||
which delegation should ultimately be trusted for a specific image. However, because it
|
||||
is anticipated that any user will be able to sign the `targets/releases` role it is not trusted
|
||||
in determining if a signing policy has been met. Therefore it is also necessary to create a
|
||||
delegation specifically for Jenkins:
|
||||
|
||||
```
|
||||
notary delegation add my_repository targets/jenkins --all-paths /path/to/cert.pem
|
||||
```
|
||||
|
||||
We will then publish both these updates (remember to add the correct `-s` and `-d` flags):
|
||||
|
||||
```
|
||||
notary publish my_repository
|
||||
```
|
||||
|
||||
Informational (Advanced): If we included the `targets/releases` role in determining if a signing policy
|
||||
had been met, we would run into the situation of images being opportunistically deployed when
|
||||
an appropriate user signs. In the scenario we have described so far, only images signed by
|
||||
the "CI" team (containing only the "jenkins" user) should be deployable. If a user "Moby" could
|
||||
also sign images but was not part of the "CI" team, they might sign and publish a new `targets/releases`
|
||||
that contained their image. UCP would refuse to deploy this image because it was not signed
|
||||
by the "CI" team. However, the next time Jenkins published an image, it would update and sign
|
||||
the `targets/releases` role as whole, enabling "Moby" to deploy their image.
|
||||
|
||||
## Conclusion
|
||||
|
||||
With the Trusted Collection initialized, and delegations created, the Jenkins server will
|
||||
now use the key we imported to sign any images we push to this repository.
|
||||
|
||||
Through either the Docker CLI, or the UCP browser interface, we will find that any images
|
||||
that do not meet our signing policy cannot be used. The signing policy we set up requires
|
||||
that the "CI" team must have signed any image we attempt to `docker pull`, `docker run`,
|
||||
or `docker service create`, and the only member of that team is the "jenkins" user. This
|
||||
restricts us to only running images that were published by our Jenkins CI system.
|
|
@ -0,0 +1,179 @@
|
|||
---
|
||||
description: Configure a Docker Universal Plane cluster to only allow running applications
|
||||
that use images you trust.
|
||||
keywords: docker, ucp, backup, restore, recovery
|
||||
title: Run only the images you trust
|
||||
---
|
||||
|
||||
With Docker Universal Control Plane (UCP) you can enforce applications to only use
|
||||
Docker images signed by UCP users you trust. When a user tries to deploy an
|
||||
application to the cluster, UCP checks if the application uses a Docker image
|
||||
that is not trusted, and won't continue with the deployment if that's the case.
|
||||
|
||||
By signing and verifying the Docker images, you ensure that the images being
|
||||
used in your cluster are the ones you trust and haven't been altered either
|
||||
in the image registry or on their way from the image registry to your UCP
|
||||
cluster.
|
||||
|
||||
## Configure UCP
|
||||
|
||||
To configure UCP to only allow running applications that use Docker images you
|
||||
trust, go to the **UCP web UI**, navigate to the **Settings** page, and click
|
||||
the **Content Trust** tab.
|
||||
|
||||
<!-- todo: add screenshot -->
|
||||
|
||||
Select the **Run only signed images** option to only allow deploying
|
||||
applications if they use images you trust.
|
||||
|
||||
Then, in the **Require signature from** field, you can specify all the teams
|
||||
that need sign the image, before it is trusted to run in the UCP cluster. If
|
||||
you specify multiple teams, the image needs to be signed by a member of each
|
||||
team, or someone that is a member of all those teams.
|
||||
If you don't specify any team, the image will be trusted as long as it is signed
|
||||
by any UCP user whose keys are trusted in a Notary delegation role.
|
||||
|
||||
## Set up the Docker Notary CLI client
|
||||
|
||||
Once you've configured UCP to only run applications that use Docker images you
|
||||
trust, you'll need to specify which Docker images can be trusted. This is done
|
||||
by using the Docker Notary server that is built into Docker Trusted Registry.
|
||||
You'll configure the Notary server to store signed metadata about the Docker
|
||||
images you trust.
|
||||
|
||||
To interact with the Notary server, you need to
|
||||
[install the Notary CLI client](https://github.com/docker/notary/releases).
|
||||
|
||||
Once you've installed the Notary client, you need to configure it to talk to
|
||||
the Notary server that is built into Docker Trusted Registry. This can be done
|
||||
using a [Notary configuration file](/notary/reference/client-config.md)
|
||||
or by running:
|
||||
|
||||
```bash
|
||||
# Create an alias to always have the notary client talking to the right server
|
||||
$ alias notary="notary -s https://<dtr_url> -d ~/.docker/trust"
|
||||
```
|
||||
|
||||
Where `-s` specifies the notary server to talk to, and `-d` specifies the
|
||||
directory to store private keys and cache data.
|
||||
|
||||
If your Docker Trusted Registry is not using certificates signed by a globally
|
||||
trusted certificate authority, you'll also need to configure notary to use the
|
||||
certificate of the DTR CA:
|
||||
|
||||
```bash
|
||||
$ alias notary="notary -s https://<dtr_url> -d ~/.docker/trust --tlscacert <dtr_ca.pem>"
|
||||
```
|
||||
|
||||
## Set up a trusted image repository
|
||||
|
||||
Once your Docker Notary CLI client is configured, you can check if Notary has
|
||||
information about a specific repository:
|
||||
|
||||
```bash
|
||||
# <dtr_url>/<account>/<repository> is also known as a Globally Unique Name (GUN)
|
||||
$ notary list <dtr_url>/<account>/<repository>
|
||||
```
|
||||
|
||||
If notary has information about the repository it returns the list of
|
||||
image tags it knows about, their expected digests, and the role of the private
|
||||
key used to sign the metadata.
|
||||
|
||||
If Notary doesn't know yet about an image repository, run:
|
||||
|
||||
```bash
|
||||
$ notary init -p <dtr_url>/<account>/<repository>
|
||||
```
|
||||
|
||||
The Notary CLI client generates public and private key pairs, prompts you for
|
||||
a passphrase to encrypt the private key, and stores the key pair in the
|
||||
directory you've specified with the `notary -d` flag.
|
||||
You should ensure you create backups for these keys, and that they are kept
|
||||
securely and offline.
|
||||
[Learn more about the keys used by Docker Notary.](/engine/security/trust/trust_key_mng.md)
|
||||
|
||||
## Sign and push an image
|
||||
|
||||
Now you can sign your images before pushing them to Docker Trusted Registry:
|
||||
|
||||
```bash
|
||||
# Setting Docker content trust makes the Docker CLI client sign images before pushing them
|
||||
$ export DOCKER_CONTENT_TRUST=1
|
||||
# Push the image
|
||||
$ docker push <dtr_url>/<account>/<repository>:<tag>
|
||||
```
|
||||
|
||||
The Docker CLI client will prompt you for the passphrase you used to encrypt the
|
||||
private keys, sign the image, and push it to the registry.
|
||||
|
||||
|
||||
## Delegate image signing
|
||||
|
||||
Instead of signing the Docker images yourself, you can delegate that task
|
||||
to other users.
|
||||
|
||||
Delegation roles simplify collaborator workflows in Notary trusted collections,
|
||||
and also allow for fine-grained permissions within a collection's contents
|
||||
across delegations.
|
||||
Delegation roles act as signers in Notary that are managed by the targets key
|
||||
and can be configured to use external signing keys. Keys can be dynamically
|
||||
added to or removed from delegation roles as collaborators join and leave
|
||||
trusted repositories.
|
||||
[Learn more about Notary delegation roles.](/notary/advanced_usage.md)
|
||||
|
||||
Every change to the repository now needs to be signed by the snapshot key that
|
||||
was generated with the `notary init` command.
|
||||
To avoid having to distribute this key to other members so that they can also
|
||||
sign images with this key, you can rotate the key and make it be managed by
|
||||
the Notary server.
|
||||
|
||||
This operation only needs to be done once for the repository.
|
||||
|
||||
```bash
|
||||
# This only needs to be done once for the repository
|
||||
$ notary key rotate <dtr_url>/<account>/<repository> snapshot --server-managed
|
||||
```
|
||||
|
||||
Then ask the users you want to delegate the image signing to share with you
|
||||
the `cert.pem` files that are included in their client bundles. These files
|
||||
should be shared using a trusted channel.
|
||||
|
||||
Then run the following command to create a new Notary delegation role, using the
|
||||
user certificates:
|
||||
|
||||
```bash
|
||||
$ notary delegation add -p <dtr_url>/<account>/<repository> targets/releases --all-paths user1.pem user2.pem
|
||||
```
|
||||
|
||||
The above command adds the the `targets/releases` delegation role to a trusted
|
||||
repository.
|
||||
This role is treated as an actual release branch for Docker Content Trust,
|
||||
since `docker pull` commands with trust enabled will pull directly from this
|
||||
role, if data exists.
|
||||
All users that can release images should be added to this role.
|
||||
[Learn more about the targets/releases role](/engine/security/trust/trust_delegation.md).
|
||||
|
||||
Notary has no limit on how many delegation roles can exist, so you can add more
|
||||
delegation roles such as `targets/qa_team` or `targets/security_team` to the
|
||||
trusted repository.
|
||||
|
||||
Valid delegation roles take the form of `targets/<delegation>`, where
|
||||
`<delegation>` does not include further slashes.
|
||||
|
||||
You will need to add the key to at least one delegation in addition to the `targets/releases` delegation in order for UCP to honor the signed content:
|
||||
|
||||
```bash
|
||||
$ notary delegation add -p <dtr_url>/<account>/<repository> targets/devops --all-paths user1.pem user2.pem
|
||||
```
|
||||
|
||||
Before delegation role users can publish signed content with Notary or
|
||||
Docker Content Trust, they must import the private key associated with the user certificate:
|
||||
|
||||
```bash
|
||||
$ notary key import key.pem
|
||||
```
|
||||
|
||||
## Where to go next
|
||||
|
||||
* [Manage trusted repositories](manage-trusted-repositories.md)
|
||||
* [Get started with Notary](/notary/getting_started.md)
|
|
@ -0,0 +1,126 @@
|
|||
---
|
||||
description: Learn how to use the Notary CLI client to manage trusted repositories
|
||||
keywords: UCP, trust, notary, registry, security
|
||||
title: Manage trusted repositories
|
||||
---
|
||||
|
||||
Once you install the Notary CLI client, you can use it to manage your signing
|
||||
keys, authorize other team members to sign images, and rotate the keys if
|
||||
a private key has been compromised.
|
||||
|
||||
When using the Notary CLI client you need to specify where is Notary server
|
||||
you want to communicate with, and where to store the private keys and cache for
|
||||
the CLI client.
|
||||
|
||||
```bash
|
||||
# Create an alias to always have the notary client talking to the right server
|
||||
$ alias notary="notary -s https://<dtr_url> -d ~/.docker/trust"
|
||||
```
|
||||
|
||||
## Manage staged changes
|
||||
|
||||
The Notary CLI client stages changes before publishing them to the server.
|
||||
You can manage the changes that are staged by running:
|
||||
|
||||
```bash
|
||||
# Check what changes are staged
|
||||
$ notary status <dtr_url>/<account>/<repository>
|
||||
|
||||
# Unstage a specific change
|
||||
$ notary status <dtr_url>/<account>/<repository> --unstage 0
|
||||
|
||||
# Alternatively, unstage all changes
|
||||
$ notary status <dtr_url>/<account>/<repository> --reset
|
||||
```
|
||||
|
||||
When you're ready to publish your chages to the Notary server, run:
|
||||
|
||||
```bash
|
||||
$ notary publish <dtr_url>/<account>/<repository>
|
||||
```
|
||||
|
||||
## Delete trust data
|
||||
|
||||
Administrator users can remove all signatures from a trusted repository by
|
||||
running:
|
||||
|
||||
```bash
|
||||
$ notary delete <dtr_url>/<account>/<repository> --remote
|
||||
```
|
||||
|
||||
If you don't include the `--remote` flag, Notary deletes local cached content
|
||||
but will not delete data from the Notary server.
|
||||
|
||||
|
||||
## Change the passphrase for a key
|
||||
|
||||
The Notary CLI client manages the keys used to sign the image metadata. To
|
||||
list all the keys managed by the Notary CLI client, run:
|
||||
|
||||
```bash
|
||||
$ notary key list
|
||||
```
|
||||
|
||||
To chance the passphrase used to encrypt one of the keys, run:
|
||||
|
||||
```bash
|
||||
$ notary key passwd <key_id>
|
||||
```
|
||||
|
||||
## Rotate keys
|
||||
|
||||
If one of the private keys is compromised you can rotate that key, so that
|
||||
images that were signed with those keys stop being trusted.
|
||||
|
||||
For keys that are kept offline and managed by the Notary CLI client, such the
|
||||
keys with the root, targets, and snapshot roles, you can rotate them with:
|
||||
|
||||
```bash
|
||||
$ notary key rotate <dtr_url>/<account>/<repository> <key_role>
|
||||
```
|
||||
|
||||
The Notary CLI client generates a new key for the role you specified, and
|
||||
prompts you for a passphrase to encrypt it.
|
||||
Then you're prompted for the passphrase for the key you're rotating, and if it
|
||||
is correct, the Notary CLI client contacts the Notary server to publish the
|
||||
change.
|
||||
|
||||
You can also rotate keys that are stored in the Notary server, such as the keys
|
||||
with the snapshot or timestamp role. For that, run:
|
||||
|
||||
```bash
|
||||
$ notary key rotate <dtr_url>/<account>/<repository> <key_role> --server-managed
|
||||
```
|
||||
|
||||
## Manage keys for delegation roles
|
||||
|
||||
To delegate image signing to other UCP users, get the `cert.pem` file that's
|
||||
included in their client bundle and run:
|
||||
|
||||
```bash
|
||||
$ notary delegation add -p <dtr_url>/<account>/<repository> targets/<role> --all-paths user1.pem user2.pem
|
||||
```
|
||||
|
||||
You can also remove keys from a delegation role:
|
||||
|
||||
```bash
|
||||
# Remove the given keys from a delegation role
|
||||
$ notary delegation remove -p <dtr_url>/<account>/<repository> targets/<role> <keyID1> <keyID2>
|
||||
|
||||
# Alternatively, you can remove keys from all delegation roles
|
||||
$ notary delegation purge <dtr_url>/<account>/<repository> --key <keyID1> --key <keyID2>
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
Notary CLI has a `-D` flag that you can use to increase the logging level. You
|
||||
can use this for troubleshooting.
|
||||
|
||||
Usually most problems are fixed by ensuring you're communicating with the
|
||||
correct Notary server, using the `-s` flag, and that you're using the correct
|
||||
directory where your private keys are stored, with the `-d` flag.
|
||||
|
||||
## Where to go next
|
||||
|
||||
* [Run only the images you trust](index.md)
|
||||
* [Get started with Notary](/notary/getting_started.md)
|
Loading…
Reference in New Issue