KubeBolt docs
GitHub

Trivy: vulnerabilities and misconfiguration

Install Trivy Operator and light up three of the four security lenses — CVEs, misconfiguration, RBAC posture and the CIS benchmark.

Trivy Operator scans what is actually running: the CVEs in your images, workload misconfiguration, exposed secrets, RBAC posture and the CIS benchmark. Its findings land across the Vulnerabilities, Configuration, Permissions and Compliance lenses of Security & Compliance.

Nothing is pushed. Trivy writes CRDs and KubeBolt lists them on its sweep — no token, no webhook, no exposed endpoint.

Install

helm repo add aqua https://aquasecurity.github.io/helm-charts/
helm install trivy-operator aqua/trivy-operator \
  -n trivy-system --create-namespace \
  --set="trivy.ignoreUnfixed=true"

ignoreUnfixed=true is a recommendation, not a requirement. A CVE with no published fix is real, but it is not a task — there is nothing to upgrade to. Turn it off when you need the full inventory for an audit, and expect the list to grow a lot.

The CIS benchmark ships as a separate report on its own schedule. Nothing extra to install.

How KubeBolt finds it

By the label app.kubernetes.io/name=trivy-operator, falling back to pods named trivy-operator* in the trivy-system, trivy-operator or security namespaces. A hand-rolled manifest without the standard labels is still found if it lives in one of those.

Verify

Reports appear a few minutes after install, one per workload:

kubectl get vulnerabilityreports -A
kubectl get configauditreports -A
kubectl get clustercompliancereports
SymptomCause
Card says “not installed”No pods matching the label or the fallback namespaces
Card says “degraded”Operator pods present but not Ready
Reports exist, no CVEs in KubeBoltThey are all MEDIUM/LOW — see below
No reports after 10 minutesThe operator cannot pull images (private registry, no credentials)
CIS empty, everything else fineThe compliance report runs on its own schedule; give it a cycle

What becomes a finding

CVEs: only CRITICAL and HIGH. MEDIUM and LOW are dropped on purpose. On a busy cluster they are thousands of rows, and a list nobody can finish is a list nobody reads. The full detail always stays in the reports themselves.

Misconfiguration: CRITICAL, HIGH and MEDIUM. Wider than the CVE gate, deliberately. Trivy’s MEDIUM band is where “runs as root”, “can escalate its own privileges” and “seccomp disabled” live — several of those matter more than things it calls HIGH. LOW is dropped: it is dominated by “runs with a high UID” and “CPU/memory not limited”, and the latter is a capacity concern KubeBolt already raises as an insight.

Compliance: only failing controls. A passing control produces nothing.

Exposed secrets are counted apart from CVEs, and they have no severity gate: a LOW one is still a live credential in a layer anyone who can pull the image can read. An unrecognised severity band is treated as HIGH. The finding never contains the secret — Trivy’s partially masked match text is not stored, only the file and the image — and the remediation says to rotate the credential, not just remove it.

RBAC assessment: CRITICAL, HIGH and MEDIUM, the same gate as misconfiguration, for both namespaced and cluster-wide roles.

Each CVE carries its remediation ready to act on — upgrade <pkg> <installed> → <fixed> — and the full image reference, rebuilt from the three fields Trivy splits it across. That last part matters more than it looks: two workloads sharing an image are one fix, and without the reference nothing in the row says so.

The CIS rollup trap

Some CIS controls are not independent checks — they are sums of checks KubeBolt already stores one by one. Any control whose checks are AVD-KSV-* is evaluated from the same config-audit reports that already produced their own findings.

Counting both would file the same problem twice: once as N workload misconfigurations, again as the control that groups them. Those controls are flagged as rollups, so the dashboard shows them as posture without adding them to the actionable total.

This was verified against a live cluster: for all 35 controls where both sides had data, the control’s own failing count equalled the summed failing results of exactly those checks. The duplication is arithmetic, not approximate.

Cost of the sweep. KubeBolt lists six report types per cluster, each a cluster-wide LIST across the agent tunnel. The cost tracks payload, not object count: measured on a dev cluster, 57 vulnerability reports took 110 ms while 120 config-audit reports took 29 ms — a vulnerability report carries hundreds of CVEs, an assessment report a handful of checks. If the sweep ever shows up in your latency, the lever is Trivy’s scan scope, not KubeBolt’s read.