File: advanced_usage.md

package info (click to toggle)
notary 0.6.1~ds1-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 4,692 kB
  • sloc: python: 1,112; sh: 481; makefile: 181; sql: 155
file content (283 lines) | stat: -rw-r--r-- 14,827 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
<!--[metadata]>
+++
title = "Use the Notary client"
description = "Becoming a power user of the notary client."
keywords = ["docker, notary, notary-client, docker content trust, content trust, power user, advanced"]
[menu.main]
parent="mn_notary"
weight=2
+++
<![end-metadata]-->

# Use the Notary client for advanced users

This page explains advanced uses of Notary client for users who are running
their own Notary service. Make sure you have first read and understood how to
[run your own Notary service](running_a_service.md) before continuing.

#### An important note about the examples

This document's command examples omit the `-s` and `-d` flags. If you do not
know what these options do, please read the [Getting
Started](getting_started.md) docs or run `notary --help` before continuing. Once
you understand what these flags do, you must provide your own values for these
options while following this document. You can also configure these options, see
[advanced configuration options](reference/index.md) for more information.

## Initialize a Trusted Collection</a>

Before adding and signing content to a collection, you must first initialize that collection.

```
$ notary init example.com/collection

No root keys found. Generating a new root key...
You are about to create a new root signing key passphrase. This passphrase
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.
Enter passphrase for new root key with ID 1f54328:
Repeat passphrase for new root key with ID 1f54328:
Enter passphrase for new targets key with ID 1df39fc (example.com/collection):
Repeat passphrase for new targets key with ID 1df39fc (example.com/collection):
```

Initializing a trusted collection will generate the following items; all keys use
asymmetric algorithms, but there is no requirement that they all use the _same_
algorithm:

- If no root key is found, an initial root key will be generated. This key will be used as the default root of trust for all your trusted collections.
- A targets key and a snapshot key. The same password is used to encrypt both of these as the security profile of them (when both held by the author of the trusted collection) is identical. This is why you will not be asked for a snapshot key password.
- A timestamp key. This is generated by the server on a request from the client, returning just the public key. The server holds the private key and will sign timestamps on behalf of the user.
- Stub signed notary metadata. This stages the base version of the trust metadata for the collection. It will be finalized when it is published to the server.

## Add and remove Targets

It's simple to add targets to a trusted collection with notary CLI:
```
$ notary add example.com/collection v1 my_file.txt
```

The above command adds the local file `my_file.txt` (this file must exist relative to the current working directory) under the target name `v1` to the `example.com/collection` collection we set up. The contents of the local file are not actually added to the collection - a "target" consists of the
file path and one or more checksums of the contents.

Note that this is an offline command, and we must run a `notary publish example.com/collection` for the add to take effect.

To remove targets, we use the `notary remove` command, specifying the GUN and target name.
```
$ notary remove example.com/collection v1
```

Removing a target is also an offline command that requires a `notary publish example.com/collection` to take effect.

## Manage keys

By default, the notary client is responsible for managing the private keys for
root, targets, snapshot roles. All of these keys are generated by default when
initializing a new trusted collection. The keys are located in the notary `trust_dir`
directory. In addition, if delegation roles exist, those roles' keys are to also
managed by the notary client.

The notary server is always responsible for managing the timestamp key. However,
it is possible for the notary server to manage the snapshot key, if the snapshot
key is rotated from the notary client to server, as described in the following
subsection.

### Rotate keys

In case of potential compromise, notary provides a CLI command for rotating keys. Currently, you can use the `notary key rotate` command to rotate the root, targets, snapshot, or timestamp keys.

While the snapshot key is managed by the notary client by default, use the `notary key
rotate snapshot -r` command to rotate the snapshot key to the server, such that the
notary server will then sign snapshots. This is particularly useful when using
delegations with a trusted collection, so that delegates will never need access to the
snapshot key to push their updates to the collection.

