Skip to content

Commit 92ce88e

Browse files
author
dlorenc
authored
Fix some bugs in the attestation support and add a formal spec. (#561)
Signed-off-by: Dan Lorenc <[email protected]>
1 parent 9479578 commit 92ce88e

File tree

4 files changed

+67
-4
lines changed

4 files changed

+67
-4
lines changed

cmd/cosign/cli/attest.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,10 @@ EXAMPLES
103103
}
104104
}
105105

106-
const intotoPayloadType = "application/vnd.in-toto+json"
106+
const (
107+
intotoPayloadType = "application/vnd.in-toto+json"
108+
dssePayloadType = "application/vnd.dsse.envelope.v1+json"
109+
)
107110

108111
func AttestCmd(ctx context.Context, ko KeyOpts, imageRef string, certPath string,
109112
upload bool, predicatePath string, force bool, predicateType string) error {
@@ -179,6 +182,7 @@ func AttestCmd(ctx context.Context, ko KeyOpts, imageRef string, certPath string
179182
Chain: sv.Chain,
180183
DupeDetector: sv,
181184
RemoteOpts: remoteOpts,
185+
MediaType: dssePayloadType,
182186
}
183187

184188
uploadTLog, err := shouldUploadToTlog(ref, force, ko.RekorURL)

cmd/cosign/cli/verify_attestation.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ func applyVerifyAttestationFlags(cmd *VerifyAttestationCommand, flagset *flag.Fl
4646
flagset.BoolVar(&cmd.Sk, "sk", false, "whether to use a hardware security key")
4747
flagset.StringVar(&cmd.Slot, "slot", "", "security key slot to use for generated key (default: signature) (authentication|signature|card-authentication|key-management)")
4848
flagset.BoolVar(&cmd.CheckClaims, "check-claims", true, "whether to check the claims found")
49-
flagset.StringVar(&cmd.Output, "output", "json", "output format for the signing image information (default JSON) (json|text)")
5049
flagset.StringVar(&cmd.FulcioURL, "fulcio-url", "https://fulcio.sigstore.dev", "[EXPERIMENTAL] address of sigstore PKI server")
5150
flagset.StringVar(&cmd.RekorURL, "rekor-url", "https://rekor.sigstore.dev", "[EXPERIMENTAL] address of rekor STL server")
5251
}
@@ -155,7 +154,8 @@ func (c *VerifyAttestationCommand) Exec(ctx context.Context, args []string) (err
155154
return err
156155
}
157156

158-
PrintVerification(imageRef, verified, co, c.Output)
157+
// The attestations are always JSON, so use the raw "text" mode for outputting them instead of conversion
158+
PrintVerification(imageRef, verified, co, "text")
159159
}
160160

161161
return nil

pkg/cosign/remote/remote.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,12 +148,17 @@ type UploadOpts struct {
148148
Bundle *Bundle
149149
AdditionalAnnotations map[string]string
150150
RemoteOpts []remote.Option
151+
MediaType string
151152
}
152153

153154
func UploadSignature(signature, payload []byte, dst name.Reference, opts UploadOpts) (uploadedSig []byte, err error) {
155+
// Preserve the default
156+
if opts.MediaType == "" {
157+
opts.MediaType = SimpleSigningMediaType
158+
}
154159
l := &staticLayer{
155160
b: payload,
156-
mt: SimpleSigningMediaType,
161+
mt: types.MediaType(opts.MediaType),
157162
}
158163

159164
base, err := SignatureImage(dst, opts.RemoteOpts...)

specs/ATTESTATION_SPEC.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Cosign Attestation Specifications
2+
3+
This document aims to describe how `cosign` attaches `Attestations` to container images.
4+
5+
The goal is to specify the behavior well enough to promote other implementations and enable interoperability.
6+
Attestations attached with `cosign` should be retrievable in other tools, and vice-versa.
7+
8+
This document focuses on the layout of attestations within an [OCI Image Manifest V1](https://github.com/opencontainers/image-spec/blob/master/manifest.md) object.
9+
10+
This document assumes you are using the In-Toto [Attestation](https://github.com/in-toto/attestation) format, serialized as a `DSSE` envelope
11+
Other formats can be used, and the `mediaType` property should describe the format of a particular attestation, but implementations may not understand them.
12+
The DSSE envelope format is defined [here](https://github.com/secure-systems-lab/dsse/blob/master/envelope.md#dsse-envelope) and uses the `mediaType`: `application/vnd.dsse.envelope.v1+json`.
13+
14+
Multiple Attestations may be "attached" to one image.
15+
Each Attestation may refer to the entire image, or to a specific part of that image.
16+
This is indicated via the `subject` field of the `Statement` inside the `Attestation`.
17+
18+
Attestations attached to a container image are generally assumed to refer to that image in some way.
19+
20+
## Overall Layout
21+
22+
An `Attestation` object is represented as an [OCI Image Manifest V1](https://github.com/opencontainers/image-spec/blob/master/manifest.md).
23+
24+
Each individual `Attestation` is represented as a `layer`, using a standard `descriptor`.
25+
The `layers` list is ordered, but no order is assumed or important for the `Attestations`.
26+
27+
Here is an example manifest containing one `Attestation`:
28+
29+
```json
30+
{
31+
"schemaVersion": 2,
32+
"config": {
33+
"mediaType": "application/vnd.oci.image.config.v1+json",
34+
"size": 233,
35+
"digest": "sha256:83bd5fb5b39f65f28e50a86d48fa79c07880befc292d92eebdc18531054b070c"
36+
},
37+
"layers": [
38+
{
39+
"mediaType": "application/vnd.dsse.envelope.v1+json",
40+
"size": 246,
41+
"digest": "sha256:ed3ad03d3b87843b5419d7dce9d50a3e0f45554b2ba93bf378611cae6b450cff",
42+
}
43+
]
44+
}
45+
```
46+
47+
## Subject Verification
48+
49+
`Attestations` MAY refer to multiple `subjects`.
50+
51+
When verifying an attestation for a container image, implementations MUST verify the relationship between the `subject` field and the container image.
52+
Attestations MAY reference the entire container image or a portion of it.
53+
54+
Implementations MUST support `Attestations` that reference the entire container image, other relationship types are optional.

0 commit comments

Comments
 (0)