Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/vole.git

Write over SSH with a registered key:

git clone ssh://git@rodent.software:2222/vole.git

A free and open-source forge that lives in your Git repo.

#108

Fail a push that adds a license this project cannot ship

merged · by keenan 10d ago · merged into main at 70ba9a69 by keenan 10d ago

keenan opened this 10d ago

Closes #95.

Why

verify failed on a reachable vulnerability but looked at no license, so a dependency this project may not distribute could land in a change request with nothing to notice it. NOTICE was the only inventory of what ships, and nothing kept it true.

What changed

  • licenses.toml at the repository root: the licenses the project can ship, each with the reason it is acceptable, so widening it is a deliberate reviewed edit. It explains why the golang.org/x modules arrive under a different identifier than the rest of the BSD-3-Clause graph.
  • scripts/check-licenses.py checks two inventories, because they arrive by different routes:
    • Go modules have metadata, so a module carrying a license outside the allowlist fails, and so does a module whose license the scanner could not detect. Unknown is not permission. A compound license (MIT OR GPL-3.0-only) has to be allowed as a whole; reading it as its first term is the mistake the check exists to prevent.
    • Vendored browser assets have no metadata, so NOTICE is their inventory, and it is checked both ways: every *.LICENSE or OFL-*.txt beside an asset must be named, and every name must point at a file.
  • .vole/workflows/verify.yaml gains a licenses step: the pinned cyclonedx-gomod builds a bill of materials, the script checks it.
  • .vole/workflows/release.yaml checks too, against the SBOM it already builds, because a tag can point at a commit that never passed a push and a release cannot be recalled. Same reasoning as the govulncheck gate there.
  • .vole/images/release.yaml gains python3, which is what the release-side check runs on.
  • CONTRIBUTING.md gains Dependencies and licenses: what a contributor does when the check fails. NOTICE gains the missing entry and says what the check enforces.

The check found drift before it was merged

NOTICE never mentioned canvas-confetti, which the celebration work shipped (confetti.browser.js plus its ISC license file). The license file was there, the inventory was not. Two-way checking is what catches that shape; one-way would have passed.

Verification

  • vole workflow run verify in the pinned image: all steps pass, the new step prints 21 modules (Apache-2.0, BSD-3-Clause, BSD-Source-Code, MIT); NOTICE matches the assets.
  • vole workflow run release against a throwaway local tag: the SBOM step runs the check with python3 from the release image and the job ends ok: 1 job(s). Tag deleted.
  • Negative cases exercised against a doctored bill of materials and a temporarily removed license file: an unlisted id, a compound expression, a module with no detected license, a NOTICE entry whose file is gone, and an asset license file missing from NOTICE each fail with one line naming the culprit.

What this does not do

The issue also asked for a module diff on the verification log. Dropped, with the reason on #95: the change request page already renders the go.mod/go.sum diff that a reviewer reads, the missing information was each module’s license rather than its name, and a comparison inside a push-triggered job has no dependable base to diff against.

Discussion (0)

No discussion yet.