The Rise of OCI Artifacts: From Images to Anything
OCI's image and distribution specs now carry Helm charts, SBOMs, signatures, Wasm modules and model weights — not just container images. Here is how media types, the referrers API and ORAS turn any registry into a universal artifact store.
Published on • November 15, 2026
AI Assistant

For ten years, a container registry held exactly one kind of thing: images. You pushed a manifest, the manifest pointed at layers, and the kubelet pulled it. The Open Container Initiative started by formalizing that image format, then quietly discovered that the format was never really about images at all — it was about content-addressed blobs plus JSON metadata. Once you look at it that way, charts, SBOMs, signatures, Wasm modules and model weights are all just descriptors with unusual media types. This post walks through the specs that made that possible, the referrers API that ties artifacts to their subjects, and the tooling and caveats you hit when you actually run a registry as a general-purpose artifact store.
From image format to content format
The OCI Image Format spec defines a small, rigid set of JSON documents: a descriptor (media type, digest, size, optional annotations), a manifest (config descriptor + layer descriptors), and an image index (a list of manifests, used for multi-arch builds). Version 1.0 of the spec was essentially a cleanup of the Docker image format, and that rigidity was the point — every container engine on earth could parse it.
OCI image-spec 1.1 bent that rigidity in three deliberate ways:
artifactType— a first-class field on the manifest that says what the thing is, independently of its config media type.subject— a descriptor pointing at another manifest, which is how an SBOM says “I describe this image.”- The empty config media type
application/vnd.oci.empty.v1+json— a canonical placeholder so an artifact doesn’t have to pretend it has an image config withEnvandEntrypointfields.
The repository’s artifacts-guidance.md documents the resulting pattern: an artifact is an ordinary image manifest whose config is the empty type, whose “layers” are arbitrary blobs, and whose artifactType carries the semantics. Nothing about the wire format changed; the interpretation did. That decision is why artifact support landed in every existing registry implementation instead of requiring a parallel protocol.
Media types are the contract
Once manifests can hold anything, the media type is the entire contract between producer and consumer. Nobody parses your blob unless the media type tells them to. Conventions that are actually in use today:
| What | Media type | Notes |
|---|---|---|
| Helm chart config | application/vnd.cncf.helm.config.v1+json | chart.yaml as the “image config” |
| Helm chart content | application/vnd.cncf.helm.chart.content.v1.tar+gzip | the tgz as a layer |
| SPDX SBOM | application/spdx+json | commonly attached via oras attach or cosign |
| CycloneDX SBOM | application/vnd.cyclonedx+json | same pattern, different schema |
| in-toto attestation | application/vnd.in-toto+json | predicate wrapped in an in-toto statement |
| cosign signature | application/vnd.dev.cosign.simplesigning.v1+json | payload is a simple signing JSON |
| Wasm module/component | application/wasm | IANA-registered type, pushed like any blob |
Two rules keep this from becoming a swamp. First, put semantics in artifactType, not in tags — tags are mutable pointers for humans, digests and artifact types are the machine-readable truth. Second, never invent a media type when an established one exists; consumers from oras to Harbor’s UI to cosign all switch behavior on those strings.
The referrers API: how an artifact finds its subject
Attaching is easy; discovering is the hard part. Before distribution-spec 1.1, the working hack was to encode the subject digest in a tag (sha256-<hex>), which meant listing tags and string-matching — fragile, and it polluted the tag namespace.
The referrers API replaced that with a proper endpoint:
GET /v2/acme/payments/referrers/sha256:9a1b7c... HTTP/1.1
Accept: application/vnd.oci.image.index.v1+json
The registry answers with an image index containing descriptors for every manifest whose subject matches the digest, optionally filtered by ?artifactType=:
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.index.v1+json",
"manifests": [
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:44f1b0...",
"size": 566,
"artifactType": "application/spdx+json"
}
]
}
Registries that predate the API may fall back to the tag scheme, which is why clients like oras implement both and prefer referrers when the registry advertises support. When you evaluate a registry for artifact work — self-hosted Harbor, your cloud provider’s service, GHCR — this endpoint is the feature to test first.
ORAS: the client for registries-as-storage
ORAS (OCI Registry As Storage) is the de facto CLI and Go/Java/Python SDK for non-image content. The mental model is “git for blobs”:
# Push an artifact with an explicit artifact type
oras push ghcr.io/acme/charts/api-server:1.4.2 \
--artifact-type application/vnd.cncf.helm.config.v1+json \
config.json:application/vnd.cncf.helm.config.v1+json \
chart.tgz:application/vnd.cncf.helm.chart.content.v1.tar+gzip
# Attach an SBOM to an image digest (referrers API, tag fallback)
oras attach ghcr.io/acme/payments@sha256:9a1b7c... \
--artifact-type application/spdx+json \
sbom.spdx.json
# Walk the relationship graph
oras discover ghcr.io/acme/payments@sha256:9a1b7c... -o tree
oras tree ghcr.io/acme/payments:1.4.2
Notice what is not in that workflow: no new server, no database, no per-artifact service to run. Auth stays the same bearer-token flow, caching and mirroring keep working, and your existing retention and RBAC policies apply because, to the registry, this is just more content.
Where this is actually used
The supply chain was the forcing function. Signing with cosign and generating SBOMs both need to bind a document to an image digest; OCI 1.1 made registries the natural place to store those bindings, and image verification increasingly happens at pull time — containerd 2.x, for example, added image verifier plugins that can reject pulls of unsigned images.
Helm moved its chart distribution to OCI registries (helm push / helm pull oci://...), which let teams retire chartmuseum instances and reuse the registry they already back up. On the AI side, projects like Sylabs’ modelpack push model weights as ORAS artifacts, treating a multi-gigabyte checkpoint as just another blob with a model-specific artifactType. Wasm toolchains do the same for components, which is how SpinKube-style workloads get their artifacts out of a registry rather than a bespoke server.
Practical limits and gotchas
- Support is uneven. Referrers API conformance varies by registry and version. Test
GET /v2/<name>/referrers/<digest>before designing around it. - Retention and GC interact badly with
subjectlinks. Delete an image and its referrers can be orphaned — or, with aggressive retention rules, deleted out from under a consumer. Harbor’s retention policies and your registry’s garbage collection need an explicit story for attached artifacts. - Big blobs stress registries. A 40 GB model weight hits upload timeouts, proxy body-size limits and chunked-upload quirks that a 200 MB image never triggered. Most registries were tuned for image-shaped content.
- The auth model is repository-scoped. You can lock down
acme/paymentsoracme/charts, but you cannot grant “read SBOMs, nothing else” without splitting repositories. - Tags remain mutable. Anything that must be tamper-evident should be resolved by digest and verified by signature, not trusted because a tag says so.
Wrapping up
OCI did not set out to build a general artifact store; it set out to stop the world from having two container image formats, and the descriptor/manifest design turned out to generalize further than anyone expected. The registries you already operate — with the caching, replication, RBAC and audit logs that took years to get right — are now your content distribution layer for everything else. Before standing up a new service to ship charts or SBOMs or model weights, check whether your registry already does it.