Skip to content

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

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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