Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid platform / displayed + misc UI feedback #475

Open
polarathene opened this issue Mar 10, 2025 · 15 comments
Open

Invalid platform / displayed + misc UI feedback #475

polarathene opened this issue Mar 10, 2025 · 15 comments
Labels
bug Something isn't working rm-external External roadmap item

Comments

@polarathene
Copy link

polarathene commented Mar 10, 2025

Describe the bug

Since zot 2.1.2 there is support for Docker media types instead of only OCI. However the UI fails to recognize / display the image arch, instead rendering as /.

To Reproduce

Reproduction instructions to build and push along with associated manifest config can be found here.

Expected behavior

Consistency with platform info (it is there just like OCI media types provide).

Screenshots

Image

Image

OCI compliant platform renders correctly, but in this case there is an unknown/unknown platform which is equally invalid (misuse for provenance attestation artifacts by Docker AFAIK?), other image registries like Gitea have this platform filtered out:

Image

Image

Additional context

Related UX concerns (or allow to be configurable):

  • When the timestamp or vendor information is also invalid, perhaps don't display that?
  • When vulnerability scanning is disabled (extensions.search.cve is missing from config), don't display the "Failed to scan" badge as it is meaningless?
  • The cube icon next to an image name doesn't appear to have any meaning in colour, nor is it deterministic (changes colour randomly, even when the same image card is displayed in both popular and updated views on the home page). There is no coverage in docs? Nor do they appear to be configurable?
  • The unknown/unknown platform technically shouldn't be displayed as a platform selection. It is presented in the list of arch chips beneath an image description and can be filtered at /explore?filter=unknown (but not available as a selectable filter understandably).
andaaron added a commit to andaaron/zot that referenced this issue Mar 10, 2025
Including handling indexes / manifest lists for buildkit manifest lists containing image cache

See
- project-zot/zui#475
- project-zot#3000 (comment)

Fix and unrelated issue with killing zot and collecting logs in case of cluster test failures

Signed-off-by: Andrei Aaron <[email protected]>
@andaaron
Copy link
Contributor

  • Since zot 2.1.2 there is support for Docker media types instead of only OCI. However the UI fails to recognize / display the image arch, instead rendering as /.

Will fix this as part of project-zot/zot#3019

  • When the timestamp or vendor information is also invalid, perhaps don't display that?

Will fix this as part of project-zot/zot#3019

  • When vulnerability scanning is disabled (extensions.search.cve is missing from config), don't display the "Failed to scan" badge as it is meaningless?

Will need to see how we can handle this.

  • The cube icon next to an image name doesn't appear to have any meaning in colour, nor is it deterministic (changes colour randomly, even when the same image card is displayed in both popular and updated views on the home page). There is no coverage in docs? Nor do they appear to be configurable?

With regards to the cube icon, that is supposed to be a customizable image by encoding it into a specific annotation.
Since that is not part of the OCI spec, de decided to shelve it a while back.

  • The unknown/unknown platform technically shouldn't be displayed as a platform selection. It is presented in the list of arch chips beneath an image description and can be filtered at /explore?filter=unknown (but not available as a selectable filter understandably).

Not sure what to do about it. I don't think we want to add custom logic based on docker specific annotations in the zot or UI code.

@polarathene
Copy link
Author

polarathene commented Mar 10, 2025

Not sure what to do about it. I don't think we want to add custom logic based on docker specific annotations in the zot or UI code.

My point was you don't have the ability to select unknown for a platform or architecture in the explore page filters.

So rather than Docker specific, it was more about not presenting these invalid platforms in the first place. AFAIK, once Docker moves it's default publishing to OCI compliance this behaviour won't remain (at least from what I understand, attestations artifacts for an image would rely on Referrers API or Referrer Tag schema for discovery, nothing in the image index that Docker is presently doing).


OCI compliant types

Here's how to reproduce with OCI compliant types.

NOTE: This differs from earlier screenshot that rendered unknown/unknown. Instead the platform with OCI media types renders as /? (Similar to how linux/amd64 / linux/arm64 platforms rendered as / for their respective platforms when Docker media types were used in earlier screenshots).

FROM alpine
RUN echo 'hello' > /tmp/hello.txt
# Docker Engine 28.0.1, buildx v0.21.1, BuildKit 0.20.0

# Run zot
docker run --rm -d --name zot -p 127.0.0.1:5000:5000 ghcr.io/project-zot/zot:v2.1.2

# Build image and push to zot
# Differs from defaults with:
# - x86_64 + aarch64 multi-arch image
# - Full provenance (instead of minimal, forces using an index even if only a single platform)
# - OCI media types for manifest/index and artifacts (instead of Docker equivalent types)
docker buildx build --builder custom-builder \
  --output 'type=image,push=true,oci-mediatypes=true,oci-artifact=true' \
  --platform 'linux/amd64,linux/arm64' \
  --provenance true \
  --tag localhost:5000/hello/world:example \
  .

Image

Inspecting their content is not that useful either:

Image

The actual OCI artifacts they reference aren't visible or possible to navigate to via the UI? I've documented that here, as the "Referred By" view doesn't appear to be functional for discovery.

