fix(vuln): survive OOM kills, isolate bad upstream strings, label findings per line

Review findings on the integrated scanner:
- An OOM kill no longer wedges the loop: inFlight is persisted before each scan, and on restart
  that image is marked failed and sits out full runs for 20h.
- One bad upstream string can no longer freeze the report: safe_url requires an exact lowercase
  scheme, acceptance reasons are bounded, /triage urls use the same rule, and report.build
  repairs or drops any entry the schema would refuse. lastCompleteRunAt advances only after a
  report is actually published.
- The private registry reports credential-required, not failed: VULN_PRIVATE_REGISTRIES names
  it, and Trivy is not invoked.
- loadError clears after a full run against a good inventory.
- Every image under platform/vuln-scanner stays out of Renovate auto-merge.
- The page labels status and target state per line, and mixed acceptance reads as mixed.

The Keycloak client is still an operator action: its key must go in an existing encrypted file
that an agent must not modify. platform/vuln-scanner/README.md has the exact steps.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
jakman85andClaude Opus 5.5 committed 2026-11-09 12:28:29 -06:00
1 parent 4c82c64b2f
commit d8b25a67fe
15 files changed
+557 -43

No files matched your search

+7 -1
View File
@@ -133,6 +133,12 @@ spec:
value: /tools/ca-certificates.crt
- name: VULN_ACCEPTANCES
value: /config/acceptances.yaml
# Registries that need a credential this scanner deliberately does not hold (R-VULN-09).
# Comma-separated hostnames. They report credential-required WITHOUT invoking Trivy:
# the egress policy excludes the LAN, so a real attempt ends in a connection error and
# would read as `failed`, firing VulnCoverageGap permanently. Flux substitutes the domain.
- name: VULN_PRIVATE_REGISTRIES
value: gitea.${BASE_DOMAIN}
- name: PYTHONUNBUFFERED
value: "1"
- name: PYTHONDONTWRITEBYTECODE
@@ -222,7 +228,7 @@ spec:
env:
# client-secret MUST equal the Keycloak `vuln-scanner` client's secret (key
# vuln-scanner-client-secret in platform/keycloak/keycloak-realm-clients.sops.yaml; see
# README.md, Operator step). Secrets by name only (R-IDP-04).
# README.md, Operator action required). Secrets by name only (R-IDP-04).
- name: OAUTH2_PROXY_CLIENT_ID
valueFrom:
secretKeyRef: { name: vuln-scanner-oauth2-proxy, key: client-id }