Skip to content

SPDX 3.0 validation: current status, Yocto Scarthgap gaps, and upstream patch proposal #3

@jetm

Description

@jetm

Updated 2026-05-11 with corrections after verifying the proposal against the openembedded-core code and the SPDX 3.0.1 spec. The original 3-patch series was scoped down to a single patch; see "Upstream patch proposal" below.

Summary

v0.0.6 ships SPDX 3.0 detection and field validation in the sbom-generation check. On real Yocto Scarthgap output with create-spdx-3.0, shipcheck scores 20/50 because create-spdx-3.0 does not emit supplier or per-Package checksums in any form.

This issue documents what passes, what fails, why, and the openembedded-core patch that closes the supplier gap.


Scoring model (50 pts total)

Category Max What is checked
Format detected 10 CreationInfo.specVersion starts with 3.
CreationInfo 5 created (ISO 8601) and createdBy (non-empty list)
Sbom rootElement 5 Chain resolves to at least one software_Package Element
Per-Package fields 30 30 pts distributed proportionally to the count of packages where all 5 required fields (name, version, supplier, license, checksums) are present

Per-Package validation uses a first-match alias resolver and a 1-hop Relationship traversal fallback for hasConcludedLicense, hasDeclaredLicense, hasSuppliedBy, and hasOriginatedBy.


Pilot 0006: Yocto Scarthgap result

Build: core-image-minimal on poky cb2dcb4963e5fbe449f1bcb019eae883ddecc8ec with INHERIT += "create-spdx-3.0".

Category Score
Format detected 10/10
CreationInfo 5/5
Sbom rootElement 5/5
Per-Package fields 0/30
Total 20/50

What Scarthgap emits and what it doesn't

create-spdx-3.0 on Scarthgap emits license via hasConcludedLicense Relationship Elements (shipcheck traverses these). Note: current openembedded-core master switched to hasDeclaredLicense in commit 61ba0ef140; both relationship types are spec-compliant under SPDX 3.0.1 and shipcheck traverses both. The license row is therefore not an upstream gap on current master.

It does not emit:

  • hasSuppliedBy Relationships (the suppliedBy field is only set when SPDX_PACKAGE_SUPPLIER is explicitly configured, which almost no build does)
  • Per-install-Package verifiedUsing (checksums land on software_File Elements contained by the Package, not on the Package itself)

As a result, supplier and checksums are absent in any form -- field or Relationship -- so no package fully complies and the 30-pt pool ends at zero.


BSI TR-03183-2 v2.1.0 → SPDX 3.0 mapping

Because BSI has not published a formal SPDX 3.0 profile, the required-field list used by shipcheck is a unilateral derivation from BSI's 2.x required fields mapped to SPDX 3.0 equivalents. It is committed at audits/0003-spdx3-mapping/mapping.md and explicitly marked "draft pending Yocto-list / SPDX-list review".

Feedback on whether the mapping correctly reflects how the SPDX community expects BSI's requirements to translate to 3.0 constructs is welcome. Note: an earlier version of the mapping doc Section 4 cited a software_declaredLicense property on software_Package; that property does not exist in SPDX 3.0.1 (license is exclusively Relationship-based in 3.0.1). The mapping doc will be revised to remove the phantom row.


Upstream patch proposal for openembedded-core

The fix is a single-patch addition to meta/classes/create-spdx-3.0.bbclass: provide a sensible default for SPDX_PACKAGE_SUPPLIER_ref so the suppliedBy field is populated on every Package without requiring per-build configuration.

spdx30: default SPDX_PACKAGE_SUPPLIER_ref to openembedded Agent

The one-line change reuses the SPDX_AUTHORS_openembedded Agent already defined in create-spdx-3.0.bbclass for the SBOM creator:

SPDX_PACKAGE_SUPPLIER_ref ??= "SPDX_AUTHORS_openembedded"

new_agent() at meta/lib/oe/sbom30.py:397-402 resolves <base>_ref as an Agent redirect, so this points suppliedBy at the existing OpenEmbedded organization Agent. Defaultable (??=), so vendor BSPs and product builds can override with their own supplier without touching the bbclass. Semantically defensible: OpenEmbedded is the entity assembling the built artifact with this exact recipe set; vendors override with their organization when they take supplier responsibility.

The dual-emit precedent in openembedded-core for the additive-field pattern is commit c8e6953a0b (2025-04-28).

Patch submitted to openembedded-core: https://lore.kernel.org/openembedded-core/20260511-spdx30-package-supplier-default-v1-1-12e0d086ccf4@jetm.me/T/#u

Out of scope for this patch

  • License field. Already spec-compliant on master via hasDeclaredLicense; no upstream change needed.
  • Per-Package verifiedUsing aggregation. The multi-hop synthesis (walk contained software_File Elements, aggregate hashes, write an IntegrityMethod on the Package) carries design questions (hash algorithm choice, zero-file packages, aggregation semantics) that warrant their own series. Tracked as future work.

Scope note: recipe-level SpdxDocument

Recipe-level SPDX 3.0 documents emitted by Yocto use SpdxDocument as the root Element rather than Sbom. Validating those requires a different traversal. This is deferred to v0.0.7+.


Testing

If you have a Scarthgap or walnascar build with create-spdx-3.0 enabled:

pip install shipcheck==0.0.6
shipcheck check --build-dir <your-build-dir>

The sbom-generation row is the relevant one. Knowing whether the 20/50 ceiling holds across different machine targets and BSPs would help scope the upstream patch.


Related

  • audits/0003-spdx3-mapping/mapping.md - BSI v2.1.0 → SPDX 3.0 field mapping (draft; license row to be corrected)
  • audits/0003-spdx3-mapping/upstream-poky-spdx3.md - upstream investigation (to be revised to reflect the verified openembedded-core code)
  • pilots/0006-poky-scarthgap-spdx3/REPORT.md - pilot report

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions