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

feat(evidence): deterministic Ricochet-store probe with sudo, joined into the derivation #21

Merged
Philipp Baumann merged 1 commit from fm/dse-security-reports-ricochet-store-probe into main 2026-10-28 07:50:03 +00:00

Summary

The Ricochet deployment stores hold the deployed application virtualenvs, and every earlier inventory missed them: the stores are root-only, so a permission-denied subtree silently contributed nothing to find, and that miss is exactly what let a false-positive verdict through on the first pass and turned it into a confirmed finding only on the second. This change originates from the pyjwt verification work (preserved worktree commit b620538, authored on 6afae77) and adds a deterministic, read-only Ricochet-store probe to the evidence collector so that gap can never silently recur. The probe uses sudo -n (documented in the script header: the evidence account holds NOPASSWD sudo), a refused store is recorded as an explicit gap with a non-zero probeExit -- never as an absence -- and both derivation lanes join ricochetInstalled / claimedVersionRicochetInstalled / ricochetGap per finding, with ricochet-verified claims counting as installed for scanner agreement.

What changed

  • scripts/ssh_evidence.sh -- bounded read-only Ricochet-store probe (sudo -n over the live /var/lib/ricochet/data/content store and the separate-filesystem backup /opt/data/backup/ricochet), jwt dist-info capture per store, running-deployment process list plus /proc mountinfo mapping every /work/.venv process to its source bundle, a bounded ricochet-only refresh for cached evidence predating the probe, and the full collection now appends the probe and parses it into the evidence payload (header documents the sudo use and the NOPASSWD basis)
  • scripts/derive_findings.py -- stdlib derivation lane joins the ricochet evidence: ricochetInstalled / claimedVersionRicochetInstalled / ricochetGap per finding, and ricochet evidence counts toward scanner agreement (rpm OR pip OR ricochet => trivy-silent)
  • src/dse_security_reports/derive.py -- polars lane mirrors the same join byte-identically
  • tests/test_derive.py -- tests for the store parsing across both layouts and for the refusal path (a refused store is a recorded gap, never an absence)
  • AGENTS.md -- one-clause note in the evidence-pipeline entry documenting the probe and its never-an-absence rule

Behaviour change

A root-only Ricochet store that earlier rounds read as "not present" now surfaces as an explicit gap in the derived findings, and a pyjwt claim backed by a Ricochet-store dist-info reads as installed. The fixture lane is unaffected: just all, just repro, just py-crosscheck and the test suite all pass offline. The only port from the preserved patch: two hunks were adapted to the shared ssh_common.sh resolution (SSH_ALIAS/SSH_TARGET/SSH_OPTS) that landed with the interactive ssh shorthands; everything else is the preserved patch verbatim.

Instructions-PR: none

## Summary The Ricochet deployment stores hold the deployed application virtualenvs, and every earlier inventory missed them: the stores are root-only, so a permission-denied subtree silently contributed nothing to `find`, and that miss is exactly what let a false-positive verdict through on the first pass and turned it into a confirmed finding only on the second. This change originates from the pyjwt verification work (preserved worktree commit b620538, authored on 6afae77) and adds a deterministic, read-only Ricochet-store probe to the evidence collector so that gap can never silently recur. The probe uses `sudo -n` (documented in the script header: the evidence account holds NOPASSWD sudo), a refused store is recorded as an explicit gap with a non-zero `probeExit` -- never as an absence -- and both derivation lanes join `ricochetInstalled` / `claimedVersionRicochetInstalled` / `ricochetGap` per finding, with ricochet-verified claims counting as installed for scanner agreement. ## What changed - `scripts/ssh_evidence.sh` -- bounded read-only Ricochet-store probe (`sudo -n` over the live `/var/lib/ricochet/data/content` store and the separate-filesystem backup `/opt/data/backup/ricochet`), jwt dist-info capture per store, running-deployment process list plus `/proc` mountinfo mapping every `/work/.venv` process to its source bundle, a bounded ricochet-only refresh for cached evidence predating the probe, and the full collection now appends the probe and parses it into the evidence payload (header documents the sudo use and the NOPASSWD basis) - `scripts/derive_findings.py` -- stdlib derivation lane joins the ricochet evidence: `ricochetInstalled` / `claimedVersionRicochetInstalled` / `ricochetGap` per finding, and ricochet evidence counts toward scanner agreement (rpm OR pip OR ricochet => trivy-silent) - `src/dse_security_reports/derive.py` -- polars lane mirrors the same join byte-identically - `tests/test_derive.py` -- tests for the store parsing across both layouts and for the refusal path (a refused store is a recorded gap, never an absence) - `AGENTS.md` -- one-clause note in the evidence-pipeline entry documenting the probe and its never-an-absence rule ## Behaviour change A root-only Ricochet store that earlier rounds read as "not present" now surfaces as an explicit gap in the derived findings, and a pyjwt claim backed by a Ricochet-store dist-info reads as installed. The fixture lane is unaffected: `just all`, `just repro`, `just py-crosscheck` and the test suite all pass offline. The only port from the preserved patch: two hunks were adapted to the shared `ssh_common.sh` resolution (`SSH_ALIAS`/`SSH_TARGET`/`SSH_OPTS`) that landed with the interactive ssh shorthands; everything else is the preserved patch verbatim. Instructions-PR: none
- Probe the live store /var/lib/ricochet/data/content and the backup copy
  /opt/data/backup/ricochet (separate filesystem) read-only with sudo -n;
  a refused store is a recorded gap (non-zero probeExit), never an absence
- Capture jwt dist-infos per store plus the running deployments (process
  list and /proc mountinfo mapping /work to its source bundle)
- Bounded ricochet-only refresh for cached evidence predating the probe
- Derive joins: ricochetInstalled / claimedVersionRicochetInstalled /
  ricochetGap per finding, Ricochet evidence counts toward scanner
  agreement (rpm OR pip OR ricochet => trivy-silent), both lanes
  byte-identical, fixture unaffected
- Ported from worktree commit b620538 (authored on 6afae77) onto main:
  the ricochet refresh block and the remote-command append now use the
  shared ssh_common.sh resolution (SSH_ALIAS/SSH_TARGET/SSH_OPTS) that
  landed with the interactive ssh shorthands
Philipp Baumann deleted branch fm/dse-security-reports-ricochet-store-probe 2026-10-28 07:50:03 +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!21
No description provided.