| hip | 9999 | |
|---|---|---|
| title | OCI Artifact Selection and Referrers Support | |
| authors |
|
|
| created | 2025-11-29 | |
| type | feature | |
| status | draft |
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.
The OCI Image and Distribution specifications v1.1 (released February 2024) introduced native support for artifacts and the Referrers API. These features enable bundling multiple artifacts under a single OCI reference and establishing relationships between them.
Currently, users who want to publish both a Helm chart and a container image for the same application version must use workarounds:
- Tag suffixes (e.g.,
:v1.0.0for image,:v1.0.0-helmfor chart) - Separate repository paths (e.g.,
registry/appfor image,registry/app-chartfor 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.
The OCI 1.1 specifications provide a standard solution: an Image Index can contain multiple manifests with different artifactType values, and the Referrers API allows querying artifacts associated with a specific image. Helm should leverage these capabilities.
The OCI Image Specification explicitly states that "artifacts have historically been created without an artifactType field, and tooling to work with artifacts should fallback to the config.mediaType value." Following this guidance ensures compatibility with:
- Charts pushed by current Helm versions (which don't set
artifactType) - Charts pushed by third-party tools that may not set
artifactType - Registries that strip or don't preserve
artifactType
The OCI Image Spec (descriptor.md) explicitly defines artifactType in Index descriptors as "the value of the config descriptor mediaType when the descriptor references an image manifest." This equality is intentional — it exposes the artifact identifier at the Index level for efficient selection without fetching manifests. Using application/vnd.cncf.helm.config.v1+json for both fields is correct per OCI spec, not a naming collision.
Layer mediaTypes (e.g., application/vnd.cncf.helm.chart.content.v1.tar+gzip) are not exposed in Image Index descriptors — only mediaType, digest, size, platform, artifactType, and annotations are available. To check layers, Helm would need to fetch every manifest in the Index first, defeating the purpose of efficient artifact selection. The artifactType/config.mediaType approach provides artifact identification at the Index level without additional round-trips.
Descriptors with a platform field are container images targeted at specific architectures. A Helm chart is not platform-specific and should never have a platform field. Skipping these descriptors avoids unnecessary manifest fetches.
The OCI Image Index specification states: "If multiple manifests match a client or runtime's requirements, the first matching entry SHOULD be used." This behavior is consistent with multi-architecture image selection.
The Referrers API enables discovering all artifacts (charts, SBOMs, signatures) associated with a specific container image. For Helm, this allows:
- Finding the chart that deploys a specific image version
- Ensuring chart and image are always used together
- Enabling security scanning workflows that link vulnerabilities to deployment configurations
This HIP introduces three related changes:
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:
-
First pass: Iterate through descriptors in
manifests[]and check forartifactType: application/vnd.cncf.helm.config.v1+json- If exactly one descriptor matches, select it
- If multiple descriptors match, select the first one (per OCI spec)
-
Second pass (fallback): If no match in first pass, iterate through descriptors WITHOUT a
platformfield:- Fetch the referenced manifest
- Check if
config.mediaTypeequalsapplication/vnd.cncf.helm.config.v1+json - If exactly one manifest matches, select it
- If multiple manifests match, select the first one
-
Skip: Descriptors with a
platformfield SHOULD be skipped as they represent container images -
Error: If no matching chart manifest is found, return an error indicating no Helm chart was found in the Image Index
Example Image Index with multiple artifacts:
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.index.v1+json",
"manifests": [
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:abc123...",
"size": 1234,
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:def456...",
"size": 567,
"artifactType": "application/vnd.cncf.helm.config.v1+json"
}
]
}In this example, Helm would select the second descriptor (digest sha256:def456...) because it has the matching artifactType.
When helm push creates a manifest, it MUST set the artifactType field to application/vnd.cncf.helm.config.v1+json.
Current manifest structure:
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": {
"mediaType": "application/vnd.cncf.helm.config.v1+json",
"digest": "sha256:...",
"size": 137
},
"layers": [...]
}Proposed manifest structure:
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"artifactType": "application/vnd.cncf.helm.config.v1+json",
"config": {
"mediaType": "application/vnd.cncf.helm.config.v1+json",
"digest": "sha256:...",
"size": 137
},
"layers": [...]
}This enables efficient selection from Image Index without fetching manifest content.
A new optional flag --subject is added to helm push:
helm push mychart-1.0.0.tgz oci://registry.example.com/myapp --subject sha256:abc123...When --subject is specified, Helm MUST:
- Set the
subjectfield in the chart manifest to reference the specified digest:
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"artifactType": "application/vnd.cncf.helm.config.v1+json",
"subject": {
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:abc123...",
"size": 1234
},
"config": {...},
"layers": [...]
}- Handle the registry response according to OCI Distribution Spec 1.1:
- If registry returns
OCI-Subjectheader, the referrer is tracked automatically - If registry does not return
OCI-Subjectheader, fall back to Referrers Tag Schema
- If registry returns
The --subject flag accepts:
- A digest (e.g.,
sha256:abc123...) - An OCI reference that will be resolved to a digest (e.g.,
oci://registry.example.com/myapp:v1.0.0)
This proposal is fully backwards compatible:
- Single manifests: Charts stored as single manifests (not Image Index) continue to work unchanged
- Existing charts: Charts without
artifactTypeare still selectable viaconfig.mediaTypefallback - Registry compatibility:
artifactTypeis an optional field per OCI spec; registries MUST NOT error on unknown fields - Optional Referrers: The
--subjectflag is optional; existinghelm pushworkflows are unchanged
- No new attack vectors: Artifact selection uses the same validation logic applied after manifest fetch
- Referrers association is weak: The
subjectfield creates an association, not a cryptographic binding. Chart integrity still depends on digest verification - Registry trust model unchanged: Users must still trust the registry to serve correct manifests
- Update the OCI registry documentation on helm.sh to explain Image Index support
- Add examples showing how to create multi-artifact Image Index using tools like
craneororas - Document the
--subjectflag and Referrers API integration
# Push container image
docker push registry.example.com/myapp:v1.0.0
# Push Helm chart
helm push myapp-1.0.0.tgz oci://registry.example.com/myapp
# 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 \
--tag registry.example.com/myapp:v1.0.0
# Now helm pull works on the combined reference
helm pull oci://registry.example.com/myapp --version 1.0.0# Get image digest
IMAGE_DIGEST=$(crane digest registry.example.com/myapp:v1.0.0)
# Push chart with subject reference
helm push myapp-1.0.0.tgz oci://registry.example.com/myapp --subject $IMAGE_DIGEST
# Query referrers (using oras)
oras discover registry.example.com/myapp@$IMAGE_DIGESTA reference implementation is available at helm/helm#31583.
Rejected because it adds unnecessary verbosity to common operations. The artifact type is always application/vnd.cncf.helm.config.v1+json for Helm charts.
Rejected because it would break compatibility with existing charts and third-party tooling that doesn't set artifactType.
Rejected because most users don't need Referrers API integration. The feature should be opt-in.
Considered automatically detecting the "main" image in an Image Index and setting it as subject. Rejected because:
- Ambiguous when multiple images exist
- May not match user intent
- Explicit is better than implicit
-
Fetching chart via Referrers API: Should
helm pullsupport fetching a chart by image digest using the Referrers API? For example:helm pull --referrer-of oci://registry.example.com/myapp@sha256:abc123... -
Multiple charts per image: What should happen when multiple charts reference the same image via Referrers API? Current proposal: return all, let user select.