1CONTAINERS-POLICY.JSON(5)(policy.json)  CONTAINERS-POLICY.JSON(5)(policy.json)
2
3
4
5Miloslav Trmač September 2016
6
7

NAME

9       containers-policy.json  -  syntax for the signature verification policy
10       file
11
12

DESCRIPTION

14       Signature verification policy files are used to  specify  policy,  e.g.
15       trusted  keys,  applicable when deciding whether to accept an image, or
16       individual signatures of that image, as valid.
17
18
19       By default,  the  policy  is  read  from  $HOME/.config/containers/pol‐
20       icy.json,  if  it  exists,  otherwise from /etc/containers/policy.json;
21       applications performing verification may allow using a different policy
22       instead.
23
24

FORMAT

26       The  signature  verification  policy  file, usually called policy.json,
27       uses a JSON format.  Unlike some  other  JSON  files,  its  parsing  is
28       fairly  strict:  unrecognized,  duplicated  or otherwise invalid fields
29       cause the  entire  file,  and  usually  the  entire  operation,  to  be
30       rejected.
31
32
33       The  purpose  of  the policy file is to define a set of policy require‐
34       ments for a container image, usually depending on its  location  (where
35       it is being pulled from) or otherwise defined identity.
36
37
38       Policy requirements can be defined for:
39
40
41              · An  individual scope in a transport.  The transport values are
42                the same as the transport prefixes when pushing/pulling images
43                (e.g.  docker:, atomic:), and scope values are defined by each
44                transport; see below for more details.
45
46
47
48       Usually, a scope can be defined to match a single  image,  and  various
49       prefixes of
50         such a most specific scope define namespaces of matching images.  - A
51       default policy for a single transport, expressed using an empty  string
52       as a scope - A global default policy.
53
54
55       If  multiple policy requirements match a given image, only the require‐
56       ments from the most specific  match  apply,  the  more  general  policy
57       requirements definitions are ignored.
58
59
60       This is expressed in JSON using the top-level syntax
61
62
63              {
64                  "default": [/* policy requirements: global default */]
65                  "transports": {
66                      transport_name: {
67                          "": [/* policy requirements: default for transport $transport_name */],
68                          scope_1: [/* policy requirements: default for $scope_1 in $transport_name */],
69                          scope_2: [/*…*/]
70                          /*…*/
71                      },
72                      transport_name_2: {/*…*/}
73                      /*…*/
74                  }
75              }
76
77
78
79       The  global default set of policy requirements is mandatory; all of the
80       other fields (transports itself, any  specific  transport,  the  trans‐
81       port-specific default, etc.) are optional.
82
83

Supported transports and their scopes

85   atomic:
86       The atomic: transport refers to images in an Atomic Registry.
87
88
89       Supported  scopes  use the form hostname[:port][/namespace[/imagestream
90       [:tag]]], i.e. either specifying a complete name of a tagged image,  or
91       prefix denoting a host/namespace/image stream.
92
93
94       Note:  The hostname and port refer to the Docker registry host and port
95       (the one used e.g. for docker pull), not to the OpenShift API host  and
96       port.
97
98
99   dir:
100       The dir: transport refers to images stored in local directories.
101
102
103       Supported  scopes  are paths of directories (either containing a single
104       image or subdirectories possibly containing images).
105
106
107       Note: The paths must be absolute and contain no symlinks. Paths violat‐
108       ing these requirements may be silently ignored.
109
110
111       The  top-level  scope "/" is forbidden; use the transport default scope
112       "", for consistency with other transports.
113
114
115   docker:
116       The docker: transport refers to images in a registry  implementing  the
117       "Docker Registry HTTP API V2".
118
119
120       Scopes  matching  individual  images are named Docker references in the
121       fully expanded form,  either  using  a  tag  or  digest.  For  example,
122       docker.io/library/busybox:latest (not busybox:latest).
123
124
125       More  general scopes are prefixes of individual-image scopes, and spec‐
126       ify a repository (by omitting the tag or digest), a  repository  names‐
127       pace, or a registry host (by only specifying the host name).
128
129
130   oci:
131       The oci: transport refers to images in directories compliant with "Open
132       Container Image Layout Specification".
133
134
135       Supported scopes use the form directory:tag, and directory referring to
136       a  directory containing one or more tags, or any of the parent directo‐
137       ries.
138
139
140       Note: See dir: above for semantics and restrictions  on  the  directory
141       paths, they apply to oci: equivalently.
142
143
144   tarball:
145       The tarball: transport refers to tarred up container root filesystems.
146
147
148       Scopes are ignored.
149
150

Policy Requirements

152       Using  the mechanisms above, a set of policy requirements is looked up.
153       The policy requirements are represented as a JSON array  of  individual
154       requirement  objects.  For an image to be accepted, all of the require‐
155       ments must be satisfied simulatenously.
156
157
158       The policy requirements can also be used to decide whether an  individ‐
159       ual  signature  is accepted (= is signed by a recognized key of a known
160       author); in that case some requirements may apply only to  some  signa‐
161       tures,  but each signature must be accepted by at least one requirement
162       object.
163
164
165       The following requirement objects are supported:
166
167
168   insecureAcceptAnything
169       A simple requirement with the following syntax
170
171
172              {"type":"insecureAcceptAnything"}
173
174
175
176       This requirement accepts any image (but note that other requirements in
177       the array still apply).
178
179
180       When  deciding to accept an individual signature, this requirement does
181       not have any effect; it does not cause the signature  to  be  accepted,
182       though.
183
184
185       This is useful primarily for policy scopes where no signature verifica‐
186       tion is required; because the array of policy requirements must not  be
187       empty,  this  requirement is used to represent the lack of requirements
188       explicitly.
189
190
191   reject
192       A simple requirement with the following syntax:
193
194
195              {"type":"reject"}
196
197
198
199       This requirement rejects every image, and every signature.
200
201
202   signedBy
203       This requirement requires an image to be signed with an expected  iden‐
204       tity,  or  accepts  a signature if it is using an expected identity and
205       key.
206
207
208              {
209                  "type":    "signedBy",
210                  "keyType": "GPGKeys", /* The only currently supported value */
211                  "keyPath": "/path/to/local/keyring/file",
212                  "keyData": "base64-encoded-keyring-data",
213                  "signedIdentity": identity_requirement
214              }
215
216
217
218       Exactly one of keyPath and keyData must be present,  containing  a  GPG
219       keyring of one or more public keys.  Only signatures made by these keys
220       are accepted.
221
222
223       The signedIdentity field, a JSON object, specifies what image  identity
224       the  signature  claims  about the image.  One of the following alterna‐
225       tives are supported:
226
227
228              · The identity in the signature must  exactly  match  the  image
229                identity.  Note that with this, referencing an image by digest
230                (with a signature claiming  a  repository:tag  identity)  will
231                fail.
232
233
234
235                {"type":"matchExact"}
236
237
238
239              · If  the image identity carries a tag, the identity in the sig‐
240                nature must exactly match; if the image identity uses a digest
241                reference,  the  identity in the signature must be in the same
242                repository as the image identity (using any tag).
243
244
245
246       (Note that with images identified using digest references,  the  digest
247       from  the  reference  is  validated  even before signature verification
248       starts.)
249
250
251                {"type":"matchRepoDigestOrExact"}
252
253
254
255              · The identity in the signature must be in the  same  repository
256                as  the  image identity.  This is useful e.g. to pull an image
257                using the :latest tag when the image  is  signed  with  a  tag
258                specifying an exact image version.
259
260
261
262                {"type":"matchRepository"}
263
264
265
266              · The  identity  in the signature must exactly match a specified
267                identity.  This is useful e.g. when locally  mirroring  images
268                signed using their public identity.
269
270
271
272                {
273                    "type": "exactReference",
274                    "dockerReference": docker_reference_value
275                }
276
277
278
279              · The  identity  in the signature must be in the same repository
280                as a specified identity.   This  combines  the  properties  of
281                matchRepository and exactReference.
282
283
284
285                {
286                    "type": "exactRepository",
287                    "dockerRepository": docker_repository_value
288                }
289
290
291
292       If the signedIdentity field is missing, it is treated as matchRepoDige‐
293       stOrExact.
294
295
296       Note: matchExact, matchRepoDigestOrExact  and  matchRepository  can  be
297       only used if a Docker-like image identity is provided by the transport.
298       In particular, the dir: and oci: transports can be only used with exac‐
299       tReference or exactRepository.
300
301

Examples

303       It  is  strongly  recommended  to set the default policy to reject, and
304       then selectively allow individual transports and scopes as desired.
305
306
307   A reasonably locked-down system
308       (Note that the /**/ comments are not valid in JSON, and  must  not  be
309       used in real policies.)
310
311
312              {
313                  "default": [{"type": "reject"}], /* Reject anything not explicitly allowed */
314                  "transports": {
315                      "docker": {
316                          /* Allow installing images from a specific repository namespace, without cryptographic verification.
317                             This namespace includes images like openshift/hello-openshift and openshift/origin. */
318                          "docker.io/openshift": [{"type": "insecureAcceptAnything"}],
319                          /* Similarly, allow installing the “official” busybox images.  Note how the fully expanded
320                             form, with the explicit /library/, must be used. */
321                          "docker.io/library/busybox": [{"type": "insecureAcceptAnything"}]
322                          /* Other docker: images use the global default policy and are rejected */
323                      },
324                      "dir": {
325                          "": [{"type": "insecureAcceptAnything"}] /* Allow any images originating in local directories */
326                      },
327                      "atomic": {
328                          /* The common case: using a known key for a repository or set of repositories */
329                          "hostname:5000/myns/official": [
330                              {
331                                  "type": "signedBy",
332                                  "keyType": "GPGKeys",
333                                  "keyPath": "/path/to/official-pubkey.gpg"
334                              }
335                          ],
336                          /* A more complex example, for a repository which contains a mirror of a third-party product,
337                             which must be signed-off by local IT */
338                          "hostname:5000/vendor/product": [
339                              { /* Require the image to be signed by the original vendor, using the vendor's repository location. */
340                                  "type": "signedBy",
341                                  "keyType": "GPGKeys",
342                                  "keyPath": "/path/to/vendor-pubkey.gpg",
343                                  "signedIdentity": {
344                                      "type": "exactRepository",
345                                      "dockerRepository": "vendor-hostname/product/repository"
346                                  }
347                              },
348                              { /* Require the image to _also_ be signed by a local reviewer. */
349                                  "type": "signedBy",
350                                  "keyType": "GPGKeys",
351                                  "keyPath": "/path/to/reviewer-pubkey.gpg"
352                              }
353                          ]
354                      }
355                  }
356              }
357
358
359
360   Completely disable security, allow all images, do not trust any signatures
361              {
362                  "default": [{"type": "insecureAcceptAnything"}]
363              }
364
365
366

SEE ALSO

368       atomic(1)
369
370

HISTORY

372       August  2018,  Rename to containers-policy.json(5) by Valentin Rothberg
373       vrothberg@suse.com ⟨mailto:vrothberg@suse.com⟩
374
375
376       September 2016, Originally compiled by Miloslav  Trmač  mitr@redhat.com
377       ⟨mailto:mitr@redhat.com⟩
378
379
380
381Page                                  ManCONTAINERS-POLICY.JSON(5)(policy.json)
Impressum