Skip to content

feat(hip): OCI Artifact Selection and Referrers Support#424

Open
lexfrei wants to merge 2 commits intohelm:mainfrom
lexfrei:hip/oci-artifact-selection
Open

feat(hip): OCI Artifact Selection and Referrers Support#424
lexfrei wants to merge 2 commits intohelm:mainfrom
lexfrei:hip/oci-artifact-selection

Conversation

@lexfrei
Copy link

@lexfrei lexfrei commented Nov 29, 2025

Summary

This HIP proposes three related enhancements to Helm's OCI support:

  1. Artifact Selection from Image Index - Enable helm pull/install/dependency to select chart manifests from OCI Image Index by artifactType (with config.mediaType fallback)

  2. Set artifactType on Push - Have helm push set the artifactType field in manifests for efficient selection

  3. Referrers API Support - Add --subject flag to helm push for associating charts with container images

Motivation

Current workarounds for publishing charts and images together (tag suffixes like :v1.0.0-helm, separate paths) are unnecessary complexity. OCI 1.1 provides native artifact bundling - Helm should leverage it.

Related

Checklist

  • HIP follows the template from HIP-0001
  • HIP is in draft status
  • Reference implementation exists

This HIP proposes enabling Helm to:
1. Select chart manifests from OCI Image Index by artifactType
2. Set artifactType field when pushing charts
3. Support Referrers API via --subject flag

Addresses helm/helm#31582

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>

When `helm pull`, `helm install`, or `helm dependency update` encounters an OCI reference that resolves to an Image Index (`application/vnd.oci.image.index.v1+json`), Helm MUST select a chart manifest using the following algorithm:

1. **First pass**: Iterate through descriptors in `manifests[]` and check for `artifactType: application/vnd.cncf.helm.config.v1+json`

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't around for the helm OCI implementation, so I don't know the thinking, but I assumed application/vnd.cncf.helm.config.v1+json represented the format of the config blob. If that is the case, it is almost as if there would need to be a new type something like application/vnd.cncf.helm.manifest.v1+json

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're correct that application/vnd.cncf.helm.config.v1+json represents the config blob format. However, using the same value for artifactType is intentional per OCI spec.

The OCI Image Spec (descriptor.md) explicitly defines artifactType in Index descriptors as:

"This is the value of the config descriptor mediaType when the descriptor references an image manifest."

This design allows clients to select manifests from an Image Index without fetching them first - the artifactType in the descriptor tells you what kind of artifact it is by exposing the config.mediaType value at the Index level.

So the equality artifactType == config.mediaType is by design, not a naming collision:

  • In Image Index descriptor: artifactType = identifier for selection
  • In Image Manifest: config.mediaType = format of the config blob

Both happen to have the same value because OCI spec defines it that way. Creating a separate type like application/vnd.cncf.helm.manifest.v1+json would contradict the OCI artifact model and require IANA registration for no functional benefit.

Reference: https://github.com/opencontainers/image-spec/blob/main/descriptor.md#properties

2. **Second pass** (fallback): If no match in first pass, iterate through descriptors WITHOUT a `platform` field:
- Fetch the referenced manifest
- Check if `config.mediaType` equals `application/vnd.cncf.helm.config.v1+json`
- If exactly one manifest matches, select it

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would think this would search for the first layer mediaType that is application/vnd.cncf.helm.chart.content.v1.tar+gzip

Copy link
Author

@lexfrei lexfrei Dec 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Layer mediaTypes are not exposed in Image Index descriptors - only these fields are available at the Index level:

  • mediaType (of the manifest itself, always application/vnd.oci.image.manifest.v1+json)
  • digest, size
  • platform (for container images)
  • artifactType (for artifacts, OCI 1.1+)
  • annotations

To check layers[].mediaType, we would need to fetch every manifest in the Index first, then inspect each one. This defeats the purpose of efficient artifact selection.

The OCI artifact model specifically uses artifactType (derived from config.mediaType) because it's available at the Index level without additional round-trips.

Example Index descriptor:

{
  "mediaType": "application/vnd.oci.image.manifest.v1+json",
  "digest": "sha256:def456...",
  "size": 567,
  "artifactType": "application/vnd.cncf.helm.config.v1+json"
  // layers[] is NOT here - it's inside the manifest
}

The fallback path (checking config.mediaType when artifactType is absent) already requires fetching the manifest. Adding layer inspection would not improve selection accuracy but would add complexity.

Reference: https://github.com/opencontainers/image-spec/blob/main/image-index.md#image-index-property-descriptions

Address review feedback from TerryHowe:
- Explain why artifactType equals config.mediaType (per OCI spec)
- Explain why layer mediaType cannot be used for selection

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
Copy link
Contributor

@sabre1041 sabre1041 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a number of concerns related to this proposal, both in complexity as well as desire as a feature within Helm. Support for this feature would not only impact all Helm users given there may need to be additional logic implemented to traverse OCI manifests which could slow down the performance of Helm, but require the use of multiple tools outside the helm ecosystem just to implement it.

In addition, since Helm, by nature uses templating languages and parameters, the Image that is actually utilized within the chart may not be the same as the image the chart is attached to. Also, many charts contain references to multiple images. What logic can be employed to suggest whether a chart should be associated to one image or another.

I am very interested in the desire for others in the community to support such a feature. Until there is a marked need, I would recommend holding off until such a time where demand does grow.


