You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs: replace asset annotations with OCI ownership referrer
<!-- markdownlint-disable MD041 -->
Updates §6.3 of the OCI storage backend spec to trace assets to their
owning Component Version via a separate *ownership referrer* manifest
(linked through the OCI `subject` field), instead of mutating the
artifact with annotations. This matches ADR 0015 and keeps the
artifact's digest and any existing OCI signatures intact.
- Defines the referrer manifest (artifact type
`application/vnd.ocm.software.ownership.v1+json`, empty config/layer,
same repository as the artifact) and discovery via the OCI Referrers
API with tag-schema fallback.
- Rewrites integrity (§6.3.2) and verification (§6.3.3) around the
referrer; drops the obsolete `software.ocm.base.digest` annotation
and the `ociArtifactDigest/v1` annotation-stripping normalization.
- Requires referrers to travel with the artifact across registries and
OCI Image Layouts.
<!--
Usage: `Fixes #<issue number>`, or `Fixes (paste link of issue)`.
-->
Fixes: open-component-model/ocm-project#1031
Signed-off-by: Piotr Janik <piotr.janik@sap.com>
*[8. Component Index (Referrer Anchor)](#8-component-index-referrer-anchor)
35
34
*[8.1 Requirements](#81-requirements)
@@ -330,15 +329,58 @@ An index representing a component version:
330
329
331
330
### 6.3 Asset Annotations
332
331
333
-
When an OCI artifact (e.g., an OCI manifest or OCI index) is imported into a Component Version as a `resource` or `source`, OCM implementations **MAY**automatically add annotations to the artifact’s top-level manifest or index.
332
+
When an OCI artifact (e.g., an OCI manifest or OCI index) is imported into a Component Version as a `resource` or `source`, OCM implementations **MAY**publish a separate OCI manifest, the _ownership referrer_, that carries asset annotations and is linked to the artifact via the OCI [`subject`](https://github.com/opencontainers/image-spec/blob/v1.1.0/manifest.md#image-manifest-property-descriptions) field.
334
333
These annotations allow consumers to derive which Component Version now started shipping the artifact,
335
334
and which artifact within that Component Version is referencing this image, thus providing a form of "asset location".
336
335
336
+
The referrer is discovered through the OCI [Referrers API](https://github.com/opencontainers/distribution-spec/blob/v1.1.1/spec.md#listing-referrers), which returns every manifest in a repository whose `subject` points at a given artifact. OCM marks its referrers with the artifact type `application/vnd.ocm.software.ownership.v1+json`: a small OCI manifest with no payload, used only to carry the asset annotations and link to the artifact.
337
+
337
338
These annotations are optional and **MUST NOT** affect any descriptor selection, or resolution semantics elsewhere in this specification.
338
339
340
+
The original artifact **MUST NOT** be modified. The artifact digest recorded in the Component Descriptor **MUST** remain identical to the digest produced before annotations were attached.
341
+
342
+
The ownership referrer is a standard OCI image manifest with the following shape:
***MUST** use `artifactType``application/vnd.ocm.software.ownership.v1+json`.
377
+
***MUST** set `subject` to the descriptor of the artifact's top-level manifest or index, using the unmodified artifact digest.
378
+
***MUST** be pushed into the same repository as the artifact.
379
+
***MUST** use the standard OCI empty `config` and a single empty `layers` entry per [OCI artifact guidance](https://github.com/opencontainers/image-spec/blob/v1.1.0/manifest.md#guidelines-for-artifact-usage).
380
+
339
381
#### 6.3.1 Normative Keys
340
382
341
-
Writers **MAY** add the following annotations:
383
+
Writers **MAY** add the following annotations to the ownership referrer:
Annotation values for `software.ocm.artifact`**MUST** be JSON-encoded strings because OCI annotation maps permit only string values.
373
415
The JSON-encoded string **SHOULD** be canonicalized as per [JCS (RFC 8785)](https://www.rfc-editor.org/rfc/rfc8785) to ensure stable formatting.
374
416
375
-
Annotations **MUST** be written to the **top-level descriptor** of the OCI artifact:
376
-
377
-
* For manifest-based artifacts → `manifest.annotations`
378
-
* For index-based artifacts → `index.annotations`
379
-
380
-
Annotations **MUST NOT** be added to nested manifests or indexes within an artifact.
381
-
Only the top-level descriptor **MAY** carry these annotations.
417
+
Annotations **MUST** be written to the **top-level descriptor** of the ownership referrer (`manifest.annotations`).
418
+
Annotations **MUST NOT** be added to the original artifact, nor to nested manifests within the referrer.
382
419
383
420
#### 6.3.2 Integrity Requirements
384
421
385
422
To avoid mutating immutable artifacts:
386
423
387
-
1. If the artifact is newly created during import, for example during component creation,
388
-
writers **MAY** inject annotations freely.
389
-
In annotations are added on demand, writers **SHOULD** signal that the original digest was modified during import.
390
-
391
-
2. If the artifact already exists in a different location and modifying annotations would change its digest,
392
-
writers **SHOULD NOT** add or modify annotations.
393
-
If they do, the origin digest **SHOULD** be preserved with the annotation `software.ocm.base.digest="<original-digest>"`.
394
-
In case of existing component version signatures, writers **SHOULD** reattest the modified artifact and its owning component version.
395
-
In case an artifact is annotated multiple times, each annotation event **MUST** preserve the original digest in `software.ocm.base.digest`.
396
-
397
-
To ensure integrity, verifiers **MAY** decide to ignore annotations when verifying signatures or digests (see [6.3.3 Verification of annotated artifacts](#633-verification-of-annotated-artifacts)).
398
-
The process to verify signatures **MUST** remain consistent regardless of annotation presence.
424
+
1. The original artifact **MUST NOT** be modified. Its digest **MUST** remain identical to the digest produced before the ownership referrer was attached.
425
+
2. The ownership referrer **MUST** be a separate OCI manifest pushed into the same repository as the artifact, linked to it via the OCI `subject` field.
426
+
3. Existing OCI-level signatures over the artifact **MUST** remain valid because the artifact bytes are unchanged.
427
+
4. A single artifact **MAY** carry multiple ownership referrers when several Component Versions ship the same artifact.
399
428
400
429
#### 6.3.3 Verification of annotated artifacts
401
430
402
-
When artifacts carry OCM-specific informational annotations, verifiers **MAY** ignore these annotations during verification.
403
-
Doing so enables stable, annotation-independent digests and signatures.
404
-
405
-
To perform verification in an annotation-tolerant way, verifiers **MAY** apply the following procedure:
406
-
407
-
1. Retrieve the artifact manifest or index and verify its digest and signatures as usual.
408
-
2. Check whether the artifact includes OCM-specific annotations such as
409
-
`software.ocm.component.name`, `software.ocm.component.version`, or `software.ocm.artifact`.
410
-
3. If such annotations exist, create an in-memory copy of the artifact descriptor with these annotations removed.
411
-
4. Recompute the descriptor digest. This digest **MUST** match the value recorded in `software.ocm.base.digest`.
412
-
5. This recomputed digest **MAY** then be used for signature verification in place of the original artifact digest.
413
-
414
-
This mechanism enables signature verification to remain stable regardless of the presence or absence of OCM-specific informational annotations.
415
-
It also preserves the original component version digest when verifiers choose to ignore those annotations.
416
-
417
-
This behavior is optional. Verifiers **MAY** instead choose to validate the artifact exactly as stored, including all annotations.
418
-
If so, both the digest and signatures **MUST** correspond to the annotated artifact, and any modification or addition of annotations **MUST** trigger re-signing.
419
-
420
-
#### 6.3.4 `ociArtifactDigest/v1` Normalization
421
-
422
-
Based on the annotations defined above, an extension to the normalisation algorithm [`ociArtifactDigest/v1`](../04-algorithms/artifact-normalization-types.md) is defined.
To verify that an ownership referrer is authentic, clients **MUST**:
451
432
452
-
OCI manifest annotations based on `sha256:64b586a57294adc5749324d0574df23499555de5168b4b1f1bd7ce9b06e2d49f` (informational, not normalized):
433
+
1. Query the [OCI Referrers API](https://github.com/opencontainers/distribution-spec/blob/v1.1.1/spec.md#listing-referrers) for the artifact digest, filtered by `artifactType=application/vnd.ocm.software.ownership.v1+json`. Registries that do not support the Referrers API **MUST** be queried via the [referrers tag schema](https://github.com/opencontainers/distribution-spec/blob/v1.1.1/spec.md#unavailable-referrers-api) (`<algorithm>-<hex>` tag).
3. Confirm `software.ocm.component.name` and `software.ocm.component.version` match the expected Component Version.
484
438
485
-
Because the digest now ignores the annotations, the value corresponds to the base artifact without OCM-specific annotations.
486
-
As the annotations were added after the component signature, the signature contains the value `abcd1234efgh5678ijkl9012mnopqrstuvwx3456yzab7890cdef1234abcd5678`.
487
-
But because the client ignores the annotations during verification, the signature **MAY** still be verified, as
488
-
the digest based on `software.ocm.base.digest` matches the signed content and is integral.
439
+
When transferring Component Versions between OCI registries or into an OCI Image Layout, implementations **MUST** carry ownership referrers alongside the artifact and maintain the tag fallback where applicable.
0 commit comments