6.3 KiB
Quiet-by-Default Triage with Attested Exceptions
Status: VALIDATED - Backend infrastructure fully implemented Archived: 2026-01-06 Related Sprints: SPRINT_20260106_004_001_FE_quiet_triage_ux_integration
Original Advisory
Here's a simple, noise-cutting design for container/security scan results that balances speed, evidence, and auditability.
Quiet-by-default triage, attested exceptions, and provenance drill-downs
Why this matters (quick context): Modern scanners flood teams with CVEs. Most aren't reachable in your runtime, many are already mitigated, and auditors still want proof. The goal is to surface what truly needs action, keep everything else reviewable, and leave a cryptographic paper trail.
1) Scan triage lanes (Quiet vs Review)
- Quiet lane (default): Only show findings that are reachable, affecting your runtime, and lack a valid VEX (Vulnerability Exploitability eXchange) statement. Everything else stays out of your way.
- Review lane: Every remaining signal (unreachable, dev-only deps, already-VEXed, kernel-gated, sandboxed, etc.).
- One-click export: Any lane/view exports an attested rationale (hashes, rules fired, inputs/versions) as a signed record for auditors. Keeps the UI calm while preserving evidence.
How it decides "Quiet":
- Call-graph reachability (package -> symbol -> call-path to entrypoints).
- Runtime context (containers, namespaces, seccomp/AppArmor, user/group, capabilities).
- Policy/VEX merge (vendor VEX + your org policy + exploit intel).
- Environment facts (network egress, isolation, feature flags).
2) Exception / VEX approval flow
-
Two steps:
- Proposer selects finding(s), adds rationale (backport present, not loaded, unreachable, compensating control).
- Approver sees call-path, exploit/telemetry signal, and the applicable policy clause side-by-side.
-
Output: Approval emits a signed VEX plus a policy attestation (what rule allowed it, when, by whom). These propagate across services so the same CVE is quiet elsewhere automatically--no ticket ping-pong.
3) Provenance drill-down (never lose "why")
- Breadcrumb bar:
image -> layer -> package -> symbol -> call-path. - Every hop shows its inline attestations (SBOM slice, build metadata, signatures, policy hits). You can answer "why is this green/red?" without context-switching.
What this feels like day-to-day
- Inbox shows only actionables; everything else is one click away in Review with evidence intact.
- Exceptions are deliberate and reversible, with proof you can hand to security/compliance.
- Engineers debug with a single visual path from image to code path, backed by signed facts.
Minimal data model you'll need
- SBOM (per image/layer) with package->file->symbol mapping.
- Reachability graph (entrypoints, handlers, jobs) + runtime observations.
- Policy/VEX store (vendor, OSS, and org-authored) with merge/versioning.
- Attestation ledger (hashes, timestamps, signers, inputs/outputs for exports).
Fast implementation sketch
- Start with triage rules:
reachable && affecting && !has_valid_VEX -> Quiet; else -> Review. - Build the breadcrumb UI on top of your existing SBOM + call-graph, then add inline attestation chips.
- Wrap exception approvals in a signer: on approve, generate VEX + policy attestation and broadcast.
If you want, I can draft the JSON schemas (SBOM slice, reachability edge, VEX record, attestation) and the exact UI wireframes for the lanes, approval modal, and breadcrumb bar.
Implementation Analysis (2026-01-06)
Status: FULLY IMPLEMENTED (Backend)
This advisory was analyzed against the existing StellaOps codebase and found to describe functionality that is already substantially implemented.
Implementation Matrix
| Advisory Concept | Implementation | Module | Status |
|---|---|---|---|
| Quiet vs Review lanes | TriageLane enum (6 states) |
Scanner.Triage | COMPLETE |
| Gating reasons | GatingReason enum + GatingReasonService |
Scanner.WebService | COMPLETE |
| Reachability gating | TriageReachabilityResult + MUTED_REACH lane |
Scanner.Triage + ReachGraph | COMPLETE |
| VEX consensus | 4-mode consensus engine | VexLens | COMPLETE |
| VEX trust scoring | VexTrustBreakdownDto (4-factor) |
Scanner.WebService | COMPLETE |
| Exception approval | ApprovalEndpoints + role gates (G0-G4) |
Scanner.WebService | COMPLETE |
| Signed decisions | TriageDecision + DSSE |
Scanner.Triage | COMPLETE |
| VEX emission | DeltaSigVexEmitter |
Scanner.Evidence | COMPLETE |
| Attestation chains | AttestationChain + Rekor v2 |
Attestor | COMPLETE |
| Evidence export | EvidenceLocker sealed bundles |
EvidenceLocker | COMPLETE |
| Structured rationale | VerdictReasonCode enum |
Policy.Engine | COMPLETE |
| Breadcrumb data model | Layer->Package->Symbol->CallPath | Scanner + ReachGraph + BinaryIndex | COMPLETE |
Key Implementation Files
Triage Infrastructure:
src/Scanner/__Libraries/StellaOps.Scanner.Triage/Entities/TriageEnums.cssrc/Scanner/__Libraries/StellaOps.Scanner.Triage/Entities/TriageFinding.cssrc/Scanner/__Libraries/StellaOps.Scanner.Triage/Entities/TriageDecision.cssrc/Scanner/StellaOps.Scanner.WebService/Services/GatingReasonService.cssrc/Scanner/StellaOps.Scanner.WebService/Contracts/GatingContracts.cs
Approval Flow:
src/Scanner/StellaOps.Scanner.WebService/Endpoints/ApprovalEndpoints.cssrc/Scanner/StellaOps.Scanner.WebService/Contracts/HumanApprovalStatement.cssrc/Scanner/StellaOps.Scanner.WebService/Contracts/AttestationChain.cs
VEX Consensus:
src/VexLens/StellaOps.VexLens/Consensus/IVexConsensusEngine.cssrc/VexLens/StellaOps.VexLens/Consensus/VexConsensusEngine.cs
UX Guide:
docs/ux/TRIAGE_UX_GUIDE.md
Remaining Work
The backend is feature-complete. Remaining work is frontend (Angular) integration of these existing APIs:
- Quiet lane toggle - UI component to switch between Quiet/Review views
- Gated bucket chips - Display
GatedBucketsSummaryDtocounts - Breadcrumb navigation - Visual path from image->layer->package->symbol->call-path
- Approval modal - Two-step propose/approve workflow UI
- Evidence export button - One-click bundle download
See: SPRINT_20260106_004_001_FE_quiet_triage_ux_integration