summaryrefslogtreecommitdiff
path: root/devdocs/docker/engine%2Fsecurity%2Ftrust%2Ftrust_delegation%2Findex.html
blob: e219395cd5acec78122952f9ab2575d61d210c77 (plain)
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
<h1>Delegations for content trust</h1>

<p>Delegations in Docker Content Trust (DCT) allow you to control who can and cannot sign an image tag. A delegation will have a pair of private and public delegation keys. A delegation could contain multiple pairs of keys and contributors in order to a) allow multiple users to be part of a delegation, and b) to support key rotation.</p> <p>The most important delegation within Docker Content Trust is <code class="language-plaintext highlighter-rouge">targets/releases</code>. This is seen as the canonical source of a trusted image tag, and without a contributor’s key being under this delegation, they will be unable to sign a tag.</p> <p>Fortunately when using the <code class="language-plaintext highlighter-rouge">$ docker trust</code> commands, we will automatically initialize a repository, manage the repository keys, and add a collaborator’s key to the <code class="language-plaintext highlighter-rouge">targets/releases</code> delegation via <code class="language-plaintext highlighter-rouge">docker trust signer add</code>.</p> <h2 id="configuring-the-docker-client">Configuring the Docker Client</h2> <p>By default, the <code class="language-plaintext highlighter-rouge">$ docker trust</code> commands expect the notary server URL to be the same as the registry URL specified in the image tag (following a similar logic to <code class="language-plaintext highlighter-rouge">$ docker push</code>). When using Docker Hub or DTR, the notary server URL is the same as the registry URL. However, for self-hosted environments or 3rd party registries, you will need to specify an alternative URL for the notary server. This is done with:</p> <div class="highlight"><pre class="highlight" data-language="">$ export DOCKER_CONTENT_TRUST_SERVER=https://&lt;URL&gt;:&lt;PORT&gt;
</pre></div> <p>If you do not export this variable in self-hosted environments, you may see errors such as:</p> <div class="highlight"><pre class="highlight" data-language="">$ docker trust signer add --key cert.pem jeff registry.example.com/admin/demo
Adding signer "jeff" to registry.example.com/admin/demo...
&lt;...&gt;
Error: trust data missing for remote repository registry.example.com/admin/demo or remote repository not found: timestamp key trust data unavailable.  Has a notary repository been initialized?

$ docker trust inspect registry.example.com/admin/demo --pretty
WARN[0000] Error while downloading remote metadata, using cached timestamp - this might not be the latest version available remotely
&lt;...&gt;
</pre></div> <p>If you have enabled authentication for your notary server, or are using DTR, you will need to log in before you can push data to the notary server.</p> <div class="highlight"><pre class="highlight" data-language="">$ docker login registry.example.com/user/repo
Username: admin
Password:

Login Succeeded

$ docker trust signer add --key cert.pem jeff registry.example.com/user/repo
Adding signer "jeff" to registry.example.com/user/repo...
Initializing signed repository for registry.example.com/user/repo...
Successfully initialized "registry.example.com/user/repo"
Successfully added signer: jeff to registry.example.com/user/repo
</pre></div> <p>If you do not log in, you will see:</p> <div class="highlight"><pre class="highlight" data-language="">$ docker trust signer add --key cert.pem jeff registry.example.com/user/repo
Adding signer "jeff" to registry.example.com/user/repo...
Initializing signed repository for registry.example.com/user/repo...
you are not authorized to perform this operation: server returned 401.

Failed to add signer to: registry.example.com/user/repo
</pre></div> <h2 id="configuring-the-notary-client">Configuring the Notary Client</h2> <p>Some of the more advanced features of DCT require the Notary CLI. To install and configure the Notary CLI:</p> <ol> <li> <p>Download the <a href="https://github.com/theupdateframework/notary/releases">client</a> and ensure that it is available on your path.</p> </li> <li> <p>Create a configuration file at <code class="language-plaintext highlighter-rouge">~/.notary/config.json</code> with the following content:</p> </li> </ol> <div class="highlight"><pre class="highlight" data-language="">{
  "trust_dir" : "~/.docker/trust",
  "remote_server": {
    "url": "https://registry.example.com",
    "root_ca": "../.docker/ca.pem"
  }
}
</pre></div> <p>The newly created configuration file contains information about the location of your local Docker trust data and the notary server URL.</p> <p>For more detailed information about how to use notary outside of the Docker Content Trust use cases, refer to the Notary CLI documentation <a href="https://github.com/theupdateframework/notary/blob/master/docs/command_reference/" target="_blank" rel="noopener" class="_">here</a></p> <h2 id="creating-delegation-keys">Creating Delegation Keys</h2> <p>A prerequisite to adding your first contributor is a pair of delegation keys. These keys can either be generated locally using <code class="language-plaintext highlighter-rouge">$ docker trust</code>, generated by a certificate authority.</p> <h3 id="using-docker-trust-to-generate-keys">Using Docker Trust to Generate Keys</h3> <p>Docker trust has a built-in generator for a delegation key pair, <code class="language-plaintext highlighter-rouge">$ docker trust generate &lt;name&gt;</code>. Running this command will automatically load the delegation private key in to the local Docker trust store.</p> <div class="highlight"><pre class="highlight" data-language="">$ docker trust key generate jeff

Generating key for jeff...
Enter passphrase for new jeff key with ID 9deed25: 
Repeat passphrase for new jeff key with ID 9deed25: 
Successfully generated and loaded private key. Corresponding public key available: /home/ubuntu/Documents/mytrustdir/jeff.pub
</pre></div> <h3 id="manually-generating-keys">Manually Generating Keys</h3> <p>If you need to manually generate a private key (either RSA or ECDSA) and a x509 certificate containing the public key, you can use local tools like openssl or cfssl along with a local or company-wide Certificate Authority.</p> <p>Here is an example of how to generate a 2048-bit RSA portion key (all RSA keys must be at least 2048 bits):</p> <div class="highlight"><pre class="highlight" data-language="">$ openssl genrsa -out delegation.key 2048

Generating RSA private key, 2048 bit long modulus
....................................................+++
............+++
e is 65537 (0x10001)
</pre></div> <p>They should keep <code class="language-plaintext highlighter-rouge">delegation.key</code> private because it is used to sign tags.</p> <p>Then they need to generate an x509 certificate containing the public key, which is what you need from them. Here is the command to generate a CSR (certificate signing request):</p> <div class="highlight"><pre class="highlight" data-language="">$ openssl req -new -sha256 -key delegation.key -out delegation.csr
</pre></div> <p>Then they can send it to whichever CA you trust to sign certificates, or they can self-sign the certificate (in this example, creating a certificate that is valid for 1 year):</p> <div class="highlight"><pre class="highlight" data-language="">$ openssl x509 -req -sha256 -days 365 -in delegation.csr -signkey delegation.key -out delegation.crt
</pre></div> <p>Then they need to give you <code class="language-plaintext highlighter-rouge">delegation.crt</code>, whether it is self-signed or signed by a CA.</p> <p>Finally you will need to add the private key into your local Docker trust store.</p> <div class="highlight"><pre class="highlight" data-language="">$ docker trust key load delegation.key --name jeff

Loading key from "delegation.key"...
Enter passphrase for new jeff key with ID 8ae710e: 
Repeat passphrase for new jeff key with ID 8ae710e: 
Successfully imported key from delegation.key
</pre></div> <h3 id="viewing-local-delegation-keys">Viewing local Delegation keys</h3> <p>To list the keys that have been imported in to the local Docker trust store we can use the Notary CLI.</p> <div class="highlight"><pre class="highlight" data-language="">$ notary key list

ROLE       GUN                          KEY ID                                                              LOCATION
----       ---                          ------                                                              --------
root                                    f6c6a4b00fefd8751f86194c7d87a3bede444540eb3378c4a11ce10852ab1f96    /home/ubuntu/.docker/trust/private
jeff                                    9deed251daa1aa6f9d5f9b752847647cf8d705da0763aa5467650d0987ed5306    /home/ubuntu/.docker/trust/private
</pre></div> <h2 id="managing-delegations-in-a-notary-server">Managing Delegations in a Notary Server</h2> <p>When the first Delegation is added to the Notary Server using <code class="language-plaintext highlighter-rouge">$ docker trust</code>, we automatically initiate trust data for the repository. This includes creating the notary target and snapshots keys, and rotating the snapshot key to be managed by the notary server. More information on these keys can be found <a href="../trust_key_mng/index">here</a></p> <p>When initiating a repository, you will need the key and the passphrase of a local Notary Canonical Root Key. If you have not initiated a repository before, and therefore don’t have a Notary root key, <code class="language-plaintext highlighter-rouge">$ docker trust</code> will create one for you.</p> <blockquote> <p>Be sure to protect and back up your <a href="../trust_key_mng/index">Notary Canonical Root Key</a></p> </blockquote> <h3 id="initiating-the-repository">Initiating the Repository</h3> <p>To upload the first key to a delegation, at the same time initiating a repository, you can use the <code class="language-plaintext highlighter-rouge">$ docker trust signer add</code> command. This will add the contributor’s public key to the <code class="language-plaintext highlighter-rouge">targets/releases</code> delegation, and create a second <code class="language-plaintext highlighter-rouge">targets/&lt;name&gt;</code> delegation.</p> <p>For DCT the name of the second delegation, in the below example <code class="language-plaintext highlighter-rouge">jeff</code>, is there to help you keep track of the owner of the keys. In more advanced use cases of Notary additional delegations are used for hierarchy.</p> <div class="highlight"><pre class="highlight" data-language="">$ docker trust signer add --key cert.pem jeff registry.example.com/admin/demo

Adding signer "jeff" to registry.example.com/admin/demo...
Initializing signed repository for registry.example.com/admin/demo...
Enter passphrase for root key with ID f6c6a4b: 
Enter passphrase for new repository key with ID b0014f8: 
Repeat passphrase for new repository key with ID b0014f8: 
Successfully initialized "registry.example.com/admin/demo"
Successfully added signer: jeff to registry.example.com/admin/demo
</pre></div> <p>You can see which keys have been pushed to the Notary server for each repository with the <code class="language-plaintext highlighter-rouge">$ docker trust inspect</code> command.</p> <div class="highlight"><pre class="highlight" data-language="">$ docker trust inspect --pretty registry.example.com/admin/demo

No signatures for registry.example.com/admin/demo


List of signers and their keys for registry.example.com/admin/demo

SIGNER              KEYS
jeff                1091060d7bfd

Administrative keys for registry.example.com/admin/demo

  Repository Key:	b0014f8e4863df2d028095b74efcb05d872c3591de0af06652944e310d96598d
  Root Key:	64d147e59e44870311dd2d80b9f7840039115ef3dfa5008127d769a5f657a5d7
</pre></div> <p>You could also use the Notary CLI to list delegations and keys. Here you can clearly see the keys were attached to <code class="language-plaintext highlighter-rouge">targets/releases</code> and <code class="language-plaintext highlighter-rouge">targets/jeff</code>.</p> <div class="highlight"><pre class="highlight" data-language="">$ notary delegation list registry.example.com/admin/demo

ROLE                PATHS             KEY IDS                                                             THRESHOLD
----                -----             -------                                                             ---------
targets/jeff        "" &lt;all paths&gt;    1091060d7bfd938dfa5be703fa057974f9322a4faef6f580334f3d6df44c02d1    1
                                          
targets/releases    "" &lt;all paths&gt;    1091060d7bfd938dfa5be703fa057974f9322a4faef6f580334f3d6df44c02d1    1 
</pre></div> <h3 id="adding-additional-signers">Adding Additional Signers</h3> <p>Docker Trust allows you to configure multiple delegations per repository, allowing you to manage the lifecycle of delegations. When adding additional delegations with <code class="language-plaintext highlighter-rouge">$ docker trust</code> the collaborators key is once again added to the <code class="language-plaintext highlighter-rouge">targets/release</code> role.</p> <blockquote> <p>Note you will need the passphrase for the repository key; this would have been configured when you first initiated the repository.</p> </blockquote> <div class="highlight"><pre class="highlight" data-language="">$ docker trust signer add --key ben.pub ben registry.example.com/admin/demo

