Files
werkregie/doc/prs/2026-10-13-PR#59-dependency-checks.md
claude-code 5fdfd84e29
werkator build succeeded after 01:00
werkator/dependencies build succeeded after 04:22
werkregie checks its dependencies for vulnerabilities and licenses (#59)
Co-authored-by: claude-code <claude-code@javagil.de>
2026-10-13 13:50:43 +02:00

90 lines
4.3 KiB
Markdown

# PR#59: werkregie Checks Its Dependencies for Vulnerabilities and Licenses
> **WARNING:** This document describes only the change applied in this PR.
> It may already be outdated once the next PR is merged.
> Historic PR documentation is not maintained along with new PRs; treat it as a snapshot.
## Related Links
- [PR#58](https://git.javagil.de/mi/werkregie/pulls/58), the required checks of all werk repositories.
## Problem
Since PR#58, each werk repository keeps a criticality and risk analysis
and checks its dependencies for known vulnerabilities and for their licenses.
werkregie has neither.
## Non-Goals
- No mutation tests; they follow in a PR of their own, as a nightly build.
- No vulnerability check of PR branches yet; see "Follow-up PRs".
- No security headers, e.g. CSP or HSTS; the risk analysis lists them as an open risk.
## Specification
### Feature: the build checks the dependencies
#### Scenario#59.01: a vulnerable dependency fails the build
&hellip; so that no dependency with a known vulnerability from CVSS 4 reaches main.
- **Given** a dependency with a known vulnerability of CVSS 4 or more, and no suppression for it
- **When** Werkator checks main for vulnerabilities
- **Then** the check fails and names the vulnerability
##### Verified by
- Manual: `./gradlew dependencyCheckAnalyze` in `dashboard/`; its first run failed on CVE-2026-53914 of `kotlin-reflect` 2.3.20.
- Werkator's build `dependencies` on main after the merge.
#### Scenario#59.02: a dependency with a license outside the allowlist fails the build
&hellip; so that no license reaches main without the consent of the human.
- **Given** a dependency whose license is not on the allowed list
- **When** the build runs
- **Then** the build fails and names the dependency and its license
##### Verified by
- Manual: `./gradlew checkLicense` in `dashboard/`; with the allowlist emptied, it failed and named all 119 dependencies.
## Solution
- `doc/risk-analysis.md`: what werkregie handles, who reaches it, what a breach would cost;
criticality high, set by the human, so a vulnerability from CVSS 4 fails the build.
- OWASP Dependency-Check, plugin `org.owasp.dependencycheck`, task `dependencyCheckAnalyze`:
- `failBuildOnCVSS` 4, over `runtimeClasspath`, i.e. what ships;
- the NVD API key comes from the environment variable `NVD_API_KEY`, else from the Gradle property `OWASP_API_KEY`;
- the data counts as current for 24 hours and lies in the Gradle home, shared by the builds on mih09;
- a suppression needs its reason, in `dashboard/config/dependency-check-suppressions.xml`;
- Sonatype's OSS Index is off, since it answers only with credentials.
- Werkator runs it as the build `dependencies` on each push to main, with the status `werkator/dependencies`:
- the first download of the NVD data takes longer than the 10 min of the build `default`, so it is a build of its own,
with the host's longest timeout;
- only main for now: Werkator takes `statusContext` from main, so a build that only this branch defines
would report as `werkator` and overwrite the status of `default`.
- The license check, plugin `com.github.jk1.dependency-license-report`, in `check`,
against the allowlist of the shared workflow in `dashboard/config/allowed-licenses.json`.
- `.werkrevisor.toml` marks the suppressions, the allowlist and the risk analysis as hard paths;
the host's paths for secrets stay.
- `AGENTS.md` names the commands of the checks.
- Version 0.38.0.
## Additional Changes
- `kotlin-reflect` 2.4.21 instead of 2.3.20, which Exposed brings under Trixnity:
the first check found CVE-2026-53914, CVSS 9.8, in Kotlin before 2.4.20.
- MIT-0 joins the allowed licenses of the shared workflow, chosen by the human:
`reactive-streams`, which Trixnity's storage needs, is under MIT-0, which is more permissive than MIT.
## Follow-up PRs
- The build `dependencies` for each PR branch.
Werkator reads a build's `statusContext` from main, never from the branch it builds.
So a PR branch can run `dependencies` under its own context only after this PR has brought the context to main;
before, its result would overwrite the status `werkator` of the build `default` on the same commit.
The follow-up drops `branches: ["main"]`, and the human then adds `werkator/dependencies` to the required checks of `main`.
- Mutation tests with werkcrappit in a nightly build.