philipp.baumann/dse-security-reports
Watch
0
0
Fork
You've already forked dse-security-reports
0

feat(coverage): include the WireGuard unit absent from both Defender exports #12

Merged
Philipp Baumann merged 2 commits from fm/dse-security-reports-wireguard-coverage into main 2026-10-26 22:35:48 +00:00

Summary

The captain asked for the WireGuard machine to be included in the analysis: dse_prod_wireguard (ASP-DSE-PROD-WIREGUARD, an Alma 9.8 Azure VM managed by dse-ansible, WireGuard gateway with 19 peers) appears in neither Defender export -- a coverage gap, since the machine is real, reachable and runs the same stack family. The pipeline now maps, collects evidence for and scans the unit, and the derivation keeps evidence-covered units with zero Defender rows in the payload with an explicit absence marker, so both reports show the gap data-driven instead of dropping the machine silently. The trivy join gains its honest one-directional complement (trivy-only) next to the per-row defender-only verdicts.

What changed

  • config/systems.csv: new exact row ASP-DSE-PROD-WIREGUARD (alias dse_prod_wireguard, RG-DSE-PROD, DSE domain), so just evidence collects it and just scan scans it like the other units.
  • scripts/derive_findings.py and src/dse_security_reports/derive.py: on real data the evidence cache is enumerated for units outside the export (gated on is_synthetic, so the fixture lane never joins real caches); evidence-covered units with zero Defender rows stay in the payload with defenderExport: absent, defenderRows, their mapping fields and machine-scoped trivyOnly detections; the payload-level scannerAgreement gains a trivy-only count. Both lanes stay byte-identical (just py-crosscheck green on fixture and real data).
  • scripts/ssh_evidence.sh / scripts/scan_trivy.sh: comment updates only (units incl. zero-Defender-row coverage, trivy-only dimension).
  • reports/defender-triage.typ: Systemlandkarte and Evidenzabdeckung render the unit with 0 Defender rows, a data-driven absence marker (Abdeckungsluecke, nicht sauber) and its evidence/trivy posture; the Trivy column now counts trivy-only CVEs per unit; a new subsection breaks the trivy-only complement down per unit with the backlog framing; the kernel-gap ranking row (P15) covers the four el9 units now; the SSH-evidence Methods bullet states the public-key authentication for philipp_baumann with account and key managed by the Ansible IaC (devxy.sysadmin users role); counts updated (8 Linux units, nginx on 7 of 8) and a fan-out row for clarifying the Defender coverage of the unit (MDE runs per the status audit).
  • reports/defender-findings.typ: scanner-agreement prose explains the one-directional join with the per-export trivy-only count; the evidence section lists units with zero Defender rows in the export as coverage gaps.
  • tests/test_derive.py: wireguard-shaped cache unit (absence marker, mapping fields, trivy-only join including machine scoping -- the bind CVE reported by Defender on DEV-WORKBENCH is trivy-only on WIREGUARD), the synthetic gate proven byte-identical for both lanes, and the committed mapping coverage test gains the new endpoint.
  • AGENTS.md: project notes updated (8 units, coverage-gap handling, trivy-only dimension, five generated tables).

Behaviour change

Machines covered by SSH evidence but absent from the Defender exports no longer vanish from the derivation: they render in the system map and coverage tables with 0 Defender rows and an explicit coverage-gap marker, together with their evidence and trivy posture (ASP-DSE-PROD-WIREGUARD: Alma 9.8, running kernel fixed, dnf-auto+install enabled, no nginx, no venvs, 998 trivy-only detections / 295 CVEs). The scanner-agreement counts gain a trivy-only value that names trivy findings without a Defender counterpart on the same unit, including the distro advisory backlog, and both reports state that this number is not comparable to export rows. The synthetic fixture lane and byte-identical reproducibility are unchanged.

Instructions-PR: none

## Summary The captain asked for the WireGuard machine to be included in the analysis: dse_prod_wireguard (ASP-DSE-PROD-WIREGUARD, an Alma 9.8 Azure VM managed by dse-ansible, WireGuard gateway with 19 peers) appears in neither Defender export -- a coverage gap, since the machine is real, reachable and runs the same stack family. The pipeline now maps, collects evidence for and scans the unit, and the derivation keeps evidence-covered units with zero Defender rows in the payload with an explicit absence marker, so both reports show the gap data-driven instead of dropping the machine silently. The trivy join gains its honest one-directional complement (trivy-only) next to the per-row defender-only verdicts. ## What changed - `config/systems.csv`: new exact row `ASP-DSE-PROD-WIREGUARD` (alias `dse_prod_wireguard`, RG-DSE-PROD, DSE domain), so `just evidence` collects it and `just scan` scans it like the other units. - `scripts/derive_findings.py` and `src/dse_security_reports/derive.py`: on real data the evidence cache is enumerated for units outside the export (gated on `is_synthetic`, so the fixture lane never joins real caches); evidence-covered units with zero Defender rows stay in the payload with `defenderExport: absent`, `defenderRows`, their mapping fields and machine-scoped `trivyOnly` detections; the payload-level `scannerAgreement` gains a `trivy-only` count. Both lanes stay byte-identical (`just py-crosscheck` green on fixture and real data). - `scripts/ssh_evidence.sh` / `scripts/scan_trivy.sh`: comment updates only (units incl. zero-Defender-row coverage, trivy-only dimension). - `reports/defender-triage.typ`: Systemlandkarte and Evidenzabdeckung render the unit with 0 Defender rows, a data-driven absence marker (Abdeckungsluecke, nicht sauber) and its evidence/trivy posture; the Trivy column now counts trivy-only CVEs per unit; a new subsection breaks the trivy-only complement down per unit with the backlog framing; the kernel-gap ranking row (P15) covers the four el9 units now; the SSH-evidence Methods bullet states the public-key authentication for `philipp_baumann` with account and key managed by the Ansible IaC (`devxy.sysadmin` users role); counts updated (8 Linux units, nginx on 7 of 8) and a fan-out row for clarifying the Defender coverage of the unit (MDE runs per the status audit). - `reports/defender-findings.typ`: scanner-agreement prose explains the one-directional join with the per-export trivy-only count; the evidence section lists units with zero Defender rows in the export as coverage gaps. - `tests/test_derive.py`: wireguard-shaped cache unit (absence marker, mapping fields, trivy-only join including machine scoping -- the bind CVE reported by Defender on DEV-WORKBENCH is trivy-only on WIREGUARD), the synthetic gate proven byte-identical for both lanes, and the committed mapping coverage test gains the new endpoint. - `AGENTS.md`: project notes updated (8 units, coverage-gap handling, trivy-only dimension, five generated tables). ## Behaviour change Machines covered by SSH evidence but absent from the Defender exports no longer vanish from the derivation: they render in the system map and coverage tables with 0 Defender rows and an explicit coverage-gap marker, together with their evidence and trivy posture (ASP-DSE-PROD-WIREGUARD: Alma 9.8, running kernel fixed, dnf-auto+install enabled, no nginx, no venvs, 998 trivy-only detections / 295 CVEs). The scanner-agreement counts gain a `trivy-only` value that names trivy findings without a Defender counterpart on the same unit, including the distro advisory backlog, and both reports state that this number is not comparable to export rows. The synthetic fixture lane and byte-identical reproducibility are unchanged. Instructions-PR: none
The captain asked for the analysis to cover dse_prod_wireguard, an Alma 9.8
Azure VM that appears in neither Defender export -- a coverage gap, since the
machine is real, reachable and runs the same stack family.

- Add ASP-DSE-PROD-WIREGUARD (alias dse_prod_wireguard, RG-DSE-PROD, DSE
  domain) to config/systems.csv so `just evidence` collects it and `just
  scan` scans it like every other Linux unit.
- Keep evidence-covered units with zero Defender rows in the derivation
  (both lanes) with an explicit `defenderExport: absent` marker, their
  mapping fields and their machine-scoped `trivyOnly` detections, plus a
  payload-level `trivy-only` count beside the per-row agreement values.
- Gate cache-unit enumeration on `is_synthetic` so the fixture lane never
  joins real caches sitting next to it, keeping `just all`/`just
  py-crosscheck` fixture-only and both lanes byte-identical.
- Render the gap data-driven in both reports: the triage Systemlandkarte
  and Evidenzabdeckung show the unit with 0 Defender rows, an absence
  marker and its evidence/trivy posture; a new trivy-only subsection
  breaks the one-directional join down per unit; the kernel-gap ranking
  row (P15) now covers the four el9 units; the standard report states the
  uncovered units and the trivy-only complement per export.
- State the SSH collection method precisely: public-key SSH authentication
  for philipp_baumann with account and key managed by the Ansible IaC
  (devxy.sysadmin users role), matching the IaC-declared state.
- Extend the pytest suite: wireguard-shaped cache unit (absence marker,
  mapping fields, trivy-only join incl. machine scoping), the synthetic
  gate with a stdlib/polars byte-identity check, and the mapping coverage
  test.
The captain asked for config/systems.csv to become config/systems.json
with the pipelines adjusted. Same data, same resolution semantics, one
machine-readable mapping file.

- Replace config/systems.csv with config/systems.json (git mv semantics,
  removed in the same commit): a top-level "systems" array with one entry
  per match key (exact machine name or family prefix) carrying the same
  six fields -- resourceGroup, location, category, subcategory, domain and
  sshAlias (an ssh.cfg alias or a raw address, as before). A malformed
  entry fails the derivation instead of silently degrading.
- Adjust both derive lanes (scripts/derive_findings.py,
  src/dse_security_reports): read the JSON baseline, read the az-refresh
  override as .local/systems-az.json with the unchanged field-wise merge
  (an override Match the baseline lacks still crashes with KeyError), and
  rename the systems_csv parameter to systems_json.
- Adjust the evidence stage (scripts/ssh_evidence.sh: unit/alias extraction
  via jq over the JSON) and the az-refresh writer
  (scripts/az_refresh_systems.sh: emits the same JSON schema, sorted by
  match key).
- Adjust both reports (mapping references and the Evidenzabdeckung row
  order now read config/systems.json), the tests (SYSTEMS_JSON, JSON
  override fixture) and the Justfile/AGENTS.md/docstring references.
- Proofs unchanged: both lanes byte-identical on the fixture and the real
  caches, two consecutive triage renders byte-identical, just test/lint/
  fmt/py-crosscheck green.
Philipp Baumann force-pushed fm/dse-security-reports-wireguard-coverage from 89d24cc48d to 6658ab47f3 2026-10-26 22:32:53 +00:00 Compare
Philipp Baumann deleted branch fm/dse-security-reports-wireguard-coverage 2026-10-26 22:35:48 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No assignees
1 participant
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
philipp.baumann/dse-security-reports!12
No description provided.