@polarathene
Copy link
Author

polarathene commented Mar 10, 2025

When vulnerability scanning is disabled (extensions.search.cve is missing from config), don't display the "Failed to scan" badge as it is meaningless?

Will need to see how we can handle this.

If you get involved on the zot end, it would be nice to update documentation for opt-out on the feature.

It was non-obvious how to opt-out (for ephemeral zot containers I didn't want the extra 1.7GB of weight or bandwidth from pulling trivy since the registry volume was short-lived).

I'm not entirely sure why the image insists on declaring a VOLUME instruction (implies users are deploying zot and expecting implicit persistent storage via Docker Compose, but if they value their data they really should have an explicit volume..). (EDIT: Raised this concern via discussion)


With regards to the cube icon, that is supposed to be a customizable image by encoding it into a specific annotation.
Since that is not part of the OCI spec, de decided to shelve it a while back.

That's fine. I have no issue with the icon itself really, but the initial impression was the colours had some meaning associated to them (like is documented for vulnerabilities) and then the observation that the colour was non-deterministic, just randomly selected.

I think it'd be better to just keep the colour fixed. GHCR for example just has a monochrome container icon:

Image

@andaaron
Copy link
Contributor

andaaron commented Mar 11, 2025

So rather than Docker specific, it was more about not presenting these invalid platforms in the first place. AFAIK, once Docker moves it's default publishing to OCI compliance this behaviour won't remain (at least from what I understand, attestations artifacts for an image would rely on Referrers API or Referrer Tag schema for discovery, nothing in the image index that Docker is presently doing).

Sorry, I don't have the time now to go through your investigation in detail today, but this stood out to me.

Given one of your examples using OCI media types:

{
  "schemaVersion": 2,
  "mediaType": "application/vnd.oci.image.index.v1+json",
  "manifests": [
    {
      "mediaType": "application/vnd.oci.image.manifest.v1+json",
      "digest": "sha256:a42bc525fcf382ea7160b037fe72444dc5a415bf8c874e9432814d22ddb61dda",
      "size": 668,
      "platform": {
        "architecture": "amd64",
        "os": "linux"
      }
    },
    {
      "mediaType": "application/vnd.oci.image.manifest.v1+json",
      "digest": "sha256:8c57cad131a6458bc17679475de6d9dd2fd5da21e4ee88a1e52774722b210652",
      "size": 668,
      "platform": {
        "architecture": "arm64",
        "os": "linux"
      }
    },
    {
      "mediaType": "application/vnd.oci.image.manifest.v1+json",
      "digest": "sha256:4e7545e0a6306b658f3896724ec8d9b5d0b6b055394bb7a2d40816676d6ac0f9",
      "size": 914,
      "annotations": {
        "vnd.docker.reference.digest": "sha256:a42bc525fcf382ea7160b037fe72444dc5a415bf8c874e9432814d22ddb61dda",
        "vnd.docker.reference.type": "attestation-manifest"
      },
      "platform": {
        "architecture": "unknown",
        "os": "unknown"
      }
    },
    {
      "mediaType": "application/vnd.oci.image.manifest.v1+json",
      "digest": "sha256:b71d18d0f25ba530053c3551fe65105974da76fee2949adc3539e60be8a67ead",
      "size": 914,
      "annotations": {
        "vnd.docker.reference.digest": "sha256:8c57cad131a6458bc17679475de6d9dd2fd5da21e4ee88a1e52774722b210652",
        "vnd.docker.reference.type": "attestation-manifest"
      },
      "platform": {
        "architecture": "unknown",
        "os": "unknown"
      }
    }
  ]
}

Handling these annotations count as referrers is not part of the OCI spec:

      "annotations": {
        "vnd.docker.reference.digest": "sha256:a42bc525fcf382ea7160b037fe72444dc5a415bf8c874e9432814d22ddb61dda",
        "vnd.docker.reference.type": "attestation-manifest"
      },

So we don't handle the manifest sha256:b71d18d0f25ba530053c3551fe65105974da76fee2949adc3539e60be8a67ead having these annotations as a referrer of sha256:a42bc525fcf382ea7160b037fe72444dc5a415bf8c874e9432814d22ddb61dda. This is not in the spec.

An actual referrer per OCI spec is a manifest such as (also from one of your examples):

{
  "schemaVersion": 2,
  "mediaType": "application/vnd.oci.image.manifest.v1+json",
  "artifactType": "doc/example",
  "config": {
    "mediaType": "application/vnd.oci.empty.v1+json",
    "digest": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a",
    "size": 2,
    "data": "e30="
  },
  "layers": [
    {
      "mediaType": "application/vnd.oci.image.layer.v1.tar",
      "digest": "sha256:d9014c4624844aa5bac314773d6b689ad467fa4e1d1a50a1b8a99d5a95f72ff5",
      "size": 14,
      "annotations": {
        "org.opencontainers.image.title": "hi.txt"
      }
    }
  ],
  "subject": {
    "mediaType": "application/vnd.oci.image.manifest.v1+json",
    "digest": "sha256:a42bc525fcf382ea7160b037fe72444dc5a415bf8c874e9432814d22ddb61dda",
    "size": 668,
    "platform": {
      "architecture": "amd64",
      "os": "linux"
    }
  },
  "annotations": {
    "org.opencontainers.image.created": "2025-03-11T02:07:44Z"
  }
}

This manifest is a referrer of sha256:a42bc525fcf382ea7160b037fe72444dc5a415bf8c874e9432814d22ddb61dda as it has it in the subject field.
Theoretically. in zui you should see this manifest in the referrers tab of the image sha256:a42bc525fcf382ea7160b037fe72444dc5a415bf8c874e9432814d22ddb61dda

Later edit:
Maybe sha256:4e7545e0a6306b658f3896724ec8d9b5d0b6b055394bb7a2d40816676d6ac0f9 is the hash of the artifact mentioned above, in which case the tooling adds this redundant referrer information in the index.json. Instead of relying only on the subject field of the referrer, and the referrers API.

But we can't have zot/zui ignore entries in the index.json because they have this specific annotation "vnd.docker.reference.type": "attestation-manifest".

@polarathene
Copy link
Author

So we don't handle the manifest sha256:b71d18d0f25ba530053c3551fe65105974da76fee2949adc3539e60be8a67ead having these annotations as a referrer of sha256:a42bc525fcf382ea7160b037fe72444dc5a415bf8c874e9432814d22ddb61dda. This is not in the spec.

I am aware it is not OCI spec. I assume Docker uses that with it's own tooling, I haven't tracked the timeline of the OCI Referrer spec but it's possible that Docker had been doing their own approach before there was an OCI standard and this is effectively legacy with the oci-artifact=true build parameter support (Buildx only got this in 2025). Presumably it'll be phased out by the time Docker defaults to publishing with OCI types instead of their own equivalents. AFAIK the image index entries aren't serving much purpose/value anywhere else, annotations may be used by Docker Desktop or docker buildx imagetools inspect.


For reference I split out the concern with Referrers API / discovery to this issue.

The associated content in this issue is about how that is rendered in zui due to unknown/unknown which probably shouldn't be displayed at all given there is no ability to filter it in /explore, nor does it serve any purpose to pull.

This manifest is a referrer of sha256:a42bc525fcf382ea7160b037fe72444dc5a415bf8c874e9432814d22ddb61dda as it has it in the subject field.
Theoretically. in zui you should see this manifest in the referrers tab of the image sha256:a42bc525fcf382ea7160b037fe72444dc5a415bf8c874e9432814d22ddb61dda

I've published with OCI compliant types, oras discover is able to report the references correctly but zui is empty.


But we can't have zot/zui ignore entries in the index.json because they have this specific annotation "vnd.docker.reference.type": "attestation-manifest".

?

My request is to ignore is unrelated to the Docker annotations, but the fact that AFAIK there is no user-facing value of:

"platform": {
  "architecture": "unknown",
  "os": "unknown"
}

Gitea registry hides this. GHCR does not.

I have noticed zui doesn't show referrer tag schema tagged indexes like GHCR does, so zui is already hiding some information as-is.

@andaaron
Copy link
Contributor

I have noticed zui doesn't show referrer tag schema tagged indexes like GHCR does, so zui is already hiding some information as-is.

Those are only a workaround for older registries not having a referrers API. Clients should not use this tag if the API is available. Maybe the client checks the API first? Not sure if we intentionally hide it.

My request is to ignore is unrelated to the Docker annotations, but the fact that AFAIK there is no user-facing value of:

Understood, but that's the data coming from the image itself. If the image builder decided to use "unknown" I think we should show it as is.
Filtering and searching by it doesn't make sense though, as it could have different meanings for different builders and use cases.

Simply showing / is something we should fix. There is an issue with showing platform information for docker mediatypes, which should be fixed in the backend, but there's no guarantee the platform will always be present in the manifest descriptor inside the index in all cases. We should have a better placeholder in case it is missing.

andaaron added a commit to andaaron/zot that referenced this issue Mar 11, 2025
Including handling indexes / manifest lists for buildkit manifest lists containing image cache

See
- project-zot/zui#475
- project-zot#3000 (comment)

Fix and unrelated issue with killing zot and collecting logs in case of cluster test failures

Signed-off-by: Andrei Aaron <[email protected]>
@polarathene
Copy link
Author

Not sure if we intentionally hide it.

To clarify, zot is fine with it. Just zui has no visibility of the tag when it's created explicitly via oras instead of using the Referrers API (default).

Understood, but that's the data coming from the image itself. If the image builder decided to use "unknown" I think we should show it as is.
Filtering and searching by it doesn't make sense though, as it could have different meanings for different builders and use cases.

My stance for these sorts of things are when there are valid use-cases to support rather than supporting unknown what-ifs 😅

As such I think Gitea is doing it right to not treat it as a valid image platform to present to the user. I think the information can still be presented via raw JSON being displayed on demand instead? Or like this issue notes for troubleshooting/observability reasons, but not necessarily as part of the primary UX until there's a valid scenario where that information is of value?

Presently you'll find reports of users complaining about such on other registries that have rendered it. Especially when users attempt to pull it since the registry treats it like any other platform. You would still be able to attempt a pull, but until there is a valid use-case for unknown/unknown, it may be better to just omit the platform from display?


Simply showing / is something we should fix. There is an issue with showing platform information for docker mediatypes, which should be fixed in the backend, but there's no guarantee the platform will always be present in the manifest descriptor inside the index in all cases. We should have a better placeholder in case it is missing.

For context, / rendered based on:

  • Docker media types affected legitimate platforms (linux/amd64 / linux/arm64)
  • OCI media types affected invalid platform unknown/unknown (but for Docker media type it rendered "correctly")

andaaron added a commit to project-zot/zot that referenced this issue Mar 11, 2025
Including handling indexes / manifest lists for buildkit manifest lists containing image cache

See
- project-zot/zui#475
- #3000 (comment)

Fix and unrelated issue with killing zot and collecting logs in case of cluster test failures

Signed-off-by: Andrei Aaron <[email protected]>
@polarathene
Copy link
Author

polarathene commented Mar 11, 2025

I have tried with v2.1.3-rc3 and the following command:

docker buildx build --builder custom-builder \
  --output 'type=image,push=true,oci-mediatypes=true,oci-artifact=true' \
  --platform 'linux/amd64,linux/arm64' \
  --provenance true \
  --tag localhost:5000/hello/world:example \
  .

This will still render the unknown/unknown platform as /. The primary concern with linux/amd64 / linux/arm64 when using Docker media types is however confirmed as resolved.

Problem: If I instead set oci-artifact=false the expected unknown/unknown platform will be displayed instead of /. I'm not entirely sure why oci-artifact=true would make this invalid platform displayed as /.


Comparison

NOTE: Below I run two oras commands. The 1st is to get the image index JSON and manually get the OCI artifact digest, but this could be done with jq and then fed into the 2nd oras command:

oras manifest fetch localhost:5000/hello/world:example \
  | jq -r '[ .manifests[]
    | select(.annotations | has("vnd.docker.reference.digest"))
    | .digest
  ] | first' \
  | oras manifest fetch "localhost:5000/hello/world@$(cat -)"

