Skip to content

Latest commit

 

History

History
278 lines (196 loc) · 12 KB

File metadata and controls

278 lines (196 loc) · 12 KB
hip 9999
title OCI Artifact Selection and Referrers Support
authors
Aleksei Sviridkin <f@lex.la>
created 2025-11-29
type feature
status draft

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.

Motivation

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.0 for image, :v1.0.0-helm for chart)
  • 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.

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.

Rationale

Why artifactType first, then config.mediaType fallback?

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:

  1. Charts pushed by current Helm versions (which don't set artifactType)
  2. Charts pushed by third-party tools that may not set artifactType
  3. Registries that strip or don't preserve artifactType

Why artifactType equals config.mediaType

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.

Why not use layer mediaType for selection

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.

Why skip descriptors with platform field?

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.

Why use first match?

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.

Why add Referrers API support?

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

Specification

This HIP introduces three related changes:

1. Artifact Selection from Image Index

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

    • 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:

    • Fetch the referenced manifest
    • Check if config.mediaType equals application/vnd.cncf.helm.config.v1+json
    • If exactly one manifest matches, select it
    • If multiple manifests match, select the first one
  3. Skip: Descriptors with a platform field SHOULD be skipped as they represent container images

  4. 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.

2. Set artifactType on Push

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.

3. Referrers API Support

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:

  1. Set the subject field 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": [...]
}
  1. Handle the registry response according to OCI Distribution Spec 1.1:
    • If registry returns OCI-Subject header, the referrer is tracked automatically
    • If registry does not return OCI-Subject header, fall back to Referrers Tag Schema

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)

Backwards Compatibility

This proposal is fully backwards compatible:

  1. Single manifests: Charts stored as single manifests (not Image Index) continue to work unchanged
  2. Existing charts: Charts without artifactType are still selectable via config.mediaType fallback
  3. Registry compatibility: artifactType is an optional field per OCI spec; registries MUST NOT error on unknown fields
  4. Optional Referrers: The --subject flag is optional; existing helm push workflows are unchanged

Security Implications

  1. No new attack vectors: Artifact selection uses the same validation logic applied after manifest fetch
  2. Referrers association is weak: The subject field creates an association, not a cryptographic binding. Chart integrity still depends on digest verification
  3. Registry trust model unchanged: Users must still trust the registry to serve correct manifests

How to Teach This

Documentation Updates

  1. Update the OCI registry documentation on helm.sh to explain Image Index support
  2. Add examples showing how to create multi-artifact Image Index using tools like crane or oras
  3. Document the --subject flag and Referrers API integration

Example: Creating Multi-Artifact Image Index

# 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

Example: Associating Chart with Image

# 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_DIGEST

Reference Implementation

A reference implementation is available at helm/helm#31583.

Rejected Ideas

Requiring explicit --artifact-type flag

Rejected because it adds unnecessary verbosity to common operations. The artifact type is always application/vnd.cncf.helm.config.v1+json for Helm charts.

Only supporting artifactType without config.mediaType fallback

Rejected because it would break compatibility with existing charts and third-party tooling that doesn't set artifactType.

Making --subject mandatory

Rejected because most users don't need Referrers API integration. The feature should be opt-in.

Automatic subject detection

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

Open Issues

  1. Fetching chart via Referrers API: Should helm pull support fetching a chart by image digest using the Referrers API? For example: helm pull --referrer-of oci://registry.example.com/myapp@sha256:abc123...

  2. Multiple charts per image: What should happen when multiple charts reference the same image via Referrers API? Current proposal: return all, let user select.

References