Skip to content

No Software Producer on any component, and no way to say we do not know #27

Description

@richardmhope

CISA's 2026 Minimum Elements renames 2021's Supplier Name to Software Producer and, per the published analysis of the final, supplies an explicit fallback value for the case where provenance is not reliably known. We emit neither the field nor the fallback. Assessment in docs/cisa-sbom-minimum-elements-2026.md on branch claude/tool-sbom-requirements-assessment-jkudvt.

This was the only element in that assessment present in both the 2021 baseline and the 2026 revision that we do not address at all, which makes it the longest-standing gap of the set.

Current state

_component (src/icebergsca/report/cyclonedx.py:110) emits type, name, purl, version and four icebergsca: properties. No supplier, publisher or author. Dependency and PackageRef (core/models.py:268, core/models.py:191) have nowhere to hold one.

For metadata.component the same gap is already tracked as part of #21. This issue is the per-component case only — the ~hundreds of library entries, not the primary component — so the two do not collide.

The cheap half is the honest half

Real producer data needs registry metadata, and that is the expensive part (below). But the immediate defect is that the field is absent, and an absent field cannot be distinguished from a tool that does not model producers. An explicit "unknown provenance" says something true and is the distinction core/models.py:6-13 already commits the codebase to:

None is "upstream does not expose this"; "" is "upstream says there is none". Collapsing the two produces confident-looking output backed by nothing.

So: emit the field with an explicit unknown value, and let it be filled in as data becomes available. That alone moves the document from silent to honest and is a renderer-only change.

What must not happen

The purl namespace already carries Maven's groupId and npm's scope (core/models.py:220). It is tempting to relabel those as the producer. They identify a namespace, not a producer — com.fasterxml.jackson.core is a coordinate, @types/node is published by DefinitelyTyped rather than by anyone called @types, and a squatted namespace looks identical to a legitimate one. Presenting a namespace as a producer would manufacture provenance, which is worse than admitting none: the whole point of the field is supply-chain attribution, and a wrong attribution is actively misleading.

A namespace beside an explicit unknown is fine. A namespace as the answer is not.

The expensive half

Genuine producer data means per-package registry metadata: PyPI JSON, the npm packument, crates.io, RubyGems, the NuGet catalog, Maven POMs. That is the same fetch, the same new cache namespace, the same --offline question and the same new failure mode as #12, from the same endpoints — in most cases from the same HTTP response. Doing them separately would mean paying that cost twice.

registry/ today is used only for range resolution (RegistryClient.versions, registry/client.py:103), so a lockfile-first scan can currently make zero registry calls. Whatever lands must keep that true by default.

Note that even fetched metadata is weak evidence: "producer" per registry metadata is an uploading account, not an organisation, and it is exactly the field an attacker controls. It should be reported as what the registry says, never as verified provenance.

Scope

  • Emit an explicit unknown producer per component now, as a renderer-only change
  • A producer field on the dependency model, distinguishing unfetched from undeclared from unknown-by-the-registry
  • Fill it from registry metadata in the same pass as Report declared licences, and emit CycloneDX licenses #12, opt-in, defaulting to no network
  • Maven from the POMs MavenResolver already fetches, where <organization> or <developers> is declared
  • Never derive a producer from a purl namespace; a test asserting that would be worth having
  • Docs stating these are registry-declared, unverified

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions