Security CVE Watch
1. What? — Definition and context
Section titled “1. What? — Definition and context”Security CVE Watch is an N8N workflow that scans the VPS Docker images daily for known vulnerabilities (CVE), deduplicates findings, and only fires an alert for new ones or severity escalations.
Components
Section titled “Components”| Workflow | ID | Nodes | Role |
|---|---|---|---|
| CVE Watch (parent) | 5mHMlcg2HqEa7pWJ | 18 | Trigger + image loop + aggregation + notification |
| CVE Scanner (SW-1) | Tz40sFr3CMrw7X81 | 6 | Runs trivy image over SSH on a single image |
| CVE Processor (SW-2) | JCyc4Jkev8fQ1mwL | 9 | Dedup, classification, historical comparison |
Architecture diagram
Section titled “Architecture diagram”Coverage
Section titled “Coverage”About a dozen images of the VPS stacks are scanned: n8nio/n8n, odoo:18, caddy:2-alpine, postgres:16, postgres:17, redis:7-alpine, qdrant/qdrant, crowdsecurity/crowdsec, prom/prometheus, grafana/grafana. The list is derived from docker images --format at runtime, so any new stack is automatically picked up at the next scan.
2. Why? — Stakes and motivations
Section titled “2. Why? — Stakes and motivations”The problem without active watch
Section titled “The problem without active watch”CVEs published on Docker images don’t trigger anything automatically. A critical vulnerability on postgres:16 can sit unnoticed for weeks if no one explicitly checks the CVE feed or reads the registry changelog.
| Symptom without CVE Watch | Cause | Impact |
|---|---|---|
| Vulnerability not detected | No systematic scan | Extended exploitation window |
| Repeated false positives | No dedup | Noise, alert desensitisation |
| Slow trigger | Manual monitoring | No retry mechanism |
| No traceability | No scan history | Can’t prove past state |
Why Trivy over Snyk or Docker Scout?
Section titled “Why Trivy over Snyk or Docker Scout?”| Criterion | Trivy | Snyk | Docker Scout |
|---|---|---|---|
| Open source | Yes (Apache 2.0) | No | No |
| Self-hosted | Yes | Partial | No |
| CVE sources | NVD, Red Hat, Alpine, Debian, Ubuntu | NVD, Snyk DB | NVD, Snyk DB |
| Auth required | No | Token + quota | Docker Hub login |
| Offline scan | Yes (local DB) | No | No |
| JSON format | Stable, documented | Stable | Stable |
The Trivy choice aligns with the VPS self-hosted philosophy: no SaaS dependency, no API quota, no leak of the image list to a third party.
Three complementary triggers
Section titled “Three complementary triggers”| Trigger | Frequency | Use case |
|---|---|---|
| Cron daily 06:00 | Every day before working hours | Catch CVEs published the previous day |
| Cron weekly Monday 09:00 | Once a week | Weekly recap with trends |
| DIUN webhook | Every image pull | Scan a new version immediately |
The pairing with DIUN closes the loop: when DIUN detects a new image is available, the CVE scan fires before the Telegram approval, so an update introducing a security regression can be rejected.
3. How? — Technical implementation
Section titled “3. How? — Technical implementation”A scan’s journey
Section titled “A scan’s journey”1. Image inventory — The parent calls docker images --format '{{.Repository}}:{{.Tag}}' over local SSH to obtain the exact list of images loaded on the VPS at scan time.
2. Per-image loop — For each one, the parent calls the CVE Scanner sub-workflow via Execute Workflow.
3. Trivy scan — The Scanner SSHes into the VPS and runs docker exec trivy image --format json --severity CRITICAL,HIGH <image>. The trivy container is pre-installed and its CVE DB cache is mounted on a volume to avoid re-downloading 150 MB on every scan.
4. Result parsing — The Scanner parses the Trivy JSON and returns a normalised array {cve_id, severity, package, installed, fixed, title, cvss}.
5. Dedup and classification — The CVE Processor compares each finding with the cve_notifications table. Three cases:
| Case | Action |
|---|---|
| Unknown CVE | Insert with status=new, add to the notification list |
| Already-notified CVE | Skip (unless severity escalation) |
| CVE marked fixed | Verify the fix is actually applied, otherwise re-open |
6. Aggregation — The parent groups new findings by image and severity.
7. Notification — If at least one CRITICAL is present, the parent fires an immediate alert to the Notification Hub. Otherwise it waits for the weekly run for a digest.
Data Tables
Section titled “Data Tables”cve_notifications (Tfng3e4kUL0Ya4Lm)
Section titled “cve_notifications (Tfng3e4kUL0Ya4Lm)”| Column | Type | Description |
|---|---|---|
cve_id | string | CVE-YYYY-NNNNN |
image | string | repo:tag |
severity | string | CRITICAL / HIGH / MEDIUM / LOW |
package | string | Vulnerable package |
installed_version | string | Current version |
fixed_version | string | Version with the fix (or null) |
first_seen | datetime | First detection |
notified_at | datetime | Last notification time |
status | string | new / notified / fixed / ignored |
cve_scan_history (elUlUt9HzqSSCr7L)
Section titled “cve_scan_history (elUlUt9HzqSSCr7L)”| Column | Type | Description |
|---|---|---|
scan_date | datetime | Run timestamp |
images_scanned | number | Number of images analysed |
critical_count | number | CRITICAL CVEs detected |
high_count | number | HIGH CVEs detected |
report_sent | boolean | Notification sent? |
Notification format
Section titled “Notification format”Immediate CRITICAL alert routed via the Notification Hub:
🚨 CRITICAL CVE DETECTED
Image: postgres:16CVE: CVE-2026-12345Severity: CRITICAL (CVSS 9.8)Package: libpqInstalled: 16.2 → Fixed in: 16.3
Affected stacks:- n8n-stack (n8n-postgres)- odoo-stack (odoo-db)
[🔄 Update now] [📖 CVE details] [⏰ Defer]Weekly digest sent every Monday at 09:00:
📊 CVE Watch · Week 18
12 scans completed0 CRITICAL · 3 HIGH · 8 MEDIUM (ignored)
FIXES APPLIED:✅ postgres:16.2 → 16.3 (CVE-2026-12345)✅ caddy:2.8.4 → 2.8.5 (CVE-2026-12346)
PENDING:⏳ redis:7.2.3 → 7.2.4 (planned Sunday)DIUN integration
Section titled “DIUN integration”When DIUN detects that a new image version is available, its webhook also triggers CVE Watch on that specific image. The result is folded into the Telegram approval message:
| Case | Approval button |
|---|---|
| New version, no CVE | [Update] (green) |
| New version + resolved CVE | [Update fixes CVE-XXX] (green) |
| New version + new CVEs | [Update despite CVE] (orange) |
The user makes the call with the risk fully visible.
4. What if? — Outlook and limits
Section titled “4. What if? — Outlook and limits”Current limits
Section titled “Current limits”| Limit | Impact | Mitigation |
|---|---|---|
| CVE feed lag | A CVE published yesterday may not yet be in the Trivy DB | Pair with NVD RSS feed later |
| Application-level deps not scanned | Trivy scans OS packages, not package.json/requirements.txt deps inside the image | Cover with a separate GitHub Dependabot workflow |
| No contextual scoring | A CVSS 9.8 on an unused package is still flagged CRITICAL | Per-package whitelist via an error_handling_config-like setup (to design) |
| musl image false positives | Trivy sometimes classifies Debian CVEs on Alpine (musl) images | Ignore via Trivy --ignore-policy |
Evolution scenarios
Section titled “Evolution scenarios”If the daily cadence becomes insufficient:
- Drop to hourly scans for CRITICAL images
- Subscribe CVE Watch to a near-real-time NVD feed
- Pair with a Trivy server webhook (
--servermode)
If notification noise grows:
- Add a per-CVE accepted whitelist (with justification)
- Group CVEs by package rather than by CVE
- Only notify if CVSS ≥ 9.0 in strict mode
If a compliance need shows up:
- Keep JSON reports in an audit bucket
- Generate a signed monthly PDF
- Expose a read-only API for an external dashboard
Relevant metrics
Section titled “Relevant metrics”| Metric | Source | Interpretation |
|---|---|---|
cve_critical_open | cve_notifications WHERE status IN ('new','notified') AND severity='CRITICAL' | Must stay at 0 |
cve_mttr | Δ between first_seen and fixed_at | Mean Time To Resolution |
scan_failures | cve_scan_history WHERE images_scanned=0 | Scanner outage indicator |
Related pages
Section titled “Related pages”Infrastructure
Section titled “Infrastructure”- Security Stack — Caddy, CrowdSec, Trivy
- Notify Stack — DIUN that fires hot scans
- VPS Architecture — Big picture
Workflows
Section titled “Workflows”- Notification Hub — CVE alert routing
- Docker Updates — Approval workflow paired with CVE scans
- Monitoring Digests — Weekly digest including CVEs
Reference
Section titled “Reference”- Glossary — CVE, CVSS, Trivy