Repository navigation
Watch Vulns
Vulnerability findings as events in the live stream. Each new pod
image is inventoried and matched in the background, then reported as
source: "vuln" SecEvents:
- one
vuln_summaryevent per image, - one
vulnerabilityevent per loaded vuln (dormant ones stay in the summary count; usevulnsto list them).
sudo k3sec watch --vulns # new pods only (realtime)
sudo k3sec watch --vulns --rollback # + the pods already running
sudo k3sec watch --vulns --ebpf # + exec events promote dormant packages
sudo k3sec watch --vulns -o json | jq 'select(.source=="vuln")'sudo k3sec watch --vulns -n demo, then kubectl -n demo run python --image=python:3.12-slim -- sleep infinity:
14:44:48 NORMAL demo/pod/python Successfully assigned demo/python to k3sec-m4-node
14:44:48 NORMAL demo/pod/python Pulling image "python:3.12-slim"
14:44:53 NORMAL demo/pod/python Successfully pulled image "python:3.12-slim" in 4.576s (4.576s including waiting). Image size: 43284989 bytes.
14:44:53 NORMAL demo/pod/python Created container: python
14:44:53 NORMAL demo/pod/python Started container python
14:44:58 CRIT demo/python/python docker.io/library/python:3.12-slim: 164 vulns, 46 loaded (0 KEV loaded), 87 packages
14:44:58 CRIT demo/python/python CVE-2019-1010022 in libc-bin 2.41-12+deb13u4 (loaded, CVSS 9.8)
14:44:58 CRIT demo/python/python CVE-2019-1010022 in libc6 2.41-12+deb13u4 (loaded, CVSS 9.8)
14:44:58 ERROR demo/python/python CVE-2026-19499 in libc-bin 2.41-12+deb13u4 (loaded, CVSS 7.7)
14:44:58 ERROR demo/python/python CVE-2026-19499 in libc6 2.41-12+deb13u4 (loaded, CVSS 7.7)
Five seconds from Started container to the findings: a 3 s settle delay (so
the process has mapped its libraries), the inventory, one API call for the new
digest (69 CVEs to enrich, stderr: INFO enriching CVEs (CVSS, KEV) cves=69).
With the nginx image, the loaded KEV is its own critical event:
13:54:56 CRIT demo/nginx-75b7c5fd7b-dhmqv/nginx docker.io/library/nginx:1.25.3: 829 vulns, 104 loaded (1 KEV loaded), 149 packages
13:54:56 CRIT demo/nginx-75b7c5fd7b-dhmqv/nginx CVE-2023-44487 in nginx 1.25.3-1~bookworm (loaded, KEV, CVSS 7.5)
A Go image with nothing loaded from OS packages (caddy:2.7.6, -o json):
{"source":"vuln","kind":"vuln_summary","severity":"info","namespace":"demo","object":"caddy/caddy","message":"docker.io/library/caddy:2.7.6: 210 vulns, 0 loaded (0 KEV loaded), 147 packages", "...": "..."}The 210 are in the Alpine base (dormant) and in Go modules of the static
caddy binary. This output is from 1.4.0, where those modules were
unknown: no loaded finding, so no vulnerability event, and
the summary is info. Since 1.5.1 the modules of the running caddy binary
are loaded, and their vulnerabilities are reported.
| Finding | Event severity |
|---|---|
| loaded and KEV | critical |
| CVSS ≥ 9.0 | critical |
| CVSS ≥ 7.0 | error |
| CVSS ≥ 4.0 | warning |
| CVSS > 0 | normal |
| unscored | info |
The summary takes the highest severity of its loaded findings (info if none).
-
Realtime: images of pods running when the watch starts are not
inventoried, unless
--rollback. - Once per digest: a second pod of an image already seen just joins it (no new inventory, no new events). Across runs, the cache avoids the API too.
- Off the hot path: inventories run as background tasks, at most 2 at a time; the pod watch and the other sources never wait on them. The pod watch drops (never blocks) when the queue (256) is full.
-
Namespace:
-nrestricts which pods are inventoried. - Retries: a container that has no process yet is retried 3 times, 2 s apart.
The probe's exec events feed the watcher. When a container executes a binary
owned by a package that was dormant at inventory time, the package flips to
loaded and its vulns are emitted then, as vulnerability events. That is
the moment worth an alert: vulnerable code that just started running (a shell
spawned in a container, a debug tool, a cron job).
The exec'd path is resolved like the rest of reachability:
through /proc/<pid>/exe, else the execve path resolved inside the container
root (/bin/sh → /usr/bin/dash → dash).
On the lab, with the pods inventoried (--rollback), perl -e 1 in the
nginx pod: the exec event and 21 perl-base vulnerability events, all
loaded, within the same second (excerpt, -o json, fields trimmed):
18:26:09 ebpf exec /usr/bin/perl (perl)
18:26:09 vuln perl-base CVE-2023-31484 loaded nginx-57fcccff77-4hhkt/nginx
18:26:09 vuln perl-base CVE-2024-56406 loaded nginx-57fcccff77-4hhkt/nginx
See SecEvent schema. In short, a vulnerability event
carries cve, package, version, purl, vuln_severity, cvss, kev
(true / false / unknown), fixed, reachability, image, digest,
pod, container in metadata, and the full finding in payload.
Commands
Live stream
Vulnerabilities
Operations
Internals