Adding signer "ben" to registry.example.com/admin/demo...
Enter passphrase for repository key with ID b0014f8: 
Successfully added signer: ben to registry.example.com/admin/demo
</pre></div> <p>Check to prove that there are now 2 delegations (Signer).</p> <div class="highlight"><pre class="highlight" data-language="">$ docker trust inspect --pretty registry.example.com/admin/demo

No signatures for registry.example.com/admin/demo

List of signers and their keys for registry.example.com/admin/demo

SIGNER              KEYS
ben                 afa404703b25
jeff                1091060d7bfd

Administrative keys for registry.example.com/admin/demo

  Repository Key:	b0014f8e4863df2d028095b74efcb05d872c3591de0af06652944e310d96598d
  Root Key:	64d147e59e44870311dd2d80b9f7840039115ef3dfa5008127d769a5f657a5d7
</pre></div> <h3 id="adding-keys-to-an-existing-delegation">Adding Keys to an Existing Delegation</h3> <p>To support things like key rotation and expiring / retiring keys you can publish multiple contributor keys per delegation. The only prerequisite here is to make sure you use the same the delegation name, in this case <code class="language-plaintext highlighter-rouge">jeff</code>. Docker trust will automatically handle adding this new key to <code class="language-plaintext highlighter-rouge">targets/releases</code>.</p> <blockquote> <p>Note you will need the passphrase for the repository key; this would have been configured when you first initiated the repository.</p> </blockquote> <div class="highlight"><pre class="highlight" data-language="">$ docker trust signer add --key cert2.pem jeff registry.example.com/admin/demo

Adding signer "jeff" to registry.example.com/admin/demo...
Enter passphrase for repository key with ID b0014f8: 
Successfully added signer: jeff to registry.example.com/admin/demo
</pre></div> <p>Check to prove that the delegation (Signer) now contains multiple Key IDs.</p> <div class="highlight"><pre class="highlight" data-language="">$ docker trust inspect --pretty registry.example.com/admin/demo

No signatures for registry.example.com/admin/demo


List of signers and their keys for registry.example.com/admin/demo

SIGNER              KEYS
jeff                1091060d7bfd, 5570b88df073

Administrative keys for registry.example.com/admin/demo

  Repository Key:	b0014f8e4863df2d028095b74efcb05d872c3591de0af06652944e310d96598d
  Root Key:	64d147e59e44870311dd2d80b9f7840039115ef3dfa5008127d769a5f657a5d7
</pre></div> <h3 id="removing-a-delegation">Removing a Delegation</h3> <p>If you need to remove a delegation, including the contributor keys that are attached to the <code class="language-plaintext highlighter-rouge">targets/releases</code> role, you can use the <code class="language-plaintext highlighter-rouge">$ docker trust signer remove</code> command.</p> <blockquote> <p>Note tags that were signed by the removed delegation will need to be resigned by an active delegation</p> </blockquote> <div class="highlight"><pre class="highlight" data-language="">$ docker trust signer remove registry.example.com/admin/demo
Removing signer "ben" from registry.example.com/admin/demo...
Enter passphrase for repository key with ID b0014f8: 
Successfully removed ben from registry.example.com/admin/demo
</pre></div> <h4 id="troubleshooting">Troubleshooting</h4> <p>1) If you see an error that there are no usable keys in <code class="language-plaintext highlighter-rouge">targets/releases</code>, you will need to add additional delegations using <code class="language-plaintext highlighter-rouge">docker trust signer add</code> before resigning images.</p> <div class="highlight"><pre class="highlight" data-language="">WARN[0000] role targets/releases has fewer keys than its threshold of 1; it will not be usable until keys are added to it
</pre></div> <p>2) If you have added additional delegations already and are seeing an error message that there are no valid signatures in <code class="language-plaintext highlighter-rouge">targest/releases</code>, you will need to resign the <code class="language-plaintext highlighter-rouge">targets/releases</code> delegation file with the Notary CLI.</p> <div class="highlight"><pre class="highlight" data-language="">WARN[0000] Error getting targets/releases: valid signatures did not meet threshold for targets/releases 
</pre></div> <p>Resigning the delegation file is done with the <code class="language-plaintext highlighter-rouge">$ notary witness</code> command</p> <div class="highlight"><pre class="highlight" data-language="">$ notary witness registry.example.com/admin/demo targets/releases --publish
</pre></div> <p>More information on the <code class="language-plaintext highlighter-rouge">$ notary witness</code> command can be found <a href="https://github.com/theupdateframework/notary/blob/master/docs/advanced_usage/#recovering-a-delegation" target="_blank" rel="noopener" class="_">here</a></p> <h3 id="removing-a-contributors-key-from-a-delegation">Removing a Contributor’s Key from a Delegation</h3> <p>As part of rotating keys for a delegation, you may want to remove an individual key but retain the delegation. This can be done with the Notary CLI.</p> <p>Remember you will have to remove the key from both the <code class="language-plaintext highlighter-rouge">targets/releases</code> role and the role specific to that signer <code class="language-plaintext highlighter-rouge">targets/&lt;name&gt;</code>.</p> <p>1) We will need to grab the Key ID from the Notary Server</p> <div class="highlight"><pre class="highlight" data-language="">$ notary delegation list registry.example.com/admin/demo

ROLE                PATHS             KEY IDS                                                             THRESHOLD
----                -----             -------                                                             ---------
targets/jeff        "" &lt;all paths&gt;    8fb597cbaf196f0781628b2f52bff6b3912e4e8075720378fda60d17232bbcf9    1
                                      1091060d7bfd938dfa5be703fa057974f9322a4faef6f580334f3d6df44c02d1    
targets/releases    "" &lt;all paths&gt;    8fb597cbaf196f0781628b2f52bff6b3912e4e8075720378fda60d17232bbcf9    1
                                      1091060d7bfd938dfa5be703fa057974f9322a4faef6f580334f3d6df44c02d1    
</pre></div> <p>2) Remove from the <code class="language-plaintext highlighter-rouge">targets/releases</code> delegation</p> <div class="highlight"><pre class="highlight" data-language="">$ notary delegation remove registry.example.com/admin/demo targets/releases 1091060d7bfd938dfa5be703fa057974f9322a4faef6f580334f3d6df44c02d1 --publish

Auto-publishing changes to registry.example.com/admin/demo
Enter username: admin
Enter password: 
Enter passphrase for targets key with ID b0014f8: 
Successfully published changes for repository registry.example.com/admin/demo
</pre></div> <p>3) Remove from the <code class="language-plaintext highlighter-rouge">targets/&lt;name&gt;</code> delegation</p> <div class="highlight"><pre class="highlight" data-language="">$ notary delegation remove registry.example.com/admin/demo targets/jeff 1091060d7bfd938dfa5be703fa057974f9322a4faef6f580334f3d6df44c02d1 --publish

Removal of delegation role targets/jeff with keys [5570b88df0736c468493247a07e235e35cf3641270c944d0e9e8899922fc6f99], to repository "registry.example.com/admin/demo" staged for next publish.

Auto-publishing changes to registry.example.com/admin/demo
Enter username: admin    
Enter password: 
Enter passphrase for targets key with ID b0014f8: 
Successfully published changes for repository registry.example.com/admin/demo
</pre></div> <p>4) Check the remaining delegation list</p> <div class="highlight"><pre class="highlight" data-language="">$ notary delegation list registry.example.com/admin/demo