## Abstract

This proposal enables Helm to select chart manifests from OCI Image Index manifests and adds support for the OCI Referrers API. Currently, `helm pull` fails when encountering an OCI Image Index containing multiple artifacts. This HIP introduces artifact selection logic based on the `artifactType` field (with fallback to `config.mediaType`), sets `artifactType` during `helm push`, and optionally allows charts to be associated with container images via the `subject` field and Referrers API.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This proposal enables Helm to select chart manifests from OCI Image Index manifests and adds support for the OCI Referrers API. Currently, `helm pull` fails when encountering an OCI Image Index containing multiple artifacts. This HIP introduces artifact selection logic based on the `artifactType` field (with fallback to `config.mediaType`), sets `artifactType` during `helm push`, and optionally allows charts to be associated with container images via the `subject` field and Referrers API.
This proposal enables Helm to select chart manifests from OCI Image Index manifests and adds support for the OCI Referrers API. Currently, `helm pull` fails when encountering an OCI Image Index containing multiple artifacts. This HIP introduces artifact selection logic based on the `artifactType` field (with fallback to `config.mediaType`), sets `artifactType` during `helm push`, and optionally allows charts to be associated with container images via the `subject` field and the Referrers API.

- Separate repository paths (e.g., `registry/app` for image, `registry/app-chart` for chart)
- Completely separate registries

These workarounds introduce unnecessary complexity in CI/CD pipelines, break atomic versioning guarantees, and require additional tooling to keep artifacts synchronized. Tools like ArtifactHub, ArgoCD, and GitOps workflows would benefit from a single source of truth for versioned artifacts.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
These workarounds introduce unnecessary complexity in CI/CD pipelines, break atomic versioning guarantees, and require additional tooling to keep artifacts synchronized. Tools like ArtifactHub, ArgoCD, and GitOps workflows would benefit from a single source of truth for versioned artifacts.
These workarounds introduce unnecessary complexity in CI/CD pipelines, break atomic versioning guarantees, and require additional tooling to keep artifacts synchronized. Tools like ArtifactHub, Argo CD, and GitOps workflows would benefit from a single source of truth for versioned artifacts.

- If exactly one descriptor matches, select it
- If multiple descriptors match, select the first one (per OCI spec)

2. **Second pass** (fallback): If no match in first pass, iterate through descriptors WITHOUT a `platform` field:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has the potential to be resource intensive iterating through all of the associated manifests associated within an index

Copy link

@JulesdeCube JulesdeCube Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should not be an issue because manifest index are fetch ether by digest (sha256:abcdef12345678...) or by tag (that are just alias of direct manifest or manifests index)

in any case manifest index should contain artifact for the same version so:

  • container image (we can consider that it don't go over 10 architectures)
  • deployment artifact (docker-compose, helm, ...)
  • the package application (npm, go package, dpkg, ...)

We have a maximum of 20 manifests that have a max size 4MB (defined in OCI 1.1 spec) this make the worse scenario 80MB of download. This is quite big but the worse case scenario.

Note that OCI 1.0 artifacts are usually link by tag. example for cosign:

An image with manifest sha256:abcdef12345678 will have it's sbom
at the tag sha256-abcdef12345678.sbom and it's signature at sha256-abcdef12345678.sig


This enables efficient selection from Image Index without fetching manifest content.

### 3. Referrers API Support
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if theres a chart associated within the index image as well as in the referrers API? Since its found in the list of manifests within the index, is the associated artifact via the referrers ignored (ie first found wins)?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that we should add referrers API support.

The main use case is to link a helm chart to a container image but:

  • helm chart can use multiple images and multiple tag of the same image and the OCI spec allow only one referrers, making referrers support at lease wonky
  • Multiple helm chart version can use the same image (repo/tag/digest). If we use referrers the image will have references to multiple helm chart. The OCI spec don't define any order in witch the referrers API should send manifests making choosing the "right" (probably the latest) helm chart at lease slow, if not conflicting.


When `helm pull`, `helm install`, or `helm dependency update` encounters an OCI reference that resolves to an Image Index (`application/vnd.oci.image.index.v1+json`), Helm MUST select a chart manifest using the following algorithm:

1. **First pass**: Iterate through descriptors in `manifests[]` and check for `artifactType: application/vnd.cncf.helm.config.v1+json`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that no changes should be made to the internal structure of the Helm chart itself (necessitating the need to register additional IANA types). This would require a HIP of its own

# Create Image Index combining both
crane index append \
--manifest registry.example.com/myapp:v1.0.0 \
--manifest registry.example.com/myapp:v1.0.0-helm \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this manifest reference does not align with the helm push command mentioned previously

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

helm chart use semver version without any v in front of it:

Suggested change
--manifest registry.example.com/myapp:v1.0.0-helm \
--manifest registry.example.com/myapp:1.0.0 \

@JulesdeCube
Copy link

I have a question that this HIP don't answer:

In case an image index or an other manifest already exist for the given tag
Is helm push should:

  • override a tag ?
  • update image index to add it's self ?
  • create new image index if config contentType isn't application/vnd.cncf.helm.config.v1+json ?

helm currently just override the tag but having a "smarter" logic don't seems to far fetch.

In case we don't want to implement this logic inside helm, helm should be able to push manifest without tag (As helm pull already work with digest)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants