Skip to content

Manifest's .config.mediaType being prefered as "artifact type" in OCI-layout index.json over .artifactType #4694

@Silvanoc

Description

@Silvanoc

Description

Saving an OCI-artifact locally with cosign save --dir results in an index.json in which the manifests entry of the artifact's manifest contains the value of .config.mediaType, even when .artifactType is being provided by that manifest.

The OCI-specification is clear on how to assign an artifact's type and therefore the sequence to identify it should be:

  1. Whatever .artifactType provides
  2. Whatever .config.mediaType provides (only when no .artifactType has been provided).

For example, we have an artifact with artifactType and an empty config:

{
  "schemaVersion": 2,
  "mediaType": "application/vnd.oci.image.manifest.v1+json",
  "artifactType": "application/vnd.my-artifact-type",
  "config": {
    "mediaType": "application/vnd.oci.empty.v1+json",
    "digest": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a",
    "size": 2,
    "data": "e30="
  },
  "layers": [
    {
      "mediaType": "application/octet-stream",
      "digest": "sha256:36c0cd9e4e37bc3db0f9186a0d5ba61f05acafeaba8f1b96f1db02f584fd2cc6",
      "size": 10485760,
      "annotations": {
        "org.opencontainers.image.title": "./random.binary"
      }
    }
  ],
  "annotations": {
    "org.opencontainers.image.created": "2026-02-12T09:52:32Z"
  }
}

Notice the values artifactType: application/vnd.my-artifact-type and config.mediaType: application/vnd.oci.empty.v1+json.

The resulting index.json in the OCI layout looks like this:

{
  "schemaVersion": 2,
  "mediaType": "application/vnd.oci.image.index.v1+json",
  "manifests": [
    {
      "mediaType": "application/vnd.oci.image.manifest.v1+json",
      "size": 641,
      "digest": "sha256:5c1b52a23d98e5ef0a00866a0b0a18b79f625110def619fcc8393c48938125da",
      "annotations": {
        "kind": "dev.cosignproject.cosign/image"
      },
      "artifactType": "application/vnd.oci.empty.v1+json"
    }
  ]
}

Notice that artifactType for the manifest is not the artifactType provided by the manifest, but the config.mediaType of that manifest!

Version

GitVersion: v3.0.4
GitCommit: 6832fba
GitTreeState: "clean"
BuildDate: 2026-01-09T21:17:16Z
GoVersion: go1.25.5
Compiler: gc
Platform: darwin/arm64

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions