feat(triage): state the WireGuard unit's IaC ownership and review its stale Trivy advisories #28
Loading…
Reference in a new issue
No description provided.
Delete branch "fm/dse-security-reports-wireguard-iac"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
The report described the WireGuard unit's software and role but never said its installation is declared and owned by configuration, and it carried the unit's scanner hits without saying where they come from or how to read them. This change states the dse-ansible declaration beside the verified host state, names the 2021 scanner entries together with the vendor's own explanation of why a correctly patched host still shows them, and dismisses CVE-2021-3695 in the scanner through a committed VEX document — while keeping every dismissal visible in both derivation lanes and in a new report table.
What changed
reports/defender-triage.typ: state the IaC declaration (pinnedgithubixx.ansible_role_wireguard19.2.0,playbooks/playbook-wireguard.yamlwith wg0 / 51820 / endpoint / 10.15.5.1/24 / ULA / MTU 1280 with MSS clamping, peers inhost_vars, cutover runbook) beside the verified host state, and contrast it with the unownedpackages-microsoft-com-prod; add the WireGuard Trivy passage (findings come from Trivy, Red Hat's FAQ as the mechanism authority, the mirror-image reading, the verified grub2 position, the epoch root cause, the checked-not-waved discipline, the kernel-exposure guard); add the data-driven «Abgewiesene Fundstellen (VEX)» table.config/vex/alma-backported-fixes.vex.json: the committed VEX fallback for CVE-2021-3695 on the eight grub2 purls, statusfixed, each statement carrying the erratum and the review horizon. The stale-advisory reading is scoped to the individually checked entries and states explicitly that it says nothing about the unit's wider Trivy set.scripts/scan_trivy.sh: add--vex <file>,--vuln-severity-source redhatand--show-suppressed; record the dismissed findings (status, source, and the document'simpact_statement) in the per-unit payload; document the VEX obstacle and the epoch root cause in the header; key the cache on ascanConfigsignature (with aformat=token) so a stale cache is re-scanned instead of silently reused.scripts/derive_findings.pyandsrc/dse_security_reports/derive.py: carryvexDismissedper evidence unit and the payload-levelvexaggregate in both lanes, and expose the VEX/severity source inscanMeta.tests/test_derive.py: cover the dismissal join, thevexaggregate and the new scan metadata.AGENTS.md: record the scan-lane VEX/severity mechanism, the VEX obstacle, the epoch root cause and the anti-invisibility rule.Behaviour change
The scan no longer reports CVE-2021-3695 on the WireGuard unit as a live finding; it records it as a dismissed entry, and the report shows that dismissal with its VEX status, its source document and the erratum that backs it. Severities follow Red Hat where Red Hat has an opinion. Nothing suppressed can become invisible: the dismissal survives the scan cache, both derivations and the render.
Evidence
The instructed vendor-VEX route does not work, and the obstacle was proven rather than assumed (the header of
scripts/scan_trivy.shrecords all of it):--vex repo(aquasecurity/vexhub) parses and fetches, but holds no statement matching ourpkg:rpm/alma/...products — 866 findings unchanged — and it writes its config to~/.trivy/vex/repository.yaml, i.e. outside the worktree.security.access.redhat.com/data/csaf/v2/vex/2021/cve-2021-3695.json, categorycsaf_vex, fixed 194 / known_affected 22 / known_not_affected 58) is parsed but cannot match: itsproduct_identification_helpercarries neither purls nor CPEs, only Red Hat-internal product ids.So the VEX source is a stated fallback, not vendor data: it encodes the vendor's own decision (RHSA-2022:5099 fixed grub2 for RHEL 9 on 2022-06-16) against the exact installed purls, and pins them, so a grub2 upgrade stops matching and the finding returns for review.
Before/after on CVE-2021-3695 (
ASP-DSE-PROD-WIREGUARD, offline, cached DB):fixeddismissals (config/vex/alma-backported-fixes.vex.json);Vendor severity source (
--vuln-severity-source redhat): CVE-2021-3695 HIGH → MEDIUM; the unit's severity mix moves from 461 HIGH / 358 MEDIUM / 47 LOW to 224 HIGH / 471 MEDIUM / 163 LOW.The root cause is ours, and it was found while proving the dismissal:
scripts/build_cyclonedx_sbom.pybuilds the purl fromrpm -qa, whose version string carries no RPM epoch, while the Alma fixed version does (1:2.06-27.el9_0.7.alma). trivy therefore compares epoch 0 against epoch 1 and reports the package although the installed release (126) is far newer than the fixed one (27). Suffixing the eight grub2 purls with?epoch=1removes all 200 grub2 findings of the unit with no suppression at all (866 → 666; all 200 removed entries are grub2, 8 packages × 25 CVEs, no additions). Carrying the epoch is the durable fix and needsscripts/ssh_evidence.shto collect%{EPOCHNUM}— deliberately not done here, because it re-baselines the whole scan lane and needs a fresh evidence round.Status of the other entries examined under the same reasoning (checked, not added to the VEX document — no blanket suppression):
Every one of them has the installed build above the vendor's fixed version once the epoch counts, so the same reading holds — but the decision to suppress them belongs to the captain, not to this change.
Validation (all on the final tree):
just all✓ (fixture lane; the empty-dismissal branch renders),just repro✓ (byte-identical PDFs for both reports),just test✓ (39 passed),just lint✓,just py-crosscheck✓ (both derivation lanes byte-identical). The fixture lane stays offline; the re-scan ran offline against the cached DB (--skip-db-update). The PDFs were re-rendered and re-published (defender-triage-2026-10-28-1517.pdfplus the bare alias, likewise for findings); previous copies were moved toartifacts/superseded/; the 2026-10-26 set was not touched, and the republished files are byte-identical to a fresh render from this tree.Scope note: the instructed premise was corrected by the check
The brief asked the report to say that the unit's Trivy findings all date from 2021 and that CVE-2021-3695 was the only HIGH. The check disproved both, which is why the passage is scoped the way it is:
ASP-DSE-PROD-WIREGUARD, the pre-change copy under.local/scans-prev28/) holds 866 findings over 277 CVEs, 461 of them HIGH, by year 2021:39, 2022:175, 2023:128, 2024:112, 2025:109, 2026:303.So the report names the checked entries, says each was verified individually rather than assumed to belong to a class, and states that the unit's wider Trivy set is large and largely unexamined — never that it has been dismissed.
Open items for the captain
%{EPOCHNUM}inscripts/ssh_evidence.shand emit the?epoch=qualifier inscripts/build_cyclonedx_sbom.py. That removes the whole class of false positives at the root and needs a fresh evidence round.Instructions-PR: none