Trivy-operator in a Kubernetes cluster has the possibility to store the output of the trivy scans in a persistent volume:
https://artifacthub.io/packages/helm/trivy-operator/trivy-operator?modal=values&path=alternateReportStorage
The reports are there as JSON files in the following directory structure:
$ tree tmp/trivy-operator/
tmp/trivy-operator/
├── cluster_sbom_reports
├── cluster_vulnerability_reports
├── sbom_reports
│ └── ReplicaSet-waveform-manager-service-59d68d98ff-waveform-manager-service.json
├── secret_reports
│ └── ReplicaSet-waveform-manager-service-59d68d98ff-waveform-manager-service.json
└── vulnerability_reports
├── ReplicaSet-rester-69fc57bf46-rester.json
├── ReplicaSet-ui-processing-configuration-service-55b79c7c89-ui-processing-configuration-service.json
└── ReplicaSet-waveform-manager-service-59d68d98ff-waveform-manager-service.json
We could run trivy-vulnerability-explorer container in a pod in the trivy-operator namespace and mount the same persistent volume into a directory.
Having the possibility to select reports from a directory would allow us to use trivy-vulnerability-explorer as a frontend for the trivy-operator reports.
An example vulnerability report looks like:
{
"metadata": {
"name": "replicaset-rester-69fc57bf46-rester",
"namespace": "rester",
"labels": {
"app.kubernetes.io/managed-by": "trivy-operator",
"resource-spec-hash": "78848d9745",
"trivy-operator.container.name": "rester",
"trivy-operator.resource.kind": "ReplicaSet",
"trivy-operator.resource.name": "rester-69fc57bf46",
"trivy-operator.resource.namespace": "rester"
},
"annotations": {
"trivy-operator.aquasecurity.github.io/report-ttl": "24h0m0s"
},
"ownerReferences": [
{
"apiVersion": "apps/v1",
"kind": "ReplicaSet",
"name": "rester-69fc57bf46",
"uid": "528fac75-b00d-4848-a1cf-c5b0ace58f33",
"controller": true,
"blockOwnerDeletion": false
}
]
},
"report": {
"updateTimestamp": "2025-11-19T12:29:22Z",
"scanner": {
"name": "Trivy",
"vendor": "Aqua Security",
"version": "0.66.0"
},
"registry": {
"server": "registry.example.com"
},
"artifact": {
"repository": "rester/rester",
"digest": "sha256:ff2edc41e6829eed589492b580ca3d4779944929e3ded14144109331cbf7708",
"tag": "0.1.7-6"
},
"os": {
"family": ""
},
"summary": {
"criticalCount": 0,
"highCount": 8,
"mediumCount": 12,
"lowCount": 0,
"unknownCount": 0,
"noneCount": 0
},
"vulnerabilities": [
{
"vulnerabilityID": "CVE-2025-58183",
"resource": "stdlib",
"installedVersion": "v1.24.6",
"fixedVersion": "1.24.8, 1.25.2",
"publishedDate": "2025-10-29T23:16:19Z",
"lastModifiedDate": "2025-11-04T22:16:33Z",
"severity": "HIGH",
"title": "golang: archive/tar: Unbounded allocation when parsing GNU sparse map",
"primaryLink": "https://avd.aquasec.com/nvd/cve-2025-58183",
"links": [],
"score": 4.3,
"target": "",
"packagePURL": "pkg:golang/stdlib@v1.24.6"
},
Ideally, the default directory could be taken from an environment variable (so we do not need to type in the directory every time but rather configure it through the env var).
Trivy-operator in a Kubernetes cluster has the possibility to store the output of the trivy scans in a persistent volume:
https://artifacthub.io/packages/helm/trivy-operator/trivy-operator?modal=values&path=alternateReportStorage
The reports are there as JSON files in the following directory structure:
We could run
trivy-vulnerability-explorercontainer in a pod in thetrivy-operatornamespace and mount the same persistent volume into a directory.Having the possibility to select reports from a directory would allow us to use
trivy-vulnerability-exploreras a frontend for the trivy-operator reports.An example vulnerability report looks like:
{ "metadata": { "name": "replicaset-rester-69fc57bf46-rester", "namespace": "rester", "labels": { "app.kubernetes.io/managed-by": "trivy-operator", "resource-spec-hash": "78848d9745", "trivy-operator.container.name": "rester", "trivy-operator.resource.kind": "ReplicaSet", "trivy-operator.resource.name": "rester-69fc57bf46", "trivy-operator.resource.namespace": "rester" }, "annotations": { "trivy-operator.aquasecurity.github.io/report-ttl": "24h0m0s" }, "ownerReferences": [ { "apiVersion": "apps/v1", "kind": "ReplicaSet", "name": "rester-69fc57bf46", "uid": "528fac75-b00d-4848-a1cf-c5b0ace58f33", "controller": true, "blockOwnerDeletion": false } ] }, "report": { "updateTimestamp": "2025-11-19T12:29:22Z", "scanner": { "name": "Trivy", "vendor": "Aqua Security", "version": "0.66.0" }, "registry": { "server": "registry.example.com" }, "artifact": { "repository": "rester/rester", "digest": "sha256:ff2edc41e6829eed589492b580ca3d4779944929e3ded14144109331cbf7708", "tag": "0.1.7-6" }, "os": { "family": "" }, "summary": { "criticalCount": 0, "highCount": 8, "mediumCount": 12, "lowCount": 0, "unknownCount": 0, "noneCount": 0 }, "vulnerabilities": [ { "vulnerabilityID": "CVE-2025-58183", "resource": "stdlib", "installedVersion": "v1.24.6", "fixedVersion": "1.24.8, 1.25.2", "publishedDate": "2025-10-29T23:16:19Z", "lastModifiedDate": "2025-11-04T22:16:33Z", "severity": "HIGH", "title": "golang: archive/tar: Unbounded allocation when parsing GNU sparse map", "primaryLink": "https://avd.aquasec.com/nvd/cve-2025-58183", "links": [], "score": 4.3, "target": "", "packagePURL": "pkg:golang/stdlib@v1.24.6" },Ideally, the default directory could be taken from an environment variable (so we do not need to type in the directory every time but rather configure it through the env var).