The earliest stage of a software program venture carries engineering dangers which can be simple to miss. The software program doesn’t but exist, and the workforce is busy standing up infrastructure: provisioning servers, writing automation scripts, configuring entry controls, and establishing the scaffolding that all the pieces else will run on. The code that does this work—Terraform templates, Ansible playbooks, shell scripts, Dockerfiles—is software program too, and it has vulnerabilities.
The potential problem at this stage is restricted: Scripts that create infrastructure could be exploited to open again doorways. A misconfigured Id and Entry Administration (IAM) function, an uncovered port left open in a provisioning script, or an unpatched base picture can quietly turn out to be an entry level that persists by way of each part of the lifecycle that follows. As a result of these points are launched earlier than growth begins in earnest, they have a tendency to not seem within the ordinary growth metrics—no dash tickets, no code evaluation feedback. They’ll sit undetected for a very long time.
The excellent news is that venture inception is among the most instrumentation-friendly levels in your entire lifecycle. As this submit illustrates, vulnerability scanning is a well-understood downside with mature tooling, and the output of that tooling is strictly the type of structured, time-series information that lends itself to efficient visualization.
What to Measure
The helpful metric on the inception and venture configuration stage is the infrastructure vulnerability report: This can be a document of which recognized vulnerabilities (CVEs) are current in your infrastructure, at what ranges of severity, and the way that image is altering over time.
A single vulnerability report is a snapshot. What we actually need is a collection of snapshots—one per scan—so we will reply questions like the next:
- Are new vulnerabilities showing quicker than we’re resolving them?
- Is a selected CVE recurring after we thought it was patched?
- Are sure parts persistently chargeable for the majority of our publicity?
The time dimension is what turns a safety report right into a monitoring software.
The Visualization: A CVE Presence Warmth Map
One of the crucial efficient methods to show this info is thru a warmth map with CVEs on one axis and scan dates on the opposite. On this visualization, every cell represents whether or not a given vulnerability was detected on a given date, and the cell’s colour encodes its severity. The outcome resembles one thing like the warmth map in Determine 1.

H = Excessive severity (purple), M = Medium (orange), L = Low (yellow), [ ] = not detected
What makes this format highly effective is that it exposes patterns {that a} static snapshot can’t. A row the place the identical CVE lights up on alternating dates suggests a remediation that isn’t sticking—the vulnerability is being patched and reintroduced. A column that goes instantly dense with high-severity findings suggests {that a} base picture replace launched a batch of latest points. A CVE that seems as soon as and by no means once more is nearly definitely resolved; one which retains showing is a candidate for escalation.
The human visible system is exceptionally good at detecting these sorts of patterns in a grid. Introduced as a sorted desk of CVE IDs and severity scores, the identical information would require cautious studying. Introduced as a warmth map, the patterns are instantly seen.
Please be aware that within the illustration above the CVE change fee is artificially proven as occurring each day to indicate how the visualization ought to work. In actuality, adjustments are extra delicate and spaced in time. The precise fee will increase primarily based on the variety of dependencies inside a venture. Any adjustments to the variety of dependencies inside a venture could lead to elevated vulnerabilities.
Getting the Information
If you wish to play with this visualization, you’ll need two issues: a vulnerability scanner and a solution to retailer its output over time.
Scanning your infrastructure with Trivy
Trivy is a free, open-source vulnerability scanner that works towards container photos, filesystems, Git repositories, and infrastructure as code (IaC) recordsdata (e.g., Terraform, Dockerfile, Helm charts). It produces structured JSON output that maps on to what we’d like.
To scan a container picture, kind the command
trivy picture --format json --output outcomes.json your-base-image:lates
Equally, to scan an IaC listing, you’ll be able to kind
trivy config --format json --output outcomes.json ./infrastructure/
The JSON output consists of CVE IDs, severity scores, affected packages, and repair availability. A light-weight Python script can parse this output and append a dated document to a working log—one row per CVE per scan date.
Constructing the Time-series Log
import json
import csv
from datetime import date
def append_scan_results(results_file, log_file):
scan_date = date.at the moment().isoformat()
with open(results_file) as f:
outcomes = json.load(f)
rows = []
for lead to outcomes.get("Outcomes", []):
for vuln in outcome.get("Vulnerabilities", []):
rows.append({
"date": scan_date,
"cve_id": vuln.get("VulnerabilityID"),
"severity": vuln.get("Severity"),
"package deal": vuln.get("PkgName"),
"fixed_version": vuln.get("FixedVersion", "none")
})
with open(log_file, "a", newline="") as f:
author = csv.DictWriter(f, fieldnames=rows[0].keys())
author.writerows(rows)
append_scan_results("outcomes.json", "vulnerability_log.csv")
Run this script after every scan—ideally as a step in your steady integration (CI) pipeline—and over time you’ll accumulate precisely the info you could construct the warmth map.
Rendering the warmth map
With the log in hand, a couple of traces of Python utilizing packages pandas and seaborn will produce the visualization:
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
df = pd.read_csv("vulnerability_log.csv")
# Pivot to a matrix: CVEs as rows, dates as columns
# Use severity because the cell worth (encode as numeric for colour mapping)
severity_map = {"CRITICAL": 4, "HIGH": 3, "MEDIUM": 2, "LOW": 1}
df["severity_score"] = df["severity"].map(severity_map)
matrix = df.pivot_table(
index="cve_id",
columns="date",
values="severity_score",
aggfunc="max"
).fillna(0)
plt.determine(figsize=(14, 8))
sns.heatmap(
matrix,
cmap=["#f5f5e8", "#ffffcc", "#f4a460", "#e05c5c", "#8b0000"],
linewidths=0.5,
linecolor="#cccccc"
)
plt.title("CVE Presence Over Time")
plt.tight_layout()
plt.savefig("cve_heatmap.png", dpi=150)
In case your workforce makes use of a distinct scanner—OPENVAS, Grype, Snyk—the construction is similar: extract CVE ID, severity, and date; construct the pivot desk; render the warmth map. The scanner is interchangeable; the visualization sample just isn’t.
What to Watch For
As soon as your warmth map is working, a couple of patterns are value calling out explicitly to your workforce:
Recurring rows. A CVE that disappears and reappears is a remediation downside, not a detection downside. The repair just isn’t being utilized persistently—maybe it lives in a base picture that will get periodically reset, or the repair is being utilized in a single setting however not one other.
Dense columns. A scan date with an unusually excessive focus of latest findings usually correlates with a base picture replace, a brand new dependency being added to the infrastructure stack, or a newly revealed batch of CVEs. It’s value correlating these columns along with your infrastructure change log.
Lengthy-lived high-severity rows. A excessive or essential CVE that persists throughout many dates with out decision deserves specific escalation. Warmth maps make these seen at a look in a means {that a} sorted report doesn’t.
Rows that clear and keep clear. These are your wins. A CVE that disappears and stays gone is proof that your remediation course of is working. Don’t ignore the excellent news—it calibrates your workforce’s sense of what “regular” appears to be like like.
Becoming a CVE Warmth Map into Your Workflow
The perfect integration is a scheduled scan that runs at any time when infrastructure code adjustments, both on decide to the infrastructure repository or, at a minimal, on a nightly cron schedule. The output will get appended to the log, and the warmth map regenerates mechanically.
In a steady integration and steady supply (CI/CD) context, you’ll be able to configure the scan to fail the pipeline if any critical-severity CVEs are detected in newly launched infrastructure code, whereas permitting lower-severity findings to move by way of to the log for monitoring. This creates a tough gate for probably the most critical points whereas sustaining visibility throughout the complete vulnerability panorama.
The important thing precept is that the scan ought to run on a schedule, not simply when somebody remembers to run it. The worth of the warmth map comes from the time collection. A one-time scan produces a snapshot, however it’s the accumulation of scans over time that produces the sample recognition functionality we’re after.
Coming Up Subsequent in Data Visualization in DevOps
That is the second submit in a collection, Data Visualization in DevOps. In case you have not learn the introduction, begin there for an summary of the collection and the monitoring framework we might be constructing towards.
Within the subsequent submit, we are going to transfer deeper into the event cycle and take a look at the Code/Commit/CI part. The chance there’s completely different: not exterior vulnerabilities, however the complexity that comes from the natural progress of a codebase itself. We’ll discover how one can visualize commit patterns, codebase progress by part, and dash velocity in ways in which floor early warning indicators of technical threat earlier than it manifests as failures downstream.
This submit is a part of the Data Visualization in DevOps collection. Learn the primary submit within the collection, Data Visualization as a DevOps Monitoring Instrument.

