[VS-NfD] Produce an SBOM and a license report in CI #202

Closed
opened 2026-07-30 01:43:37 +02:00 by fable-5 · 1 comment
Collaborator

Plan reference: 20-massnahmenplan.md -> Phase 2
ADR: n/a
Effort: M (1–2 AT)
Depends on:

Context

An SBOM is the artefact a supply-chain question is answered with rather
than argued about, and the license report is needed for the procurement
side of the same conversation.

Current state

  • .gitea/workflows/ci.yml runs install, build, lint, typecheck, tests and
    i18n:check; there is no SBOM step. No reference to sbom, syft or
    cyclonedx exists anywhere in .gitea/ or the root package.json.
  • Deployment is by container image (deploy/compose/docker-compose.yml), so
    the SBOM has to cover both the pnpm workspace and the images.

Acceptance criteria

  • CI produces a CycloneDX SBOM per released image plus one for the
    workspace, and attaches them as build artefacts of the release
    workflow.
  • A license report lists every dependency with its license; the job
    fails on a license outside a documented allowlist.
  • Runner constraints respected: the CI runner image lacks python and
    node tooling outside the workspace, and bind mounts talk to the host
    daemon — the chosen tool works under those conditions (documented in
    the PR).
  • The SBOM's provenance is documented so an assessor can regenerate it.
  • #228 references where SBOMs are published per release.

Out of scope

Vulnerability scanning and its triage policy, and signing the SBOM.

**Plan reference:** `20-massnahmenplan.md` -> Phase 2 **ADR:** n/a **Effort:** M (1–2 AT) **Depends on:** — ## Context An SBOM is the artefact a supply-chain question is answered *with* rather than argued about, and the license report is needed for the procurement side of the same conversation. ## Current state - `.gitea/workflows/ci.yml` runs install, build, lint, typecheck, tests and `i18n:check`; there is no SBOM step. No reference to `sbom`, `syft` or `cyclonedx` exists anywhere in `.gitea/` or the root `package.json`. - Deployment is by container image (`deploy/compose/docker-compose.yml`), so the SBOM has to cover both the pnpm workspace and the images. ## Acceptance criteria - [ ] CI produces a CycloneDX SBOM per released image plus one for the workspace, and attaches them as build artefacts of the release workflow. - [ ] A license report lists every dependency with its license; the job fails on a license outside a documented allowlist. - [ ] Runner constraints respected: the CI runner image lacks python and node tooling outside the workspace, and bind mounts talk to the host daemon — the chosen tool works under those conditions (documented in the PR). - [ ] The SBOM's provenance is documented so an assessor can regenerate it. - [ ] #228 references where SBOMs are published per release. ## Out of scope Vulnerability scanning and its triage policy, and signing the SBOM.
fable-5 added this to the M25 — VS-NfD: hardening & supply chain milestone 2026-07-30 01:43:37 +02:00
fable-5 added the
area:supply-chain
effort:M
vs-nfd
labels 2026-07-30 01:43:37 +02:00
Author
Collaborator

Implemented in PR #258 (commit d3289b2, CI run 521 green, fast-forward merged per Stefan's standing go-ahead for the M25 block).

Evidence against the acceptance criteria:

  • CycloneDX SBOMs per released image + one for the workspace: release.yml generates them with pinned anchore/syft:v1.33.0 (images from the freshly built tar, OS packages included; workspace from pnpm-lock.yaml) and attaches everything as build artefacts supply-chain-vX.Y.Z BEFORE publishing the release. First real artefacts appear with the next release run.
  • License report + allowlist gate: scripts/check-licenses.mjs (documented allowlist: permissive + MPL-2.0/CC-BY-4.0 with reasoning + per-package exceptions, khroma verified MIT by shipped license text). Gate runs on every PR in ci.yml; verified positive (1125 packages) and negative (fabricated GPL fails). Release stores the full pnpm licenses report next to the SBOMs.
  • Runner constraints documented in the workflow comment and honored: no bind mounts (host daemon) - docker cp streams files in, docker save tars images (syft cannot read tar from stdin; tested); both SBOM paths tested locally against real inputs (workspace: 1382 components; image: 1047 components).
  • Provenance/regeneration documented in security.md, Supply chain artefacts section; publication location recorded on #228.

CD verification of the merged main follows.

Implemented in PR #258 (commit d3289b2, CI run 521 green, fast-forward merged per Stefan's standing go-ahead for the M25 block). Evidence against the acceptance criteria: - CycloneDX SBOMs per released image + one for the workspace: release.yml generates them with pinned anchore/syft:v1.33.0 (images from the freshly built tar, OS packages included; workspace from pnpm-lock.yaml) and attaches everything as build artefacts supply-chain-vX.Y.Z BEFORE publishing the release. First real artefacts appear with the next release run. - License report + allowlist gate: scripts/check-licenses.mjs (documented allowlist: permissive + MPL-2.0/CC-BY-4.0 with reasoning + per-package exceptions, khroma verified MIT by shipped license text). Gate runs on every PR in ci.yml; verified positive (1125 packages) and negative (fabricated GPL fails). Release stores the full pnpm licenses report next to the SBOMs. - Runner constraints documented in the workflow comment and honored: no bind mounts (host daemon) - docker cp streams files in, docker save tars images (syft cannot read tar from stdin; tested); both SBOM paths tested locally against real inputs (workspace: 1382 components; image: 1047 components). - Provenance/regeneration documented in security.md, Supply chain artefacts section; publication location recorded on #228. CD verification of the merged main follows.
Sign in to join this conversation.
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: stwaidele/dorfteich#202
No description provided.