1container-signature(5)              format              container-signature(5)
2
3
4
5Miloslav Trmač March 2017
6
7

NAME

9       container-signature - Container signature format
10
11
12

DESCRIPTION

14       This  document  describes the format of container signatures, as imple‐
15       mented by the github.com/containers/image/signature package.
16
17
18       Most users should be able to consume  these  signatures  by  using  the
19       github.com/containers/image/signature  package  (preferably through the
20       higher-level signature.PolicyContext interface) without having to  care
21       about  the  details  of the format described below.  This documentation
22       exists primarily for maintainers of the package and to  allow  indepen‐
23       dent reimplementations.
24
25

High-level overview

27       The  signature  provides  an end-to-end authenticated claim that a con‐
28       tainer image has been approved by a specific party (e.g. the creator of
29       the  image  as  their work, an automated build system as a result of an
30       automated build, a company IT department approving the image  for  pro‐
31       duction)  under  a specified identity (e.g. an OS base image / specific
32       application, with a specific version).
33
34
35       A container signature consists of a cryptographic signature which iden‐
36       tifies  and authenticates who signed the image, and carries as a signed
37       payload a JSON document.  The JSON document identifies the image  being
38       signed, claims a specific identity of the image and if applicable, con‐
39       tains other information about the image.
40
41
42       The signatures do not modify the container image (the layers,  configu‐
43       ration,  manifest, …); e.g. their presence does not change the manifest
44       digest used to  identify  the  image  in  docker/distribution  servers;
45       rather,  the signatures are associated with an immutable image.  An im‐
46       age can have any number of signatures so signature distribution systems
47       SHOULD support associating more than one signature with an image.
48
49

The cryptographic signature

51       As  distributed,  the  container  signature  is a blob which contains a
52       cryptographic signature in  an  industry-standard  format,  carrying  a
53       signed  JSON payload (i.e. the blob contains both the JSON document and
54       a signature of the JSON document; it is not a “detached signature” with
55       independent blobs containing the JSON document and a cryptographic sig‐
56       nature).
57
58
59       Currently the only defined cryptographic signature format is an OpenPGP
60       signature (RFC 4880), but others may be added in the future.  (The blob
61       does not contain metadata identifying the cryptographic signature  for‐
62       mat.  It is expected that most formats are sufficiently self-describing
63       that this is not necessary and the configured expected public key  pro‐
64       vides  another  indication of the expected cryptographic signature for‐
65       mat. Such metadata may be added in the future for newly  added  crypto‐
66       graphic signature formats, if necessary.)
67
68
69       Consumers  of container signatures SHOULD verify the cryptographic sig‐
70       nature against one or more trusted public keys (e.g. defined in a  pol‐
71       icy.json    signature   verification   policy   file   ⟨containers-pol‐
72       icy.json.5.md⟩) before parsing or processing the JSON  payload  in  any
73       way,  in particular they SHOULD stop processing the container signature
74       if the cryptographic signature verification fails, without even  start‐
75       ing to process the JSON payload.
76
77
78       (Consumers  MAY  extract  identification  of  the signing key and other
79       metadata from the cryptographic signature, and the JSON payload,  with‐
80       out  verifying  the  signature, if the purpose is to allow managing the
81       signature blobs, e.g. to list the authors and image identities of  sig‐
82       natures  associated  with  a single container image; if so, they SHOULD
83       design the output of such processing to minimize the risk of users con‐
84       sidering  the output trusted or in any way usable for making policy de‐
85       cisions about the image.)
86
87
88   OpenPGP signature verification
89       When verifying a cryptographic signature in  the  OpenPGP  format,  the
90       consumer  MUST  verify  at least the following aspects of the signature
91       (like the github.com/containers/image/signature package does):
92
93
94              • The blob MUST be a “Signed Message” as defined RFC  4880  sec‐
95                tion  11.3.   (e.g.  it  MUST NOT be an unsigned “Literal Mes‐
96                sage”, a “Cleartext Signature” as defined in RFC 4880  section
97                7, or any other non-signature format).
98
99              • The  signature  MUST have been made by an expected key trusted
100                for the purpose (and the specific container image).
101
102              • The signature MUST be correctly formed and  pass  the  crypto‐
103                graphic validation.
104
105              • The  signature  MUST  correctly authenticate the included JSON
106                payload (in particular, the parsing of the JSON  payload  MUST
107                NOT  start  before the complete payload has been cryptographi‐
108                cally authenticated).
109
110              • The signature MUST NOT be expired.
111
112
113
114       The consumer SHOULD have tests for its verification code  which  verify
115       that signatures failing any of the above are rejected.
116
117

JSON processing and forward compatibility

119       The  payload  of  the  cryptographic  signature is a JSON document (RFC
120       7159).  Consumers SHOULD parse it very strictly, refusing any signature
121       which  violates  the  expected  format (e.g. missing members, incorrect
122       member types) or can be interpreted ambiguously (e.g. a duplicated mem‐
123       ber in a JSON object).
124
125
126       Any violations of the JSON format or of other requirements in this doc‐
127       ument MAY be accepted if the JSON document can be  recognized  to  have
128       been  created by a known-incorrect implementation (see optional.creator
129       ⟨#optionalcreator⟩ below) and if the semantics of the invalid document,
130       as created by such an implementation, is clear.
131
132
133       The top-level value of the JSON document MUST be a JSON object with ex‐
134       actly two members, critical and optional, each a JSON object.
135
136
137       The critical object MUST contain a type member identifying the document
138       as  a container signature (as defined below ⟨#criticaltype⟩) and signa‐
139       ture consumers MUST reject signatures which do not have this member  or
140       in which this member does not have the expected value.
141
142
143       To  ensure forward compatibility (allowing older signature consumers to
144       correctly accept or reject signatures created at  a  later  date,  with
145       possible  extensions  to this format), consumers MUST reject the signa‐
146       ture if the critical object, or any of its subobjects, contain any mem‐
147       ber  or  data  value which is unrecognized, unsupported, invalid, or in
148       any other way unexpected.  At a  minimum,  this  includes  unrecognized
149       members in a JSON object, or incorrect types of expected members.
150
151
152       For  the same reason, consumers SHOULD accept any members with unrecog‐
153       nized names in the optional object, and MAY accept signatures where the
154       object member is recognized but unsupported, or the value of the member
155       is unsupported.  Consumers still SHOULD reject signatures where a  mem‐
156       ber  of  an optional object is supported but the value is recognized as
157       invalid.
158
159

JSON data format

161       An example of the full format follows, with detailed description below.
162       To  reiterate,  consumers  of  the  signature SHOULD perform successful
163       cryptographic verification, and MUST  reject  unexpected  data  in  the
164       critical object, or in the top-level object, as described above.
165
166
167              {
168                  "critical": {
169                      "type": "atomic container signature",
170                      "image": {
171                          "docker-manifest-digest": "sha256:817a12c32a39bbe394944ba49de563e085f1d3c5266eb8e9723256bc4448680e"
172                      },
173                      "identity": {
174                          "docker-reference": "docker.io/library/busybox:latest"
175                      }
176                  },
177                  "optional": {
178                      "creator": "some software package v1.0.1-35",
179                      "timestamp": 1483228800,
180                  }
181              }
182
183
184
185   critical
186       This  MUST  be  a JSON object which contains data critical to correctly
187       evaluating the validity of a signature.
188
189
190       Consumers MUST reject any signature where the critical object  contains
191       any  unrecognized,  unsupported, invalid or in any other way unexpected
192       member or data.
193
194
195   critical.type
196       This MUST be a string with a string value exactly equal to atomic  con‐
197       tainer signature (three words, including the spaces).
198
199
200       Signature  consumers MUST reject signatures which do not have this mem‐
201       ber or this member does not have exactly the expected value.
202
203
204       (The consumers MAY support signatures with a  different  value  of  the
205       type  member,  if  any is defined in the future; if so, the rest of the
206       JSON document is interpreted according to rules defining that value  of
207       critical.type, not by this document.)
208
209
210   critical.image
211       This  MUST  be  a JSON object which identifies the container image this
212       signature applies to.
213
214
215       Consumers MUST reject any signature  where  the  critical.image  object
216       contains any unrecognized, unsupported, invalid or in any other way un‐
217       expected member or data.
218
219
220       (Currently only the docker-manifest-digest way of  identifying  a  con‐
221       tainer image is defined; alternatives to this may be defined in the fu‐
222       ture, but existing consumers are required to  reject  signatures  which
223       use formats they do not support.)
224
225
226   critical.image.docker-manifest-digest
227       This  MUST  be  a  JSON string, in the github.com/opencontainers/go-di‐
228       gest.Digest string format.
229
230
231       The value of this member MUST match the manifest  of  the  signed  con‐
232       tainer  image,  as  implemented in the docker/distribution manifest ad‐
233       dressing system.
234
235
236       The consumer of the signature SHOULD verify the manifest digest against
237       a  fully verified signature before processing the contents of the image
238       manifest in any other way (e.g. parsing the manifest further  or  down‐
239       loading layers of the image).
240
241
242       Implementation notes: * A single container image manifest may have sev‐
243       eral valid manifest digest values, using different algorithms.   *  For
244       “signed”  docker/distribution  schema 1 ⟨https://github.com/docker/dis
245       tribution/blob/master/docs/spec/manifest-v2-1.md⟩ manifests, the  mani‐
246       fest  digest  applies  to the payload of the JSON web signature, not to
247       the raw manifest blob.
248
249
250   critical.identity
251       This MUST be a JSON object which identifies the claimed identity of the
252       image (usually the purpose of the image, or the application, along with
253       a version information), as asserted by the author of the signature.
254
255
256       Consumers MUST reject any signature where the critical.identity  object
257       contains any unrecognized, unsupported, invalid or in any other way un‐
258       expected member or data.
259
260
261       (Currently only the docker-reference way of  claiming  an  image  iden‐
262       tity/purpose is defined; alternatives to this may be defined in the fu‐
263       ture, but existing consumers are required to  reject  signatures  which
264       use formats they do not support.)
265
266
267   critical.identity.docker-reference
268       This  MUST be a JSON string, in the github.com/docker/distribution/ref‐
269       erence string format, and using the same normalization semantics (where
270       e.g. busybox:latest is equivalent to docker.io/library/busybox:latest).
271       If the normalization semantics allows multiple  string  representations
272       of  the  claimed  identity  with equivalent meaning, the critical.iden‐
273       tity.docker-reference member SHOULD use the fully  explicit  form  (in‐
274       cluding the full host name and namespaces).
275
276
277       The value of this member MUST match the image identity/purpose expected
278       by the consumer of the image signature and the image (again, accounting
279       for the docker/distribution/reference normalization semantics).
280
281
282       In  the most common case, this means that the critical.identity.docker-
283       reference value must be equal to the docker/distribution reference used
284       to  refer to or download the image.  However, depending on the specific
285       application, users or system administrators may  accept  less  specific
286       matches  (e.g. ignoring the tag value in the signature when pulling the
287       :latest tag or when referencing an image by digest), or  they  may  re‐
288       quire  critical.identity.docker-reference values with a completely dif‐
289       ferent namespace to the reference used to refer to/download  the  image
290       (e.g.  requiring a critical.identity.docker-reference value which iden‐
291       tifies the image as coming from a supplier when fetching it from a com‐
292       pany-internal mirror of approved images).  The software performing this
293       verification SHOULD allow the users to define such a policy  using  the
294       policy.json  signature verification policy file format ⟨containers-pol‐
295       icy.json.5.md⟩.
296
297
298       The critical.identity.docker-reference value SHOULD  contain  either  a
299       tag or digest; in most cases, it SHOULD use a tag rather than a digest.
300       (See also the default matchRepoDigestOrExact matching semantics in pol‐
301       icy.json ⟨containers-policy.json.5.md#signedby⟩.)
302
303
304   optional
305       This MUST be a JSON object.
306
307
308       Consumers  SHOULD accept any members with unrecognized names in the op‐
309       tional object, and MAY accept a signature where the  object  member  is
310       recognized but unsupported, or the value of the member is valid but un‐
311       supported.  Consumers still SHOULD reject any signature where a  member
312       of  an  optional object is supported but the value is recognized as in‐
313       valid.
314
315
316   optional.creator
317       If present, this MUST be a JSON string, identifying the name  and  ver‐
318       sion  of  the software which has created the signature (identifying the
319       low-level software implementation; not the top-level caller).
320
321
322       The contents of this string is not defined in detail; however each  im‐
323       plementation creating container signatures:
324
325
326              • SHOULD  define  the contents to unambiguously define the soft‐
327                ware in practice (e.g. it SHOULD contain the name of the soft‐
328                ware, not only the version number)
329
330              • SHOULD  use  a build and versioning process which ensures that
331                the contents of this string (e.g. an included version  number)
332                changes whenever the format or semantics of the generated sig‐
333                nature changes in any way; it SHOULD not be possible  for  two
334                implementations  which  use a different format or semantics to
335                have the same optional.creator value
336
337              • SHOULD use a format which is reasonably easy to parse in soft‐
338                ware  (perhaps using a regexp), and which makes it easy enough
339                to recognize a range of versions of a specific  implementation
340                (e.g.  the  version of the implementation SHOULD NOT be only a
341                git hash, because they don’t have an easily defined  ordering;
342                the string should contain a version number, or at least a date
343                of the commit).
344
345
346
347       Consumers of container signatures MAY recognize specific values or sets
348       of  values  of  optional.creator (perhaps augmented with optional.time‐
349       stamp), and MAY change their processing of the signature based on these
350       values (usually to accommodate violations of this specification in past
351       versions of the signing software which cannot be fixed  retroactively),
352       as long as the semantics of the invalid document, as created by such an
353       implementation, is clear.
354
355
356       If consumers of signatures do change their behavior based  on  the  op‐
357       tional.creator  value,  they SHOULD take care that the way they process
358       the signatures is not inconsistent with strictly  validating  signature
359       consumers.  (I.e. it is acceptable for a consumer to accept a signature
360       based on a specific optional.creator  value  if  other  implementations
361       would completely reject the signature, but it would be very undesirable
362       for the two kinds of implementations to accept the signature in differ‐
363       ent and inconsistent situations.)
364
365
366   optional.timestamp
367       If  present,  this  MUST  be a JSON number, which is representable as a
368       64-bit integer, and identifies the time when the signature was  created
369       as the number of seconds since the UNIX epoch (Jan 1 1970 00:00 UTC).
370
371
372
373signature                          Container            container-signature(5)
Impressum