Migrate Normalisation Algorithms
Goal
Move the signatures and component reference digests of your component versions to the current default normalisation
algorithm, jsonNormalisation/v4alpha3.
There is no urgency. Digests computed with older algorithms keep verifying, and so do component versions that mix
algorithms, for example a parent signed with jsonNormalisation/v4alpha3 that references children built with an older
OCM CLI. Migrate gradually, as part of your regular releases. You do not need to switch everything at once.
Why Migrate?
The normalisation algorithm decides which parts of a component descriptor a digest, and therefore a signature, covers. Older algorithms may cover less of the descriptor than the current default (see Normalization and Digest Calculation). OCM logs a warning whenever it relies on such a digest and you can act on it:
trusted digest was computed with an older normalisation algorithm: a signature checked byocm verify, or a digest pin.component reference digest was computed with an older normalisation algorithm: a component reference in your component constructor (ocm add cv), or of a component version you transfer (ocm transfer cv).signing with an older normalisation algorithm:ocm sign cv --normalisationwith an algorithm other than the default.
The OCM controller and ocm add cv, for the references of component versions published by others, log the same messages
at debug level only: these digests can only be upgraded by their publisher.
Why Re-Signing Alone Is Not Enough
A signature covers the component version it is attached to, and reaches the component versions it references only
through their component reference digests. Each reference digest is part of the referencing descriptor and is computed
with its own normalisation algorithm, when the referencing component version is built with ocm add cv. ocm sign
never changes reference digests.
So a tree is only as strongly covered as the weakest algorithm along each reference. Re-signing a root with the default upgrades its signature, but not the reference digests inside it, and not the references further down. To upgrade a tree, build and sign its component versions with a current OCM CLI.
Prerequisites
- A current OCM CLI, on every machine that builds, signs, transfers or verifies your component versions
- Your component constructors
Steps
1. Upgrade the consumers first
Component versions built with a current OCM CLI carry jsonNormalisation/v4alpha3 digests. An older OCM CLI or OCM
controller does not know that algorithm: it fails a recursive ocm transfer cv or a reference digest check with
unknown normalisation algorithm. Upgrade the OCM CLI in your pipelines and the OCM controllers that consume your
component versions before you publish the first migrated version.
2. Find what still uses an older algorithm
Look at the normalisationAlgorithm of the signatures and component references of a component version and the
component versions it references:
ocm get cv <repository>//<component>:<version> --recursive -o yaml \
| yq '.[] | {.component.name + ":" + .component.version: {"signatures": [.signatures[].digest.normalisationAlgorithm], "references": [.component.componentReferences[].digest.normalisationAlgorithm]}}'Anything other than jsonNormalisation/v4alpha3 is a candidate. The warnings listed above point to the same component
versions while you work with them.
3. Build the next release with a current OCM CLI
Build your next release of each component as usual, with a current OCM CLI. ocm add cv computes every component
reference digest that the constructor does not pin with the default. A digest you pin in the constructor is kept with
its algorithm, so remove pinned digests that use an older algorithm.
Build the referenced components before the components that reference them. Components you build in one
ocm add cv run are ordered for you. A referenced component version built and published by someone else keeps its own
references until its owner rebuilds it; your reference to it is upgraded either way.
Publish a new version instead of rebuilding an existing one. ocm add cv replaces an existing component version by
default. A rebuilt version has new reference digests and therefore a different digest, so existing pins and the
reference digests of component versions that reference it no longer match.
4. Sign with the default
Sign without --normalisation; the default is jsonNormalisation/v4alpha3:
ocm sign cv <repository>//<component>:<version> --signature <name>5. Check the result
ocm verify cv <repository>//<component>:<version> --signature <name>You should see SIGNATURE VERIFICATION SUCCESSFUL and no warning about an older normalisation algorithm. Older
references further down the tree are still reported by ocm transfer cv --recursive until their component versions are
rebuilt.
Troubleshooting
Symptom: unknown normalisation algorithm: jsonNormalisation/v4alpha3
Cause: The OCM CLI or OCM controller is older than the component version it reads.
Fix: Upgrade it (see step 1).
Symptom: reference digest uses a verify-only normalisation algorithm
Cause: The constructor pins a component reference digest computed with jsonNormalisation/v1, which can only be
verified, never recorded in a new component version.
Fix: Remove the digest from that reference; ocm add cv computes one with the default.