org.opencontainers.image.source is a standardized OCI image label whose value is the URL of the source repository an image was built from — and setting it is the cheapest provenance win available in container builds. It is one of the pre-defined annotation keys in the OCI Image Format Specification, and registries and scanners increasingly treat it as the authoritative pointer from a binary artifact back to its code. If you maintain images and this label is missing, consumers of your image are guessing where it came from; if you consume images, its absence is a signal worth noticing.
Where the key comes from
The Open Container Initiative (OCI) Image Format Specification defines a set of pre-defined annotation keys under the org.opencontainers.image.* namespace. They superseded the older community convention, org.label-schema.* (Label Schema), which is deprecated. The commonly used keys:
| Key | Meaning |
|---|---|
org.opencontainers.image.source | URL of the source repository (e.g., a Git hosting URL) |
org.opencontainers.image.revision | Source control revision (typically the Git commit SHA) |
org.opencontainers.image.created | Build date/time, RFC 3339 format |
org.opencontainers.image.url | URL to find more information |
org.opencontainers.image.version | Version of the packaged software |
org.opencontainers.image.licenses | SPDX license expression |
org.opencontainers.image.title / .description | Human-readable name and description |
org.opencontainers.image.vendor / .authors | Who distributes and who wrote it |
org.opencontainers.image.base.name / .base.digest | Reference and digest of the base image |
Together, source + revision + created answer the three provenance questions every incident responder asks about a running container: what code, which commit, built when.
Labels vs. annotations: the distinction that trips people up
The OCI spec defines these keys for two related but different places:
- Labels live in the image config (what a
LABELinstruction in a Dockerfile produces). They travel inside the image and show up indocker inspect. - Annotations live on the image manifest or index — metadata attached at the registry layer, settable by tools like
docker buildxororaswithout touching the filesystem layers.
The same org.opencontainers.image.* keys are used in both. Most tooling reads labels; newer registry-native tooling also reads manifest annotations. Setting the keys as labels is the compatible baseline; adding them as manifest annotations too (buildx supports --annotation) is a bonus for registry-side consumers.
Setting the labels in practice
Dockerfile, hard-coded (fine for simple cases)
FROM alpine:3.20
LABEL org.opencontainers.image.source="https://github.com/acme/payments-api" \
org.opencontainers.image.description="Payments API service" \
org.opencontainers.image.licenses="Apache-2.0"
Dockerfile with build args (better: revision changes per build)
ARG GIT_SHA
ARG BUILD_DATE
LABEL org.opencontainers.image.source="https://github.com/acme/payments-api" \
org.opencontainers.image.revision=$GIT_SHA \
org.opencontainers.image.created=$BUILD_DATE
docker build \
--build-arg GIT_SHA="$(git rev-parse HEAD)" \
--build-arg BUILD_DATE="$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
-t ghcr.io/acme/payments-api:latest .
CI-injected labels (best: nothing to maintain in the Dockerfile)
docker build --label and buildx set labels at build time without a LABEL line. In GitHub Actions, docker/metadata-action generates the full OCI set automatically from repository context, and docker/build-push-action applies it. This is the pattern to standardize on in shared pipelines: label correctness stops depending on every team's Dockerfile hygiene.
Verify the result:
docker inspect --format '{{ index .Config.Labels "org.opencontainers.image.source" }}' \
ghcr.io/acme/payments-api:latest
What the label unlocks
Registry linking — the GHCR effect
GitHub Container Registry is the highest-profile consumer: when an image pushed to GHCR carries org.opencontainers.image.source pointing at a GitHub repository, GHCR connects the package to that repository — the package page links to the repo, the README renders alongside the image, and (for repo-linked packages) access management can follow the repository. Many maintainers first meet this label as "the thing you set so your GHCR package shows up attached to your repo." Other registries and artifact platforms read the same key for display and linking.
Provenance during incident response
When a vulnerability drops and you have five hundred distinct images running in production, the difference between labeled and unlabeled fleets is measured in hours. With source and revision set, "which commit built the vulnerable image, and does main already contain the fix?" is a one-line query against image metadata. Without them, it is an archaeology project through CI logs.
Supply chain and scanner context
Vulnerability scanners and SCA platforms use source labels to enrich findings — mapping an image finding back to a repository means the fix can be routed to the owning team and the offending manifest, instead of dead-ending at an opaque digest. A platform such as Safeguard, for example, correlates image-level findings with the linked repository's dependency manifests when the source label is present, which turns "this image is vulnerable" into "this line in this lockfile is why."
Base-image keys (base.name, base.digest) matter here too: they let tooling distinguish "vulnerability inherited from the base image — fix by rebasing" from "vulnerability introduced by your layers."
The honest limits: labels are claims, not proof
A label is a self-declared string. Anyone can build a malicious image and stamp it with org.opencontainers.image.source: https://github.com/kubernetes/kubernetes. Nothing in the OCI spec verifies it. So treat labels as provenance hints with excellent effort-to-value ratio, and layer verifiable mechanisms on top where the threat model demands it:
- Signing (Sigstore Cosign or Notation) proves who published the image.
- Attested provenance (SLSA provenance documents, in-toto attestations) cryptographically binds the artifact to the builder, source repo, and commit — the verified version of what the label merely asserts.
- SBOM attachments describe what is inside, complementing where it came from.
The practical posture for most teams: require the labels everywhere (they cost nothing and help every day), and require signatures/attestations for images crossing trust boundaries — anything pulled from outside, or anything you publish for others.
Enforcing it across a fleet
Standards that rely on memory decay. Options that actually hold:
- Central CI templates that inject the labels via metadata actions or shared build scripts — teams inherit correctness.
- Admission or pipeline policy: a Conftest/OPA rule or registry-side check that rejects images missing
org.opencontainers.image.sourceandrevision. Keep the failure message instructive. - Periodic fleet audit: iterate your registry, inspect configs, and report unlabeled images by team. Pair the report with the one-line fix and adoption follows quickly.
If you are building out broader pipeline provenance — signing, SBOMs, attestation verification — labels are step zero, and the same rollout playbook covers the rest. Our supply chain learning track walks through the full progression from labels to SLSA-style attestations.
FAQ
What is org.opencontainers.image.source used for?
It records the URL of the source repository an image was built from. Registries (notably GitHub Container Registry) use it to link the image to its repository, and scanners and provenance tooling use it to map findings and artifacts back to code.
Is org.opencontainers.image.source a label or an annotation?
Both uses exist. The OCI spec defines the key for manifest annotations, and the same key is conventionally set as an image config label via Dockerfile LABEL or docker build --label. Setting it as a label is the widely compatible baseline.
Does setting the label prove where an image came from?
No. Labels are unverified, self-declared metadata — useful hints, not proof. For verifiable provenance, add image signing (e.g., Cosign) and build attestations (SLSA/in-toto) on top of the labels.
What replaced org.label-schema.* labels?
The org.opencontainers.image.* keys defined by the OCI Image Format Specification. Label Schema (org.label-schema.*) is deprecated, and most of its keys have direct OCI equivalents.