oci-artifact=true

Image

The linux/amd64 artifact manifest:

oras manifest fetch --pretty localhost:5000/hello/world:test-t
oras manifest fetch --pretty \
localhost:5000/hello/world@sha256:05774b462cb207aa3dded9d0d9c9943054c6aa26a29eec6ea13a9969974af1be
{
  "schemaVersion": 2,
  "mediaType": "application/vnd.oci.image.manifest.v1+json",
  "artifactType": "application/vnd.docker.attestation.manifest.v1+json",
  "config": {
    "mediaType": "application/vnd.oci.empty.v1+json",
    "digest": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a",
    "size": 2,
    "data": "e30="
  },
  "layers": [
    {
      "mediaType": "application/vnd.in-toto+json",
      "digest": "sha256:b4c552c500c2e7573cf57439097ab8ee8a7d7133297dcd66c1389af411e4b9f0",
      "size": 1017,
      "annotations": {
        "in-toto.io/predicate-type": "https://slsa.dev/provenance/v0.2"
      }
    }
  ],
  "subject": {
    "mediaType": "application/vnd.oci.image.manifest.v1+json",
    "digest": "sha256:a42bc525fcf382ea7160b037fe72444dc5a415bf8c874e9432814d22ddb61dda",
    "size": 668,
    "platform": {
      "architecture": "amd64",
      "os": "linux"
    }
  }
}

Related zot logs:

warning: config sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a has an unknown media type: application/vnd.oci.empty.v1+json
warning: layer sha256:b4c552c500c2e7573cf57439097ab8ee8a7d7133297dcd66c1389af411e4b9f0 has an unknown media type: application/vnd.in-toto+json

warning: config sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a has an unknown media type: application/vnd.oci.empty.v1+json
warning: layer sha256:e90b8921ef91952865a6f26c1930caae1e30460cd88544c759150cf8c6303a31 has an unknown media type: application/vnd.in-toto+json

oci-artifact=false

Image

The linux/amd64 artifact manifest:

oras manifest fetch --pretty localhost:5000/hello/world:test-f
oras manifest fetch --pretty \
localhost:5000/hello/world@sha256:85c58175832585eeae3a36e3211e7f6f62a9e6c4ef8f75c199cf3aa5214387d1
{
  "schemaVersion": 2,
  "mediaType": "application/vnd.oci.image.manifest.v1+json",
  "config": {
    "mediaType": "application/vnd.oci.image.config.v1+json",
    "digest": "sha256:2a7ab206301b4f2cfc11b15344e1d9fa694d6a3c75e93331a189e9a73d9d7050",
    "size": 167
  },
  "layers": [
    {
      "mediaType": "application/vnd.in-toto+json",
      "digest": "sha256:6510340fa92b62fd4fb596421dca5e8686c3274e2b572a50e971bfa66e990835",
      "size": 1017,
      "annotations": {
        "in-toto.io/predicate-type": "https://slsa.dev/provenance/v0.2"
      }
    }
  ]
}

