Tag every firmware image with the hardware identifiers it is compatible with, plus a release counter that rises with each version, and make the device check both before it installs. The first stops a valid image going to the wrong model. The second stops a device being pushed back to an older release.
What the Uptane standard recommends
The Uptane standard lists information to place with each image on the Director repository. One item is a release counter, incremented each time a new version of the image is released, which can be used to prevent rollback attacks even when the Director repository is compromised. Another is a hardware identifier, or list of identifiers, for the models of ECU the image is compatible with. This can be used to ensure that an ECU cannot be ordered to install an incompatible image, even when the Director is compromised.
The point is that the device checks these itself. If only the server decides, a compromised server decides wrongly.
The two failure modes
| Failure | Cause | Control |
|---|---|---|
| Brick from wrong image | Valid image sent to an incompatible model | Hardware ID list |
| Known flaw returns | Older valid image replayed | Release counter |
| Mixed incompatible parts | Each image valid, combination bad | Server side compatibility table |
Steps to add this to your pipeline
- Assign every hardware revision a stable identifier. Revisions that need different images get different identifiers.
- At build time, write the compatible identifiers into the signed metadata, not an unsigned side file.
- Keep a release counter per image line. It only goes up.
- On the device, compare the identifier and counter before writing anything to a slot.
- Reject an image with a lower counter than the one installed, unless a signed, deliberate downgrade exception exists.
- Log every rejection and send it at the next check-in.
Where it gets awkward
Rollback has legitimate uses. If a release is bad, you may want devices to return to the previous one. Handle that by publishing the fix as a new release with a higher counter, built from the older code, so the rule stays simple. Make exceptions rare, signed, and visible in the log.
Hardware identifiers drift as supply chains change. A board revision with a different chip is a new identifier, even if the case looks the same. Tie the identifier to your hardware bill of materials so it cannot silently diverge.
Why this belongs in component tracking
Each rejection log line tells you something about your inventory: a device that rejected an image may be a model you did not know was in the field. Feed those lines into the device record. Safeguard's SBOM and dependency scanning cover the software contents of each image, and the free scan at gold.safeguard.sh/scan shows how.
Quick check
Can I reuse a version number as a release counter?
Only if it is a strictly increasing integer. Free form version strings are hard to compare safely.
How do I roll back a bad release?
Ship a new release with a higher counter that contains the previous code, instead of lowering the counter.
Sources
Last reviewed: 19 October 2026.