Skip to content

Trivy Operator

Runtime vulnerability scanning for every image running in the cluster. Deployed as the trivy-operator Argo CD platform app (k8s/envs/platform/trivy-operator/), Aqua's trivy-operator Helm chart in the trivy-system namespace.

Why it exists

The cluster runs two kinds of images and they need different scanning:

Image kind Examples Scanned by
Ours (we build them) tomoda-backend, tomoda-frontend trivy step in Cloud Build — blocks a bad image before it reaches the registry
Third-party infra (upstream charts) argocd, traefik, cert-manager, ESO, loki, tempo, cnpg, redis, oauth2-proxy Trivy Operator — the only thing that sees them

Build-time trivy can't cover the infra images: we don't build them, so there's no build to hook. Trivy Operator closes that gap by scanning whatever is actually running, on a schedule, so newly-disclosed CVEs against long-running infra pods surface too.

What it does

The operator watches every workload and creates a VulnerabilityReport CRD per container, plus a ConfigAuditReport for misconfig checks. Query them like any resource:

# Vulnerability reports across the cluster
kubectl get vulnerabilityreports -A

# HIGH/CRITICAL counts for a specific report
kubectl get vulnerabilityreport -n <ns> <name> \
  -o jsonpath='{.report.summary}'

Configuration

Tuned deliberately for this small, memory-tight cluster (application.yaml):

  • severity: HIGH,CRITICAL + ignoreUnfixed: true — only actionable findings. No noise from LOW/MEDIUM or CVEs with no available fix.
  • scanJobsConcurrentLimit: 1 — scan jobs never stampede the node pool (capped at 3, memory-tight). One scan at a time.
  • Scan-job resources capped (500m CPU / 500Mi mem limit) so a scan can't evict a workload.
  • Only vuln + config-audit scanners — the RBAC, infra-assessment, and cluster-compliance scanners are off; we don't consume them yet.
  • scannerReportTTL: 24h — reports refresh daily, picking up new CVEs against running images.

Metrics + alerting

serviceMonitor.enabled: true — the operator exposes Prometheus metrics and the chart ships a ServiceMonitor, so the existing monitoring stack scrapes vulnerability counts automatically. Add a PrometheusRule alerting on a rising CRITICAL count when you want to be paged on new findings.

Relationship to build-time scanning

Two layers, not a choice between them:

  • Build-time (trivy in Cloud Build) — gate: a bad tomoda-* image never gets pushed. See Cloud Build → Vulnerability scanning.
  • Runtime (this operator) — coverage: everything running, including infra, re-checked daily.

Artifact Registry's built-in paid scanning stays off — it only covers images pushed to our AR (not the upstream infra images) and bills per scan. Trivy Operator covers strictly more, for free.