Want your cluster configuration reviewed? The WZ-IT cluster audit reviews configuration, versions, access, network policies, secrets and backups of a Kubernetes cluster against the CIS Kubernetes Benchmark and BSI IT-Grundschutz and delivers a report with prioritized measures. See the Kubernetes cluster audit
Trivy is an open-source scanner from Aqua Security for known vulnerabilities, misconfigurations and secrets in images, manifests and clusters. For Kubernetes there are three modes of operation, each answering a different question: trivy image in the pipeline, trivy k8s on the CLI and the Trivy Operator in the cluster. This guide covers commands, installation, prioritization and the limits. As of October 2026: Trivy v0.76.1 (21 October 2026) and Trivy Operator v0.35.0 (5 October 2026, current GitHub release), both under Apache-2.0 (operator: LICENSE).
Table of contents
- What Trivy checks and how it determines findings
- Three modes of operation compared
- trivy image: checking images before deployment
- trivy k8s: checking the running cluster
- Trivy Operator: continuous operation in the cluster
- Operations: network access, telemetry and your own registry
- Prioritizing findings: a decision rule
- Limits and demarcation
- The scanner as part of the supply chain
- Status and methodology
- Our approach at WZ-IT
- Further guides
What Trivy checks and how it determines findings
| Target | Command | Checked |
|---|---|---|
| Container image | trivy image |
Vulnerabilities in OS and language packages plus secrets (default); optionally licenses, IaC files in the image and the image configuration (docs) |
| Manifests, Helm charts | trivy config |
Misconfigurations according to the built-in checks (docs) |
| Kubernetes cluster | trivy k8s |
Vulnerabilities in images and in control plane and node components, misconfigurations, secrets, RBAC, compliance profiles (docs) |
| Software bill of materials | --format cyclonedx |
SBOM of an image; for the cluster the KBOM of its components (docs) |
Vulnerability findings come from a version match against advisory sources (docs). That affects how to read them:
- For OS packages the distributor's advisories apply, not upstream data, because distributors backport fixes. The severity also comes from the distributor: CVE-2023-0464 is High in the NVD and Low at Red Hat, and Trivy shows Low.
- Packages from third-party sources are not covered. According to the docs, Trivy supports official distributor packages but not packages from third-party repositories or self-compiled packages. That avoids false alarms but can omit findings. When distributor advisories are delayed or missing,
--detection-priority comprehensiveadditionally draws on upstream advisories, at the cost of false alarms. - The default favors precision. A run without findings is no proof that nothing is vulnerable.
Three modes of operation compared
trivy image |
trivy k8s |
Trivy Operator | |
|---|---|---|---|
| Question | Is this artifact clean? | What runs now, how is it configured? | How does the state develop over time? |
| When | Build, before deployment | on demand, after changes | on workload changes; reports expire after 24 h (default) |
| Result | Console, JSON, SARIF, SBOM | Console, JSON, KBOM, compliance report | Custom resources in the cluster |
| Prerequisite | Access to the registry | kubeconfig with read rights | Deployment in the namespace trivy-system |
| Maturity per docs | command not marked experimental, individual options are | EXPERIMENTAL | project "incubating", CRDs may change |
trivy image: checking images before deployment
trivy image --severity HIGH,CRITICAL --ignore-unfixed --exit-code 1 registry.example.com/team/app:1.4.2
--ignore-unfixed hides findings without an available fix, --exit-code 1 makes the pipeline fail on a finding. Both were checked with v0.76.1 against a test image: with findings, the run ends with exit code 1. In GitHub Actions, the trivy-action integrates the scan:
- name: Trivy image scan
uses: aquasecurity/trivy-action@FULL-COMMIT-SHA # v0.36.0
with:
image-ref: registry.example.com/team/app:${{ github.sha }}
severity: CRITICAL,HIGH
ignore-unfixed: true
exit-code: "1"
Exceptions belong in a .trivyignore.yaml with a reason and an expiry date (fields id, statement, expired_at, paths). According to the docs the file is experimental and must be passed with --ignorefile (filtering). For code scanning interfaces, --format sarif provides the matching format (reporting).
Requests and limits are checked as well: for a Deployment without resource values, trivy config reported in v0.76.1, among others, KSV-0011 (CPU not limited), KSV-0015 (CPU requests not specified), KSV-0016 (Memory requests not specified) and KSV-0018 (Memory not limited), all with severity LOW. If you leave out CPU limits on purpose, document that in the ignore file (background in the guide on ResourceQuota and LimitRange):
misconfigurations:
- id: KSV-0011
statement: CPU limit deliberately not set, to avoid throttling
expired_at: 2027-04-30
trivy k8s: checking the running cluster
The command needs a kubeconfig with list rights on the resources of the API groups core, apps, batch, networking.k8s.io and rbac.authorization.k8s.io. The node collector, which gathers node configurations, starts jobs and creates a namespace; --disable-node-collector skips it and leaves out node findings (docs).
# Overview as a summary
trivy k8s --report summary
# One namespace, HIGH and CRITICAL only, with details
trivy k8s --include-namespaces production --severity HIGH,CRITICAL --report all
# Configuration and RBAC only, without pulling images
trivy k8s --scanners misconfig,rbac --skip-images --report summary
# Built-in compliance profile (CIS Kubernetes Benchmark v1.23)
trivy k8s --compliance k8s-cis-1.23 --report summary
# Bill of materials of the cluster components (KBOM) as CycloneDX
trivy k8s --format cyclonedx --output kbom.cdx.json
According to the CLI reference, --report defaults to all (reference), so always specify summary or all explicitly. Older guides write trivy k8s cluster: in v0.76.1 the positional argument is a kubeconfig context, and cluster ends, unless a context of that name exists, with the message context "cluster" does not exist. The docs themselves name one restriction: KBOM matching works for plain Kubernetes distributions but only to a limited degree for vendor variants, including some managed services. Then there is the version of the CIS profile: the built-in profile is based on version 1.23, while the CIS benchmark page currently lists 2.1.0 for Kubernetes. The result is an indication, not proof of conformance.
Trivy Operator: continuous operation in the cluster
The operator watches changes in the cluster, starts scan jobs and stores the results as custom resources, among them VulnerabilityReport, ConfigAuditReport, ExposedSecretReport, RbacAssessmentReport, InfraAssessmentReport, ClusterComplianceReport and SbomReport (docs).
helm repo add aqua https://aquasecurity.github.io/helm-charts/
helm repo update
helm install trivy-operator aqua/trivy-operator \
--namespace trivy-system --create-namespace \
--version CHART-VERSION \
--set trivy.ignoreUnfixed=true
kubectl get vulnerabilityreports -A -o wide
kubectl get configauditreports -A -o wide
Pin the chart version (Helm installation); As of 28 October 2026, 0.37.0 is the newest chart version in the Helm repository (app version 0.35.0); helm search repo aqua/trivy-operator --versions lists the available ones. These defaults from the values.yaml for v0.35.0 matter operationally:
- Scan jobs: up to 10 at the same time (
operator.scanJobsConcurrentLimit); per scan container the default is a request of 100m CPU and 100M memory and a limit of 500m and 500M (trivy.resources). This load needs room on the nodes and in the operator's namespace. - Database: in the default mode every scan job downloads the vulnerability database again, which can lead to rate limits.
operator.builtInTrivyServer=trueenables client-server mode with a shared database (docs). - Report lifetime: 24 hours (
operator.scannerReportTTL). - Metrics: the chart can provide Prometheus metrics and a ServiceMonitor.
The operator creates reports per container image of a workload; kubectl get vulnerabilityreports -o wide shows the count by severity for each report. The same image in ten Deployments appears ten times, so for assessment images count, not reports.
Operations: network access, telemetry and your own registry
In normal operation Trivy needs internet access. The databases for vulnerabilities, Java and checks are stored as OCI images in public registries, by default mirror.gcr.io and ghcr.io; the project points out possible rate limits under heavy load (network docs). To avoid external access, mirror the databases to your own registry and set --db-repository, --java-db-repository and --checks-bundle-repository (self-hosting). The mirror must be updated continuously, otherwise the findings go stale. Trivy also collects anonymous usage data (hash of a machine fingerprint, version, operating system, non-identifying scan options) and checks for updates through check.trivy.dev (telemetry). --disable-telemetry and --skip-version-check switch both off; they are two separate switches.
Prioritizing findings: a decision rule
A scan delivers candidates, not priorities. Trivy shows severity, CVSS values, fixed version and status for each finding (JSON fields Severity, CVSS, FixedVersion, Status, checked with v0.76.1). Statements on exploitation and reachability are missing. They come from the cluster and from external lists: the CISA KEV catalog for observed exploitation and the EPSS for the estimated probability of exploitation in the next 30 days. CVSS describes severity, not risk in your own operations. Our rule of procedure, in this order:
| Level | Finding | Action |
|---|---|---|
| 1 | Secret in an image or manifest | Rotate the secret, then rebuild the image |
| 2 | CVE in the KEV catalog, workload reachable from outside | Patch first or restrict access |
| 3 | CRITICAL or HIGH with a fixed version, workload reachable | Update base image or package in the next release |
| 4 | Misconfiguration with impact on compromise (privileged, hostPath, hostNetwork, far-reaching RBAC bindings) | Harden the manifest, apply the Pod Security Standards |
| 5 | CRITICAL or HIGH without a fixed version | Document the risk, compensate, add an exception with an expiry date |
| 6 | Remaining findings | Backlog, handle with base image updates |
Reachable means: a Service of type LoadBalancer or NodePort, a route via Ingress or Gateway, no restrictive network policy. VEX statements with the status not_affected (justification, for example, vulnerable_code_not_in_execute_path) hide findings; the --vex option is experimental and applies only with substantiated provenance (VEX).
Limits and demarcation
Trivy detects known vulnerabilities and misconfigurations at the time of the scan. It does not observe runtime behavior, does not assess exploitability and does not know unknown vulnerabilities. Other checks with a different subject sit alongside it:
| Trivy | Cluster audit | Vulnerability scan | CVE monitoring | |
|---|---|---|---|---|
| Subject | Images, manifests, cluster objects | Configuration, versions, access, network policies, secrets, backups | reachable services and systems on the network | software inventory of the systems including container images |
| Yardstick | Advisory databases, built-in checks | CIS Kubernetes Benchmark, BSI APP.4.4 | check routines of a scanner | continuous matching against CVE notices |
| Timing | Build, on demand, continuous | one-off | one-off or recurring | continuous |
| Result | Raw findings | Report with prioritized measures | Report with prioritization | prioritized alerts |
The cluster audit assesses what a scanner does not see, such as the restore path and the upgrade path. The vulnerability scan as a service works with OpenVAS from Greenbone and checks systems from the network; the layers of individual images are not its subject. CVE monitoring continuously matches the inventory against new CVE notices and classifies them by exposure.
The scanner as part of the supply chain
In March 2026, Trivy artifacts were compromised. On 19 March 2026 a manipulated release v0.69.4 appeared, 76 of 77 version tags of the trivy-action and all 7 tags of setup-trivy pointed to malicious code, and on 22 March 2026 manipulated Docker Hub images followed (v0.69.5 and v0.69.6). The malicious code in the manipulated actions read credentials from CI runners (security advisory GHSA-69fq-xp46-6x23). According to the advisory, images referenced by digest of an unchanged version and Actions pinned to a safe commit SHA, among others, were not affected (details on the timeframes are in the advisory). Four rules for integration follow:
- Pin the Trivy version and reference the image by digest.
- Pin GitHub Actions to the full commit SHA, not to a tag.
- Verify release signatures with cosign (the commands are in the advisory).
- Run scan jobs without deployment credentials.
Status and methodology
As of 28 October 2026. The basis is the Trivy documentation and repository (docs, CLI reference, release v0.76.1), the Trivy Operator documentation (chart values from the tag v0.35.0), the security advisory GHSA-69fq-xp46-6x23 and the pages of CIS, CISA and FIRST. Checked against v0.76.1 itself: the flags of trivy k8s and trivy image, the exit code, the JSON fields, the positional argument of trivy k8s, the misconfiguration findings for missing requests and limits and the ignore file for KSV-0011. Not executed: trivy k8s against a cluster and the Helm installation of the operator; for these, the statements of the documentation apply. The prioritization rule is a WZ-IT rule of procedure, not a Trivy requirement.
Our approach at WZ-IT
Trivy covers the level of images, manifests and cluster objects. In Managed Kubernetes operations, CVE assessment and hardening are part of the scope: vulnerabilities are classified, exposure is assessed and measures are implemented based on risk. Monitoring runs 24/7, and the response to P1 incidents follows the service level. For the configuration level against CIS and BSI there is the cluster audit, and for matching inventory and CVE notices there is CVE monitoring. Which scope suits a cluster is settled by an inventory, as the takeover checklist describes.
Further guides
- Kubernetes requests, limits, ResourceQuota and LimitRange
- Taking over a Kubernetes cluster: audit checklist
- Vulnerability scan as a service
- CVE monitoring
- Kubernetes support without a contract for individual tasks
Want your cluster reviewed and then operated? The cluster audit costs from €1,490 excl. VAT one-time and is credited against the first month of operations. Managed Kubernetes costs from €590 excl. VAT per cluster and month including 3 worker nodes, €129.90 for each additional worker node, cancellable monthly with 30 days' notice to the end of the month (as of October 2026).











