Add content trust docs from UCP 2.0 (#2656)

This commit is contained in:
Jim Galasyn 2017-04-06 14:50:12 -07:00 committed by GitHub
parent fa304dc832
commit cff050336f
4 changed files with 462 additions and 0 deletions

View File

@ -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/

View File

@ -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.

View File

@ -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)

View File

@ -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)