Related zot logs:

warning: layer sha256:6510340fa92b62fd4fb596421dca5e8686c3274e2b572a50e971bfa66e990835 has an unknown media type: application/vnd.in-toto+json
warning: layer sha256:ad8e94db85e7bd04572160657f0b4e28a8f8502db48173cb8f2b6a35557089b8 has an unknown media type: application/vnd.in-toto+json

Relevancy

When comparing the respective image index JSON for both images, there is nothing distinctive between the two to suggest the UI rendering difference for platform. I assume it's related to something on the zot side that your PR missed?

While on the topic of unknown/unknown relevancy... Do note that zot logs a warning:

warning: operating system "unknown" of the bundle is not supported yet.
warning: architecture "unknown" is not supported yet.

I assume there isn't any intention for unknown/unknown to ever be supported, but if zot logs the above should zui really be misleading by rendering as if it was a valid platform to pull?

@andaaron
Copy link
Contributor

andaaron commented Mar 11, 2025

Those are only a workaround for older registries not having a referrers API. Clients should not use this tag if the API is available. Maybe the client checks the API first? Not sure if we intentionally hide it.

I checked and we don't add the referrers tag to our DB on push, That's why we don't return it.

@polarathene
Copy link
Author

That's why we don't return it.

Shouldn't the query to zot be leveraging Referrers API? That works absolutely fine with oras discover (as I documented here).

I checked and we don't add the referrers tag to our DB on push

Is this in relation to an actual referrers tag being created at the zot registry? (as I documented here)

My understanding of zui is it's a static frontend, no backend support other than querying zot via it's standard APIs? So I assume there is no zui specific DB 😅

Even when a referrer tag is specifically created, the referrer API support in zot should still work regardless. I don't think zui needs to care about such, just query like oras discover does?

Or is this meant to be a zui specific optimization for the frontend feature?

@andaaron
Copy link
Contributor

andaaron commented Mar 11, 2025

The UI doesn't call the referrers REST API, it calls a graphql endpoint which queries a DB on zot side. It's a different implementation.
I meant the referrers tag is ignored if someone pushes it (the one created with oras attach --distribution-spec v1.1-referrers-tag). So you won't see it in the list of tags for that repo shown in the UI.
In the REST API it should be present, as that one doesn't use the DB I mentioned above.

That doesn't have anything to do with the UI not showing the content for referred by, this I still need to look into.

@andaaron
Copy link
Contributor

andaaron commented Mar 11, 2025

With regards to #475 (comment).
Looking at the data in the comment. I don't see platform information in the output of oras manifest fetch --pretty localhost:5000/hello/world@sha256:05774b462cb207aa3dded9d0d9c9943054c6aa26a29eec6ea13a9969974af1be. The config is the empty mediatype, The values are not set for os and arch, resulting in /.

In case of oras manifest fetch --pretty localhost:5000/hello/world@sha256:85c58175832585eeae3a36e3211e7f6f62a9e6c4ef8f75c199cf3aa5214387d1 the config sha256:2a7ab206301b4f2cfc11b15344e1d9fa694d6a3c75e93331a189e9a73d9d7050 probably contains unknown for the os and arch, resulting in unknown/unknown. Can you check the config content?

Given the error messages in one of your other issues, which you also mentioned above:

warning: layer sha256:feaa98933b0f8d3e40d4c331be215bec0c3b29c7d69097ec9ba796144ffc5c2b has an unknown media type: application/vnd.in-toto+json

warning: operating system "unknown" of the bundle is not supported yet.
warning: architecture "unknown" is not supported yet.

warning: layer sha256:feaa98933b0f8d3e40d4c331be215bec0c3b29c7d69097ec9ba796144ffc5c2b has an unknown media type: application/vnd.in-toto+json

Later edit, this looks like opencontainers/image-spec#1192

@rchincha We should update to the latest image spec.

@polarathene
Copy link
Author

polarathene commented Mar 11, 2025

TL;DR: I can confirm that the artifact config content differs by:

  • oci-artifact=false => unknown/unknown is sourced from here.
  • oci-artifact=true => OCI v1.1 compliant artifact has empty config, platform is encoded under subject attribute.

With regards to #475 (comment).
Looking at the data in the comment. I don't see platform information in the output of oras manifest fetch --pretty localhost:5000/hello/world@sha256:05774b462cb207aa3dded9d0d9c9943054c6aa26a29eec6ea13a9969974af1be. The config is the empty mediatype, The values are not set for os and arch, resulting in /.

Right.. this is probably because I'm thinking of the platform being inferred from the image index JSON that a registry would normally derive this information from AFAIK?

EDIT: As confirmed below, the info is being sourced from each individual manifest config attribute, rather than context from the image index itself.


In case of oras manifest fetch --pretty localhost:5000/hello/world@sha256:85c58175832585eeae3a36e3211e7f6f62a9e6c4ef8f75c199cf3aa5214387d1 the config sha256:2a7ab206301b4f2cfc11b15344e1d9fa694d6a3c75e93331a189e9a73d9d7050 probably contains unknown for the os and arch, resulting in unknown/unknown.

Can you check the config content?

sha256:85c5817 has been shared in the below reference section under "Attestation artifact (no referrers information)" (oci-artifact=false).

You are correct, the artifact (sha256:85c5817) config content (sha256:2a7ab20) is unknown/unknown:

oras manifest fetch-config --pretty \
localhost:5000/hello/world@sha256:85c58175832585eeae3a36e3211e7f6f62a9e6c4ef8f75c199cf3aa5214387d1
{
  "architecture": "unknown",
  "os": "unknown",
  "config": {},
  "rootfs": {
    "type": "layers",
    "diff_ids": [
      "sha256:6510340fa92b62fd4fb596421dca5e8686c3274e2b572a50e971bfa66e990835"
    ]
  }
}

EDIT: Here is the official Docker docs on the attestation config descriptor (bolded emphasis by me):

The image config descriptor will point to a valid image config, however, it will not contain attestation-specific details, and should be ignored as it is only included for compatibility purposes.

Meanwhile, the OCI artifact with empty config:

$ oras manifest fetch-config --pretty \
localhost:5000/hello/world@sha256:05774b462cb207aa3dded9d0d9c9943054c6aa26a29eec6ea13a9969974af1be

{}

If it is helpful, here is the associated JSON attachment (provenance attestation) for that artifact:

Inspecting the OCI artifact layer content

Content is effectively the same and platform is encoded. oci-artifact parameter makes no meaningful difference to this content.

oras blob fetch --output - \
localhost:5000/hello/world@sha256:6510340fa92b62fd4fb596421dca5e8686c3274e2b572a50e971bfa66e990835 \
| jq .
{
  "_type": "https://in-toto.io/Statement/v0.1",
  "predicateType": "https://slsa.dev/provenance/v0.2",
  "subject": [
    {
      "name": "pkg:docker/localhost%3A5000/hello/world@test-f?platform=linux%2Famd64",
      "digest": {
        "sha256": "a42bc525fcf382ea7160b037fe72444dc5a415bf8c874e9432814d22ddb61dda"
      }
    }
  ],
  "predicate": {
    "builder": {
      "id": ""
    },
    "buildType": "https://mobyproject.org/buildkit@v1",
    "materials": [
      {
        "uri": "pkg:docker/alpine@latest?platform=linux%2Famd64",
        "digest": {
          "sha256": "a8560b36e8b8210634f77d9f7f9efd7ffa463e380b75e2e74aff4511df3ef88c"
        }
      }
    ],
    "invocation": {
      "configSource": {
        "entryPoint": "Dockerfile"
      },
      "parameters": {
        "frontend": "dockerfile.v0",
        "locals": [
          {
            "name": "context"
          },
          {
            "name": "dockerfile"
          }
        ]
      },
      "environment": {
        "platform": "linux/amd64"
      }
    },
    "metadata": {
      "buildInvocationID": "s2wchebzazfrqwbze11we5aay",
      "buildStartedOn": "2025-03-11T20:19:23.204656792Z",
      "buildFinishedOn": "2025-03-11T20:19:24.672025931Z",
      "completeness": {
        "parameters": true,
        "environment": true,
        "materials": false
      },
      "reproducible": false,
      "https://mobyproject.org/buildkit@v1#metadata": {}
    }
  }
}

Reference

Expand for additional reference comparisons
Earlier shared build command
FROM alpine
RUN echo 'hello' > /tmp/hello.txt
docker buildx build --builder custom-builder \
  --output 'type=image,push=true,oci-mediatypes=true,oci-artifact=true' \
  --platform 'linux/amd64,linux/arm64' \
  --provenance true \
  --tag localhost:5000/hello/world:example \
  .

The next two sections provide reproduction + output of linux/amd64 related JSON for two image build tags test-f and test-t, where the only difference is toggling the output parameter oci-artifact.

oci-artifact=false / :test-f

For example, here is that image index with each manifest associated to a platform:

Image index for `:test-f` (`oci-artifact=false`)
oras manifest fetch --pretty localhost:5000/hello/world:test-f
{
  "schemaVersion": 2,
  "mediaType": "application/vnd.oci.image.index.v1+json",
  "manifests": [
    {
      "mediaType": "application/vnd.oci.image.manifest.v1+json",
      "digest": "sha256:a42bc525fcf382ea7160b037fe72444dc5a415bf8c874e9432814d22ddb61dda",
      "size": 668,
      "platform": {
        "architecture": "amd64",
        "os": "linux"
      }
    },
    {
      "mediaType": "application/vnd.oci.image.manifest.v1+json",
      "digest": "sha256:8c57cad131a6458bc17679475de6d9dd2fd5da21e4ee88a1e52774722b210652",
      "size": 668,
      "platform": {
        "architecture": "arm64",
        "os": "linux"
      }
    },
    {
      "mediaType": "application/vnd.oci.image.manifest.v1+json",
      "digest": "sha256:85c58175832585eeae3a36e3211e7f6f62a9e6c4ef8f75c199cf3aa5214387d1",
      "size": 566,
      "annotations": {
        "vnd.docker.reference.digest": "sha256:a42bc525fcf382ea7160b037fe72444dc5a415bf8c874e9432814d22ddb61dda",
        "vnd.docker.reference.type": "attestation-manifest"
      },
      "platform": {
        "architecture": "unknown",
        "os": "unknown"
      }
    },
    {
      "mediaType": "application/vnd.oci.image.manifest.v1+json",
      "digest": "sha256:54163e206be92d250fa41e3cedd761b4784a8ec20442bc80429a71a5e36ad310",
      "size": 566,
      "annotations": {
        "vnd.docker.reference.digest": "sha256:8c57cad131a6458bc17679475de6d9dd2fd5da21e4ee88a1e52774722b210652",
        "vnd.docker.reference.type": "attestation-manifest"
      },
      "platform": {
        "architecture": "unknown",
        "os": "unknown"
      }
    }
  ]
}

If I query the linux/amd64 platform manifest we get:

`linux/amd64` manifest (`oci-artifact=false`)
# NOTE: could also infer the digest by using the `--platform` option:
# oras manifest fetch --pretty --platform linux/amd64 localhost:5000/hello/world:test-f

oras manifest fetch --pretty \
localhost:5000/hello/world@sha256:a42bc525fcf382ea7160b037fe72444dc5a415bf8c874e9432814d22ddb61dda
{
  "schemaVersion": 2,
  "mediaType": "application/vnd.oci.image.manifest.v1+json",
  "config": {
    "mediaType": "application/vnd.oci.image.config.v1+json",
    "digest": "sha256:22a3cd305250e171afdb759a5494bd2cb30412583217904d33126de010411075",
    "size": 821
  },
  "layers": [
    {
      "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
      "digest": "sha256:f18232174bc91741fdf3da96d85011092101a032a93a388b79e99e69c2d5c870",
      "size": 3642247
    },
    {
      "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
      "digest": "sha256:935e4938154b3cc8b5d6c92b652110cca3295483871f9b08f4f01ae8960989b6",
      "size": 139
    }
  ]
}

Notice that there is no platform information here as the mediaType is application/vnd.oci.image.manifest.v1+json. That's to be expected, only an OCI artifact (v1.1 compliant?) identifies the related image by platform via subject metadata.

  • The associated artifact manifest (oci-artifact=false) would have been prior to OCI artifact being standardized, but has been published with OCI compliant media types (oci-mediatypes=true, implicit with default provenance attestation from docker build).
  • This is probably why Docker has been appending the unknown/unknown platform entries to refer to these artifacts at the image index. Since the artifact manifest otherwise only has a layer with the attestation content, but no metadata for the associated image it belongs to.
Attestation artifact (_no referrers information_)
oras manifest fetch --pretty \
localhost:5000/hello/world@sha256:85c58175832585eeae3a36e3211e7f6f62a9e6c4ef8f75c199cf3aa5214387d1
{
  "schemaVersion": 2,
  "mediaType": "application/vnd.oci.image.manifest.v1+json",
  "config": {
    "mediaType": "application/vnd.oci.image.config.v1+json",
    "digest": "sha256:2a7ab206301b4f2cfc11b15344e1d9fa694d6a3c75e93331a189e9a73d9d7050",
    "size": 167
  },
  "layers": [
    {
      "mediaType": "application/vnd.in-toto+json",
      "digest": "sha256:6510340fa92b62fd4fb596421dca5e8686c3274e2b572a50e971bfa66e990835",
      "size": 1017,
      "annotations": {
        "in-toto.io/predicate-type": "https://slsa.dev/provenance/v0.2"
      }
    }
  ]
}

oci-artifact=true / :test-t

This differs with oci-artifacts=true (the :test-t tagged image), but only for the OCI artifact manifest which now has the subject attribute to be an OCI compliant artifact which can leverage the Referrers API (or the referrers tag schema fallback, when supporting index + tag are present).

There is no other notable difference (JSON collapsed for brevity):