Note that new collections created by a Docker 1.11 Engine client will have the server manage the snapshot key by default.
To reclaim control of the snapshot key on the client, use the `notary key rotate` command without the `-r` flag.

The root and targets key must be locally managed - to rotate either the root or targets key, for instance in case of compromise, use the `notary key rotate` command without the `-r` flag.
The timestamp key must be remotely managed - to rotate the timestamp key use the `notary key rotate <GUN> timestamp -r` command.

### Use a Yubikey

Notary can be used with
<a href="https://www.yubico.com/products/yubikey-hardware/yubikey4/" target="_blank">Yubikey
4</a> keys, via a PKCS11 interface when the Yubikey has CCID mode enabled.
The Yubikey will be prioritized to store root keys, and will require user touch-input for signing.
Note that Yubikey support is included with the Docker Engine 1.11 client for use with Docker Content Trust.

Yubikey support requires
<a href="https://www.yubico.com/support/downloads" target="_blank">Yubico PIV libraries
(which are bundled with the PIV tools)</a> to be available in standard
library locations.

## Work with delegation roles

Delegation roles simplify collaborator workflows in notary trusted collections, and
also allow for fine-grained permissions within a collection's contents across
delegations. In essence, delegation roles are restricted versions of the targets
role that are only allowed to sign targets within certain filepaths.

A delegation role is given its own keys, such that each collaborator can keep
his own private key without the administrator having to share the
targets key or allow a collaborator write access to all targets of the
collection.

Before adding any delegations, you should rotate the snapshot key to the server.
Note that this is done by default for new collections created with a Docker Engine 1.11 client.
This is such that delegation roles will not require the snapshot key to publish
their own targets to the collection, since the server can publish the valid
snapshot with the delegation targets:

```
$ notary key rotate example.com/collection snapshot -r
```

Here, `-r` specifies to rotate the key to the remote server.

When adding a delegation, your must acquire a x509 certificate with the public
key of the user you wish to delegate to. The user who will assume this
delegation role must hold the private key to sign content with notary.

Once you've acquired the delegate's x509 certificate, you can add a delegation
for this user:

```
$ notary delegation add example.com/collection targets/releases cert.pem --paths="delegation/path"
```

The preceding example illustrates a request to add the delegation
`targets/releases` to the GUN `example.com/collection`. The delegation name must
be prefixed by `targets/` to be valid, since all delegations are restricted
versions of the target role. The command adds the public key contained in the
x509 cert `cert.pem` to the `targets/releases` delegation.

For the `targets/releases` delegation role to sign content, the delegation user
must possess the private key corresponding to this public key. This command
restricts this delegation to only publish content under pathnames prefixed by
`delegation/path`. With the given path of "delegation/path", the `targets/releases`
role would be able to sign paths like "delegation/path/content.txt", "delegation/path_file.txt"
and "delegation/path.txt". You can add more paths in a comma-separated list under
`--paths`, or pass the `--all-paths` flag to allow this delegation to publish
content under any pathname.

After publishing, you can view delegations using a list command:

```
$ notary delegation list example.com/collection

      ROLE               PATHS                                   KEY IDS                                THRESHOLD
---------------------------------------------------------------------------------------------------------------
  targets/releases   delegation/path   729c7094a8210fd1e780e7b17b7bb55c9a28a48b871b07f65d97baf93898523a   1
```

You can see the `targets/releases` with its paths and key IDs. If you wish to modify these fields, you can do so with additional `notary delegation add` or `notary delegation remove` commands on this role.

A threshold of `1` indicates that only one of the keys specified in `KEY IDS` is required to publish to this delegation. Thresholds other than 1 are not currently supported. To remove a delegation role entirely, or just individual keys and/or paths, use the `notary delegation remove` command:

```
$ notary delegation remove example.com/user targets/releases

Are you sure you want to remove all data for this delegation? (yes/no)
yes

Forced removal (including all keys and paths) of delegation role targets/releases to repository "example.com/user" staged for next publish.
```

You can remove individual keys and/or paths by passing keys as arguments, and/or
paths under the `--paths` flag. Use `--all-paths` to clear all paths for this
role. If you specify all key IDs currently in the delegation role, you will be left
with a role that is unusable as it will not have enough valid signatures (see the
next section for details on how to recover such a role).

To add targets to a specified delegation role, we can use the `notary add`
command with the `--roles` flag.

You must have imported an appropriate delegation key for this role. To do so,
you can run `notary key import <KEY_FILE> --role user` with the private key PEM
file, or drop the private key PEM in `private/tuf_keys` as `<KEY_ID>.key` with
the `role` PEM header set to `user`.

```
$ notary add example/collections delegation/path/target delegation_file.txt --roles=targets/releases
```

In the preceding example, you add the target `delegation/path/target` to
collection `example/collections` staged for next publish. The file
`delegation_file.txt` is a target `delegation/path/target` using the delegation
role `targets/releases`. This target's path is valid because it is prefixed by
the delegation role's valid path.

The `notary list` and `notary remove` commands can also take the `--roles` flag
to specify roles to list or remove targets from. By default, this operates over
the base `targets` role.

To remove this target from our delegation, use the `notary remove` command with
the same flag:

```
$ notary remove example/collections delegation/path/target --roles=targets/releases
```

## Recovering a delegation

It is possible for delegations to get into a state where they delegation file is not
signed by any currently valid keys. This will typically happen when the key that has 
signed the latest version of the delegation file is removed from the list of valid keys
for the role. Even when a new valid key is added to the delegation
role, clients will refuse to pull the existing file due to signature verification failure.
However the existence of the delegation file will cause the server to reject a new delegation
file set to version `0`. 

The `notary witness` command (added in notary v0.4.0) adds signatures to an existing 
invalid delegation file to make it valid again. The holder of any key that is valid for 
the delegation must `witness` the role to sign it with their key.

IMPORTANT: all existing targets in the role being witnessed are preserved. It is up to the 
new signer to keep or remove existing content once they have claimed it.

```
$ notary witness example/collections targets/releases
The following roles were successfully marked for witnessing on the next publish:
	- targets/releases
```

## Use delegations with content trust

Docker Engine 1.10 and above supports the usage of the `targets/releases`
delegation as the canonical source of a trusted image tag, if it exists.

When running `docker pull` with Docker Content Trust on Docker Engine 1.10,
Docker will attempt to search the `targets/releases` role for the signed image tag,
and will fall back to the default `targets` role if it does not exist. Please note
that when searching the default `targets` role, Docker 1.10 may pick up on other
non-`targets/releases` delegation roles' signed images if they exist for this tag.
In Docker 1.11, this behavior is changed such that all `docker pull` commands with
Docker Content Trust must pull tags only signed by the `targets/releases` delegation role
or the `targets` base role.

When running `docker push` with Docker Content Trust, Docker Engine 1.10 will
attempt to sign and push with the `targets/releases` delegation role if it exists,
otherwise falling back to the `targets` role. In Docker 1.11, a `docker push` will
instead attempt to sign and push with all delegation roles directly under targets
(ex: `targets/role` but not `targets/nested/role`) that the user has signing keys for.
If delegation roles exist but the user does not have signing keys, the push will fail.
If no delegation roles exist, the push will attempt to sign with the base `targets` role.

To use the `targets/releases` role for pushing and pulling images with content trust,
follow the steps above to add and publish the delegation role with notary.
When adding the delegation, the `--all-paths` flag should be used to allow signing all tags.

# Files and state on disk

Notary stores state in its `trust_dir` directory, which is `~/.notary` by
default or usually `~/.docker/trust` when enabling docker content trust. Within this
directory, `trusted_certificates` stores certificates for bootstrapping trust in
a collection, `tuf` stores TUF metadata and changelists to be applied to a GUN,
and `private` stores private keys.

The `root_keys` subdirectory within `private` stores root private keys, while
`tuf_keys` stores targets, snapshots, and delegations private keys.