The problem: Your SBOM validator reports components without a purl or CPE. You need to add identifiers, but the packages come from Buildroot, Yocto, a vendor SDK and a few binary blobs.
purl and CPE solve different problems
- purl (Package URL)
- A structured, package-manager-aware identifier: scheme pkg, type, namespace, name, version, qualifiers and subpath. It is the identifier open-source advisory feeds prefer for libraries.
- CPE
- NIST's product dictionary entry (vendor, product, version, update and so on). It is broader and lossier, but for a commercial or renamed component it may be the only identifier a feed understands.
A component may legitimately carry both. What it must not carry is a purl that claims an ecosystem the component does not come from, because that produces a confident wrong match.
Step 1 — classify each unidentifiable component
| Component origin | Identifier to use | Watch out for |
|---|---|---|
| Distro or Yocto/Buildroot package | purl with the real type, namespace and version | Image-recipe versions that differ from the upstream source |
| Language package (npm, PyPI, Cargo, Go) | purl with the ecosystem type | Lockfile ranges instead of resolved versions |
| Upstream library compiled in | purl matching the upstream release | Vendor patch level; add qualifiers only if a feed understands them |
| Commercial SDK or radio module | CPE when the vendor publishes CVE-assigned products, otherwise a vendor-described component | Do not fabricate pkg:generic entries |
| Bootloader or RTOS component | purl if it is released upstream, CPE if the vendor tracks it that way | Often outside open-source advisory coverage entirely |
Step 2 — build the purl from the source of truth
Generate the identifier where the version is already known: the recipe, the lockfile, the package manifest. Hand-editing a finished SBOM is how identity errors enter.
{
"type": "library",
"name": "openssl"
}
{
"type": "library",
"bom-ref": "pkg:generic/[email protected]",
"name": "openssl",
"version": "3.0.13",
"purl": "pkg:generic/[email protected]",
"supplier": { "name": "OpenSSL Software Foundation" }
}Keep the version inside both the version field and the purl. A purl without a version field, or a version field that contradicts the purl, is one of the most common causes of a component that looks identified but never matches.
Step 3 — use CPE deliberately
- Use CPE 2.3 formatted strings with an explicit version when the vendor tracks products that way.
- Do not attach a CPE for a similar-sounding product. A wrong CPE produces false positives that are harder to disprove than a missing identifier.
- Never use the any-version wildcard to make a component look covered; it cannot be resolved to a specific advisory state.
- If neither identifier is meaningful, say so in the component and in your risk assessment instead of filling the field.
Step 4 — re-validate and check the reason changed
Re-run the validator and compare the readiness reasons before and after. The number of query-ready components should rise, and the remaining reasons should be ones you can explain: an unsupported ecosystem, an ambiguous identity, a vendor component with no feed coverage.
If a component moves from “missing identifier” to “query ready” but your scanning result does not change, the problem is downstream of the SBOM: the matcher's ecosystem coverage, not the document.
Scope and limits
- A syntactically valid purl does not guarantee that any advisory feed knows the package.
- This guide covers identifier quality only; it does not assess exploitability or product risk.