Agent Wranglers

IOT-39Recommended

Keep a bill of materials for every firmware image

Every firmware release ships with a machine-readable software bill of materials in SPDX or CycloneDX, stored next to the signed image. It lists the bootloader, the operating system or RTOS, the chip vendor's SDK and radio blobs, and every library, each with its version.

How to do it

When a hole is published in a TCP/IP stack or a Wi-Fi driver, you must answer within hours which models and versions carry it. Firmware hides parts that package managers never see, such as vendor SDKs copied into the tree and binary radio firmware. Generate the list in the build, and add the parts no tool detects from a hand-kept file. Fail the build when a part has no version. Build the image reproducibly, as build the same bytes from the same commit says, so the list matches what ships. The general method is keep a bill of materials and provenance. The Cyber Resilience Act asks for a bill of materials covering at least top-level dependencies in the technical file.

Examples

Python example

import json
import sys

def parts_without_version(sbom_path: str) -> list[str]:
    sbom = json.load(open(sbom_path))
    return [part["name"] for part in sbom.get("components", []) if not part.get("version")]

if missing := parts_without_version(sys.argv[1]):
    sys.exit(f"Firmware bill of materials has parts without a version: {missing}")

Go example

type component struct {
	Name    string `json:"name"`
	Version string `json:"version"`
}

func PartsWithoutVersion(sbomJSON []byte) ([]string, error) {
	var sbom struct {
		Components []component `json:"components"`
	}
	if err := json.Unmarshal(sbomJSON, &sbom); err != nil {
		return nil, err
	}
	var missing []string
	for _, part := range sbom.Components {
		if part.Version == "" {
			missing = append(missing, part.Name)
		}
	}
	return missing, nil
}

How to check

The release job fails when the image has no bill of materials, or when any listed part has no version. A query over the stored lists returns, for a given library and version, every model and firmware version that contains it.

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/connected-devices/firmware-updates/firmware-sbom">Agent Wranglers connected devices playbook</a>. In code you write, add a comment next to it with the same link.