Security engineering / Vulnerability management

Vulnerability Management

A Python workflow for scanner normalization, explainable remediation priority, and closure verified against matching rescans, with reproducible synthetic and local Trivy evidence.

Inspect the system

A completed local lab with an offline workflow demo and a captured Trivy dependency scan. The business processes are simulated.

Inputs
CSV, Trivy JSON v2, and Nessus v2 XML exports.
Workflow
Risk and SLA, reviewed dispositions, remediation, and rescan verification.
Scope
Local files and an inert dependency manifest; no production integrations.

Overview

I built this lab to make vulnerability decisions inspectable: where a finding came from, why it deserves attention, what remediation was recorded, and which later evidence supports closure.

Problem

Severity alone misses asset context. A lower risk score does not establish remediation, and a finding missing from an incomplete export does not prove it was fixed.

From observation to closure

  1. Normalize scanner exports
  2. Enrich asset context
  3. Calculate priority and SLA
  4. Record reviewed work
  5. Compare a matching rescan
  6. Report closure or continued work

Stable identities and provenance survive normalization. A transparent custom score combines technical severity, asset importance, exposure, threat context, age, and evidenced controls. Calendar-day SLAs retain the original first-seen date; accepting risk does not pause the clock.

Engineering decisions

Scanner observations and workflow decisions stay separate. Closure requires recorded remediation and a strictly later complete scan with matching scanner, scope, and asset coverage. Reappearing findings reopen. Time-bound exceptions and validated false positives remain visible with review dates.

Validation

The six-finding synthetic demo ends with two verified closures, one accepted risk, one validated false positive, and two actionable open findings. A separate real Trivy capture on September 7, 2026 found five vulnerabilities before a Requests manifest update and zero afterward; matching package coverage, timestamps, and hashes support five closures.

September 7, 2026 CI passed 212 tests in each Windows/Ubuntu and Python 3.11/3.14 matrix job, plus lint, configuration checks, and byte-for-byte comparisons of 13 synthetic-demo and 11 captured-scan artifacts.

Lessons / constraints

The real scan analyzes a direct-dependency manifest; it does not install packages, prove exploitability, or assess a running system. Nessus support is export parsing. Ownership and approvals are simulated, scoring is custom, and local JSON has no authenticated roles, concurrent transactions, or signed evidence.