ROLE                PATHS             KEY IDS                                                             THRESHOLD
----                -----             -------                                                             ---------
targets/jeff        "" &lt;all paths&gt;    8fb597cbaf196f0781628b2f52bff6b3912e4e8075720378fda60d17232bbcf9    1    
targets/releases    "" &lt;all paths&gt;    8fb597cbaf196f0781628b2f52bff6b3912e4e8075720378fda60d17232bbcf9    1    
</pre></div> <h3 id="removing-a-local-delegation-private-key">Removing a local Delegation Private Key</h3> <p>As part of rotating delegation keys, you may need to remove a local delegation key from the local Docker trust store. This is done with the Notary CLI, using the <code class="language-plaintext highlighter-rouge">$ notary key remove</code> command.</p> <p>1) We will need to get the Key ID from the local Docker Trust store</p> <div class="highlight"><pre class="highlight" data-language="">$ notary key list

ROLE       GUN                          KEY ID                                                              LOCATION
----       ---                          ------                                                              --------
root                                    f6c6a4b00fefd8751f86194c7d87a3bede444540eb3378c4a11ce10852ab1f96    /home/ubuntu/.docker/trust/private
admin                                   8fb597cbaf196f0781628b2f52bff6b3912e4e8075720378fda60d17232bbcf9    /home/ubuntu/.docker/trust/private
jeff                                    1091060d7bfd938dfa5be703fa057974f9322a4faef6f580334f3d6df44c02d1    /home/ubuntu/.docker/trust/private
targets    ...example.com/admin/demo    c819f2eda8fba2810ec6a7f95f051c90276c87fddfc3039058856fad061c009d    /home/ubuntu/.docker/trust/private
</pre></div> <p>2) Remove the key from the local Docker Trust store</p> <div class="highlight"><pre class="highlight" data-language="">$ notary key remove 1091060d7bfd938dfa5be703fa057974f9322a4faef6f580334f3d6df44c02d1

Are you sure you want to remove 1091060d7bfd938dfa5be703fa057974f9322a4faef6f580334f3d6df44c02d1 (role jeff) from /home/ubuntu/.docker/trust/private?  (yes/no)  y

Deleted 1091060d7bfd938dfa5be703fa057974f9322a4faef6f580334f3d6df44c02d1 (role jeff) from /home/ubuntu/.docker/trust/private.
</pre></div> <h2 id="removing-all-trust-data-from-a-repository">Removing all trust data from a Repository</h2> <p>You can remove all trust data from a repository, including repository, target, snapshot and all delegations keys using the Notary CLI.</p> <p>This is often required by a container registry before a particular repository can be deleted.</p> <div class="highlight"><pre class="highlight" data-language="">$ notary delete registry.example.com/admin/demo --remote

Deleting trust data for repository registry.example.com/admin/demo
Enter username: admin
Enter password: 
Successfully deleted local and remote trust data for repository registry.example.com/admin/demo

$ docker trust inspect --pretty registry.example.com/admin/demo

No signatures or cannot access registry.example.com/admin/demo
</pre></div> <h2 id="related-information">Related information</h2> <ul> <li><a href="../index">Content trust in Docker</a></li> <li><a href="../trust_key_mng/index">Manage keys for content trust</a></li> <li><a href="../trust_automation/index">Automation with content trust</a></li> <li><a href="../trust_sandbox/index">Play in a content trust sandbox</a></li> </ul> 
<p><a href="https://docs.docker.com/search/?q=trust">trust</a>, <a href="https://docs.docker.com/search/?q=security">security</a>, <a href="https://docs.docker.com/search/?q=delegations">delegations</a>, <a href="https://docs.docker.com/search/?q=keys">keys</a>, <a href="https://docs.docker.com/search/?q=repository">repository</a></p>
<div class="_attribution">
  <p class="_attribution-p">
    &copy; 2019 Docker, Inc.<br>Licensed under the Apache License, Version 2.0.<br>Docker and the Docker logo are trademarks or registered trademarks of Docker, Inc. in the United States and/or other countries.<br>Docker, Inc. and other parties may also have trademark rights in other terms used herein.<br>
    <a href="https://docs.docker.com/engine/security/trust/trust_delegation/" class="_attribution-link">https://docs.docker.com/engine/security/trust/trust_delegation/</a>
  </p>
</div>