Files
Thore Cimbal b989987d69 cve: four rules and three panels guard the derivation (#0106)
Gate 3 planned three rules; there are four. The fourth covers a case the others
miss entirely: every source answers cleanly but empty. Then nothing is missing,
because the desired set is empty, the freshness stamps are current, and nothing
is scanned at all. The Python suite already carries that case as "an empty set
is not the same as success", so the rule belongs with it.

These are the first rule unit tests in this stack. Each rule has a case where it
must fire and one where it must stay silent, because a rule that always fires
cannot be told from a correct one otherwise. Two sabotages confirm the tests
bite: an unreachable threshold on the source-freshness rule makes the expected
alert vanish, and removing the six hour grace period makes the missing-targets
rule fire at five hours where the test demands silence.

The grace period is not padding. A full round over roughly 65 images takes time,
so right after a deploy the gap is real rather than wrong.

The dashboard gains coverage and unscanned-image counters in the two free slots
of the top row, and a source-freshness bar at the bottom, so no existing panel
moves. That bar is the only place where a failed derivation can be told apart
from success.
2026-08-21 12:00:00 +00:00

422 lines
9.0 KiB
JSON

{
"title": "CVE-Übersicht (Trivy)",
"uid": "cve-overview",
"tags": [
"security",
"cve",
"gitops-47"
],
"timezone": "browser",
"schemaVersion": 39,
"refresh": "5m",
"time": {
"from": "now-30d",
"to": "now"
},
"panels": [
{
"type": "stat",
"title": "Offene CRITICAL",
"id": 1,
"gridPos": {
"x": 0,
"y": 0,
"w": 4,
"h": 4
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 1
}
]
}
},
"overrides": []
},
"targets": [
{
"expr": "sum(trivy_vuln_count{severity=\"CRITICAL\"}) or vector(0)",
"instant": true,
"refId": "A"
}
]
},
{
"type": "stat",
"title": "Offene HIGH",
"id": 2,
"gridPos": {
"x": 4,
"y": 0,
"w": 4,
"h": 4
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "orange",
"value": 1
}
]
}
},
"overrides": []
},
"targets": [
{
"expr": "sum(trivy_vuln_count{severity=\"HIGH\"}) or vector(0)",
"instant": true,
"refId": "A"
}
]
},
{
"type": "stat",
"title": "MEDIUM/LOW (Summe)",
"id": 3,
"gridPos": {
"x": 8,
"y": 0,
"w": 4,
"h": 4
},
"targets": [
{
"expr": "sum(trivy_vuln_count{severity=~\"MEDIUM|LOW\"}) or vector(0)",
"instant": true,
"refId": "A"
}
]
},
{
"type": "stat",
"title": "Ältester Scan (Stunden)",
"id": 4,
"gridPos": {
"x": 12,
"y": 0,
"w": 4,
"h": 4
},
"fieldConfig": {
"defaults": {
"unit": "h",
"color": {
"mode": "thresholds"
},
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 48
}
]
}
},
"overrides": []
},
"targets": [
{
"expr": "(time() - min(trivy_last_scan_timestamp)) / 3600",
"instant": true,
"refId": "A"
}
]
},
{
"type": "table",
"title": "Offene CVEs (HIGH/CRITICAL) — CVE · Ort · Typ · Paket · Fix · seit",
"id": 5,
"gridPos": {
"x": 0,
"y": 4,
"w": 24,
"h": 12
},
"targets": [
{
"expr": "trivy_vuln_info",
"instant": true,
"format": "table",
"refId": "A"
},
{
"expr": "trivy_vuln_first_seen_timestamp * 1000",
"instant": true,
"format": "table",
"refId": "B"
}
],
"transformations": [
{
"id": "merge",
"options": {}
},
{
"id": "organize",
"options": {
"excludeByName": {
"Time": true,
"__name__": true,
"job": true,
"instance": true,
"Value #A": true
},
"renameByName": {
"cve": "CVE",
"severity": "Severity",
"host": "Ort (Host)",
"target_type": "Typ",
"target": "Target",
"pkg": "Paket",
"installed": "Installiert",
"fixed_version": "Fix-Version",
"Value #B": "Erstmals gesehen"
}
}
}
],
"fieldConfig": {
"defaults": {},
"overrides": [
{
"matcher": {
"id": "byName",
"options": "Erstmals gesehen"
},
"properties": [
{
"id": "unit",
"value": "dateTimeAsIso"
}
]
},
{
"matcher": {
"id": "byName",
"options": "CVE"
},
"properties": [
{
"id": "links",
"value": [
{
"title": "NVD (Mitigation/Details)",
"targetBlank": true,
"url": "https://nvd.nist.gov/vuln/detail/${__value.text}"
}
]
}
]
}
]
}
},
{
"type": "state-timeline",
"title": "Zeitstrahl: offene HIGH/CRITICAL je Target",
"id": 6,
"gridPos": {
"x": 0,
"y": 16,
"w": 24,
"h": 8
},
"targets": [
{
"expr": "count by (target) (trivy_vuln_info)",
"legendFormat": "{{target}}",
"refId": "A"
}
],
"fieldConfig": {
"defaults": {
"custom": {
"fillOpacity": 70
}
},
"overrides": []
}
},
{
"type": "timeseries",
"title": "Funde je Severity über Zeit",
"id": 7,
"gridPos": {
"x": 0,
"y": 24,
"w": 24,
"h": 8
},
"targets": [
{
"expr": "sum by (severity) (trivy_vuln_count)",
"legendFormat": "{{severity}}",
"refId": "A"
}
]
},
{
"type": "stat",
"title": "Deckung der Zielmenge",
"id": 8,
"gridPos": {
"x": 16,
"y": 0,
"w": 4,
"h": 4
},
"fieldConfig": {
"defaults": {
"unit": "percentunit",
"color": {
"mode": "thresholds"
},
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "red",
"value": null
},
{
"color": "orange",
"value": 0.9
},
{
"color": "green",
"value": 1
}
]
}
},
"overrides": []
},
"targets": [
{
"expr": "cve_target_coverage_ratio",
"instant": true,
"refId": "A"
}
]
},
{
"type": "stat",
"title": "Ungeprüfte Images",
"id": 9,
"gridPos": {
"x": 20,
"y": 0,
"w": 4,
"h": 4
},
"fieldConfig": {
"defaults": {
"unit": "none",
"color": {
"mode": "thresholds"
},
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 1
}
]
}
},
"overrides": []
},
"targets": [
{
"expr": "cve_targets_missing or vector(0)",
"instant": true,
"refId": "A"
}
]
},
{
"type": "bargauge",
"title": "Frische der Zielquellen (Sekunden seit letzter Herleitung)",
"id": 10,
"gridPos": {
"x": 0,
"y": 32,
"w": 24,
"h": 6
},
"description": "Faellt eine Quelle aus, wird die Soll-Menge kleiner - und die Deckung sieht dadurch BESSER aus statt schlechter. Diese Zeile ist die einzige Stelle, an der ein Ausfall der Herleitung von Erfolg zu unterscheiden ist (ADR-0026).",
"fieldConfig": {
"defaults": {
"unit": "s",
"color": {
"mode": "thresholds"
},
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "orange",
"value": 7200
},
{
"color": "red",
"value": 10800
}
]
}
},
"overrides": []
},
"options": {
"displayMode": "gradient",
"orientation": "horizontal"
},
"targets": [
{
"expr": "cve_target_source_stale",
"instant": true,
"refId": "A",
"legendFormat": "{{quelle}}"
}
]
}
]
}