Image index for `:test-t` (`oci-artifact=true`)
oras manifest fetch --pretty localhost:5000/hello/world:test-t
{
  "schemaVersion": 2,
  "mediaType": "application/vnd.oci.image.index.v1+json",
  "manifests": [
    {
      "mediaType": "application/vnd.oci.image.manifest.v1+json",
      "digest": "sha256:a42bc525fcf382ea7160b037fe72444dc5a415bf8c874e9432814d22ddb61dda",
      "size": 668,
      "platform": {
        "architecture": "amd64",
        "os": "linux"
      }
    },
    {
      "mediaType": "application/vnd.oci.image.manifest.v1+json",
      "digest": "sha256:8c57cad131a6458bc17679475de6d9dd2fd5da21e4ee88a1e52774722b210652",
      "size": 668,
      "platform": {
        "architecture": "arm64",
        "os": "linux"
      }
    },
    {
      "mediaType": "application/vnd.oci.image.manifest.v1+json",
      "digest": "sha256:05774b462cb207aa3dded9d0d9c9943054c6aa26a29eec6ea13a9969974af1be",
      "size": 914,
      "annotations": {
        "vnd.docker.reference.digest": "sha256:a42bc525fcf382ea7160b037fe72444dc5a415bf8c874e9432814d22ddb61dda",
        "vnd.docker.reference.type": "attestation-manifest"
      },
      "platform": {
        "architecture": "unknown",
        "os": "unknown"
      }
    },
    {
      "mediaType": "application/vnd.oci.image.manifest.v1+json",
      "digest": "sha256:8a24f3af5c1700021ad0cccb6d3bc0880d6c6bd2ba15b493e81d237d68166ddf",
      "size": 914,
      "annotations": {
        "vnd.docker.reference.digest": "sha256:8c57cad131a6458bc17679475de6d9dd2fd5da21e4ee88a1e52774722b210652",
        "vnd.docker.reference.type": "attestation-manifest"
      },
      "platform": {
        "architecture": "unknown",
        "os": "unknown"
      }
    }
  ]
}
`linux/amd64` manifest (`oci-artifact=true`)
oras manifest fetch --pretty --platform linux/amd64 localhost:5000/hello/world:test-t
{
  "schemaVersion": 2,
  "mediaType": "application/vnd.oci.image.manifest.v1+json",
  "config": {
    "mediaType": "application/vnd.oci.image.config.v1+json",
    "digest": "sha256:22a3cd305250e171afdb759a5494bd2cb30412583217904d33126de010411075",
    "size": 821
  },
  "layers": [
    {
      "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
      "digest": "sha256:f18232174bc91741fdf3da96d85011092101a032a93a388b79e99e69c2d5c870",
      "size": 3642247
    },
    {
      "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
      "digest": "sha256:935e4938154b3cc8b5d6c92b652110cca3295483871f9b08f4f01ae8960989b6",
      "size": 139
    }
  ]
}
OCI artifact (_with `subject` referring to a manifest with `platform` attribute_)
oras manifest fetch --pretty \
localhost:5000/hello/world@sha256:05774b462cb207aa3dded9d0d9c9943054c6aa26a29eec6ea13a9969974af1be
{
  "schemaVersion": 2,
  "mediaType": "application/vnd.oci.image.manifest.v1+json",
  "artifactType": "application/vnd.docker.attestation.manifest.v1+json",
  "config": {
    "mediaType": "application/vnd.oci.empty.v1+json",
    "digest": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a",
    "size": 2,
    "data": "e30="
  },
  "layers": [
    {
      "mediaType": "application/vnd.in-toto+json",
      "digest": "sha256:b4c552c500c2e7573cf57439097ab8ee8a7d7133297dcd66c1389af411e4b9f0",
      "size": 1017,
      "annotations": {
        "in-toto.io/predicate-type": "https://slsa.dev/provenance/v0.2"
      }
    }
  ],
  "subject": {
    "mediaType": "application/vnd.oci.image.manifest.v1+json",
    "digest": "sha256:a42bc525fcf382ea7160b037fe72444dc5a415bf8c874e9432814d22ddb61dda",
    "size": 668,
    "platform": {
      "architecture": "amd64",
      "os": "linux"
    }
  }
}

@polarathene
Copy link
Author

My request is to ignore is unrelated to the Docker annotations, but the fact that AFAIK there is no user-facing value of:

Understood, but that's the data coming from the image itself. If the image builder decided to use "unknown" I think we should show it as is.

For reference Docker attestation docs detail their Docker specific annotations and image index usage with attestations using unknown/unknown platform:

Image

It rather clearly states the intention is to prevent pulling. It's only purpose was to assist traversal/discover prior to supporting oci-artifact=true with referrers API / tag schema discovery.

andaaron added a commit to andaaron/zot that referenced this issue Mar 12, 2025
As side effect the warnings mentioned in project-zot/zui#475 (comment) should no longer show up.

Signed-off-by: Andrei Aaron <[email protected]>
andaaron added a commit to andaaron/zot that referenced this issue Mar 12, 2025
As side effect the warnings mentioned in project-zot/zui#475 (comment) should no longer show up.

Signed-off-by: Andrei Aaron <[email protected]>
andaaron added a commit to andaaron/zot that referenced this issue Mar 12, 2025
As side effect the warnings mentioned in project-zot/zui#475 (comment) should no longer show up.

Signed-off-by: Andrei Aaron <[email protected]>
andaaron added a commit to andaaron/zot that referenced this issue Mar 13, 2025
As side effect the warnings mentioned in project-zot/zui#475 (comment) should no longer show up.

Signed-off-by: Andrei Aaron <[email protected]>
andaaron added a commit to project-zot/zot that referenced this issue Mar 13, 2025
chore: update image-spec and dist-spec to v1.1.1

As side effect the warnings mentioned in project-zot/zui#475 (comment) should no longer show up.

Signed-off-by: Andrei Aaron <[email protected]>
@rchincha rchincha added the bug Something isn't working label Mar 19, 2025
@rchincha rchincha added the rm-external External roadmap item label Mar 19, 2025
@andaaron
Copy link
Contributor

Some fixes for these issues #477 and project-zot/zot#3023.
The other issue mentioned in Additional context still need to be evaluated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working rm-external External roadmap item
Projects
None yet
Development

No branches or pull requests

3 participants