Skip to content

Commit

Permalink
Use OCI Image Manifest v1 (#300)
Browse files Browse the repository at this point in the history
Signed-off-by: Jake Sanders <[email protected]>
  • Loading branch information
Jake Sanders authored May 4, 2021
1 parent a3a74fe commit 6a2c836
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 11 deletions.
9 changes: 5 additions & 4 deletions SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,11 +156,12 @@ Implementations MAY store signatures objects in the same OCI repository as the t
This section describes the way the properties from above are embedded into OCI objects that can be stored in a registry.
Implementations MUST support storing signatures in at least the following object types:

* [Image Manifest V2 Schema 2](https://docs.docker.com/registry/spec/manifest-v2-2/)
* [OCI Image Manifest V1](#oci-image-manifest-v1)

#### Image Manifest V2 Schema 2
#### OCI Image Manifest V1

This section describes the way the mandatory and optional signature properties are embedded into an Image Manifest V2 Schema 2 object.
This section describes the way the mandatory and optional signature properties are embedded into an
[OCI Image Manifest V1](https://github.com/opencontainers/image-spec/blob/master/manifest.md) object.

Only one image manifest is created for every signed object.
Multiple signatures can be embedded in one image manifest.
Expand All @@ -177,8 +178,8 @@ Example `payload`:
```
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
<omitted for brevity>
},
"layers": [
Expand Down
12 changes: 10 additions & 2 deletions pkg/cosign/remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,23 @@ func Descriptors(ref name.Reference) ([]v1.Descriptor, error) {
return m.Layers, nil
}

// SignatureImage
// SignatureImage returns the existing destination image, or a new, empty one.
func SignatureImage(dstTag name.Reference, opts ...remote.Option) (v1.Image, error) {
base, err := remote.Image(dstTag, opts...)
if err != nil {
if te, ok := err.(*transport.Error); ok {
if te.StatusCode != http.StatusNotFound {
return nil, te
}
base = empty.Image
if !DockerMediaTypes() {
base = mutate.MediaType(empty.Image, types.OCIManifestSchema1)
m, err := base.Manifest()
if err != nil {
// should never happen...?
return nil, err
}
m.Config.MediaType = types.OCIConfigJSON
}
} else {
return nil, err
}
Expand Down
16 changes: 12 additions & 4 deletions pkg/cosign/upload.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,11 @@ import (
)

const (
ExperimentalEnv = "COSIGN_EXPERIMENTAL"
repoEnv = "COSIGN_REPOSITORY"
ServerEnv = "REKOR_SERVER"
rekorServer = "https://api.rekor.dev"
ExperimentalEnv = "COSIGN_EXPERIMENTAL"
repoEnv = "COSIGN_REPOSITORY"
DockerMediaTypesEnv = "COSIGN_DOCKER_MEDIA_TYPES"
ServerEnv = "REKOR_SERVER"
rekorServer = "https://api.rekor.dev"
)

func Experimental() bool {
Expand All @@ -47,6 +48,13 @@ func Experimental() bool {
return false
}

func DockerMediaTypes() bool {
if b, err := strconv.ParseBool(os.Getenv(DockerMediaTypesEnv)); err == nil {
return b
}
return false
}

func DestinationRef(ref name.Reference, img *remote.Descriptor) (name.Reference, error) {
dstTag := ref.Context().Tag(Munge(img.Descriptor))
wantRepo := os.Getenv(repoEnv)
Expand Down
13 changes: 12 additions & 1 deletion test/e2e_test_secrets.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ export COSIGN_PASSWORD=$pass
./cosign generate-key-pair
img="us-central1-docker.pkg.dev/projectsigstore/cosign-ci/test"
img2="us-central1-docker.pkg.dev/projectsigstore/cosign-ci/test-2"
for image in $img $img2
legacy_img="us-central1-docker.pkg.dev/projectsigstore/cosign-ci/legacy-test"
for image in $img $img2 $legacy_img
do
(crane delete $(./cosign triangulate $image)) || true
crane cp busybox $image
Expand All @@ -42,6 +43,9 @@ done
./cosign sign -key cosign.key $img
./cosign verify -key cosign.pub $img

## confirm use of OCI media type in signature image
crane manifest $(./cosign triangulate $img) | grep -q "application/vnd.oci.image.config.v1+json"

## sign/verify multiple images
./cosign sign -key cosign.key -a multiple=true $img $img2
./cosign verify -key cosign.pub -a multiple=true $img $img2
Expand All @@ -56,6 +60,13 @@ if (./cosign verify -key cosign.pub -a foo=bar -a bar=baz $img); then false; fi
./cosign verify -key cosign.pub -a foo=bar -a bar=baz $img
./cosign verify -key cosign.pub -a bar=baz $img

# confirm the use of legacy (Docker) media types
COSIGN_DOCKER_MEDIA_TYPES=1 ./cosign sign -key cosign.key $legacy_img
./cosign verify -key cosign.pub $legacy_img
legacy_manifest=$(crane manifest $(./cosign triangulate $legacy_img))
echo $legacy_manifest | grep -q "application/vnd.docker.distribution.manifest.v2+json"
echo $legacy_manifest | grep -q "application/vnd.docker.container.image.v1+json"

# wrong keys
mkdir wrong && pushd wrong
../cosign generate-key-pair
Expand Down

0 comments on commit 6a2c836

Please sign in to comment.