Skip to content

Commit

Permalink
exporter: set custom config media type on attestation manifests
Browse files Browse the repository at this point in the history
This patch sets the media type for attestation manifests to
"application/vnd.docker.attestation.config.v1+json" instead of faking a
"application/vnd.oci.image.config.v1+json" type.

This updates the attestation manifests inline with the OCI artifact type
defined at https://github.com/opencontainers/artifacts. Aside from just
making us inline with the spec here, we would hopefully be able to see
better integrations in registries that just handle config media types
and don't inspect the custom buildkit attestations.

Additionally, this makes it *firmly* impossible for runtimes to
accidentally download and run the attestation manifest, treating it as
an image manifest.

Signed-off-by: Justin Chadwell <me@jedevc.com>
  • Loading branch information
jedevc committed Feb 9, 2023
1 parent ecc5937 commit 723216e
Show file tree
Hide file tree
Showing 5 changed files with 9 additions and 31 deletions.
31 changes: 4 additions & 27 deletions exporter/containerimage/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ func (ic *ImageWriter) commitDistributionManifest(ctx context.Context, opts *Ima
func (ic *ImageWriter) commitAttestationsManifest(ctx context.Context, opts *ImageCommitOpts, p exptypes.Platform, target string, statements []intoto.Statement) (*ocispecs.Descriptor, error) {
var (
manifestType = ocispecs.MediaTypeImageManifest
configType = ocispecs.MediaTypeImageConfig
configType = attestationTypes.MediaTypeOCIAttestationConfig
)
if !opts.OCITypes {
manifestType = images.MediaTypeDockerSchema2Manifest
Expand All @@ -473,7 +473,7 @@ func (ic *ImageWriter) commitAttestationsManifest(ctx context.Context, opts *Ima
}
digest := digest.FromBytes(data)
desc := ocispecs.Descriptor{
MediaType: attestationTypes.MediaTypeDockerSchema2AttestationType,
MediaType: attestationTypes.MediaTypeAttestationLayer,
Digest: digest,
Size: int64(len(data)),
Annotations: map[string]string{
Expand All @@ -488,10 +488,7 @@ func (ic *ImageWriter) commitAttestationsManifest(ctx context.Context, opts *Ima
layers[i] = desc
}

config, err := attestationsConfig(layers)
if err != nil {
return nil, err
}
config := []byte("{}")
configDigest := digest.FromBytes(config)
configDesc := ocispecs.Descriptor{
Digest: configDigest,
Expand All @@ -511,11 +508,7 @@ func (ic *ImageWriter) commitAttestationsManifest(ctx context.Context, opts *Ima
Versioned: specs.Versioned{
SchemaVersion: 2,
},
Config: ocispecs.Descriptor{
Digest: configDigest,
Size: int64(len(config)),
MediaType: configType,
},
Config: configDesc,
},
}

Expand Down Expand Up @@ -586,22 +579,6 @@ func defaultImageConfig() ([]byte, error) {
return dt, errors.Wrap(err, "failed to create empty image config")
}

func attestationsConfig(layers []ocispecs.Descriptor) ([]byte, error) {
img := ocispecs.Image{
Architecture: intotoPlatform.Architecture,
OS: intotoPlatform.OS,
OSVersion: intotoPlatform.OSVersion,
OSFeatures: intotoPlatform.OSFeatures,
Variant: intotoPlatform.Variant,
}
img.RootFS.Type = "layers"
for _, layer := range layers {
img.RootFS.DiffIDs = append(img.RootFS.DiffIDs, digest.Digest(layer.Annotations["containerd.io/uncompressed"]))
}
dt, err := json.Marshal(img)
return dt, errors.Wrap(err, "failed to create attestations image config")
}

func parseHistoryFromConfig(dt []byte) ([]ocispecs.History, error) {
var config struct {
History []ocispecs.History
Expand Down
2 changes: 1 addition & 1 deletion solver/llbsolver/solver.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ func (s *Solver) recordBuildHistory(ctx context.Context, id string, req frontend
if err != nil {
return nil, nil, err
}
w, err := s.history.OpenBlobWriter(ctx, attestation.MediaTypeDockerSchema2AttestationType)
w, err := s.history.OpenBlobWriter(ctx, attestation.MediaTypeAttestationLayer)
if err != nil {
return nil, nil, err
}
Expand Down
3 changes: 2 additions & 1 deletion util/attestation/types.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package attestation

const (
MediaTypeDockerSchema2AttestationType = "application/vnd.in-toto+json"
MediaTypeAttestationLayer = "application/vnd.in-toto+json"
MediaTypeOCIAttestationConfig = "application/vnd.docker.attestation.config.v1+json"

DockerAnnotationReferenceType = "vnd.docker.reference.type"
DockerAnnotationReferenceDigest = "vnd.docker.reference.digest"
Expand Down
2 changes: 1 addition & 1 deletion util/imageutil/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ func childrenConfigHandler(provider content.Provider, platform platforms.MatchCo
descs = append(descs, index.Manifests...)
}
case images.MediaTypeDockerSchema2Config, ocispecs.MediaTypeImageConfig, docker.LegacyConfigMediaType,
attestation.MediaTypeDockerSchema2AttestationType:
attestation.MediaTypeAttestationLayer, attestation.MediaTypeOCIAttestationConfig:
// childless data types.
return nil, nil
default:
Expand Down
2 changes: 1 addition & 1 deletion util/push/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ func childrenHandler(provider content.Provider) images.HandlerFunc {
case images.MediaTypeDockerSchema2Layer, images.MediaTypeDockerSchema2LayerGzip,
images.MediaTypeDockerSchema2Config, ocispecs.MediaTypeImageConfig,
ocispecs.MediaTypeImageLayer, ocispecs.MediaTypeImageLayerGzip,
attestation.MediaTypeDockerSchema2AttestationType:
attestation.MediaTypeAttestationLayer, attestation.MediaTypeOCIAttestationConfig:
// childless data types.
return nil, nil
default:
Expand Down

0 comments on commit 723216e

Please sign in to comment.