The module lifecycle stage: General Availability

The module has requirements for installation

v0.6.8

Release date: 2026-09-28

Security score of the cluster and of every user namespace; Grafana vulnerability and CIS dashboards removed in favour of Deckhouse Console; alerts when the Trivy vulnerability database is missing or outdated; reliable configuration audit, compliance and cluster SBOM reports; module images and dependencies updated to address CVEs.

Highlights

Changes in this release:

  • The module publishes a security score: a ClusterSecurityScore resource for the cluster and a SecurityScore resource in every user namespace, so a namespace score is granted together with access to the namespace itself.
  • Grafana dashboards Security / Trivy Image Vulnerability Overview and Security / CIS Kubernetes Benchmark are removed; use Deckhouse Console for vulnerability overview and CIS Benchmark results.
  • ClusterAlerts warn when trivy-db is missing or older than vulnerabilityDatabaseMaxAge (default 168h); set vulnerabilityDatabaseMaxAge to "" to disable both alerts.
  • Configuration audit, compliance and cluster SBOM (k8s-cluster) reports are complete again when reports are served by security-storage, and a failed scan job is repeated instead of leaving its workload without a report.
  • Dependencies and base images are updated to close CVEs.

New features

This release adds:

  • Security score of the cluster and of every user namespace. The cluster score lives in a ClusterSecurityScore resource named cluster, and a namespace score in a SecurityScore resource named security-score in that namespace. A namespace score is granted by the d8:use:capability:module:operator-trivy:view role together with access to the namespace, and the cluster score by the d8:manage:permission:module:operator-trivy:view role. A namespace is scored by the same formula as the cluster, without the cluster-scoped components: a namespace with no reports at all is limited to 60, and a namespace without scanning enabled always loses the whole coverage weight. A component with no reports behind it carries the notMeasured field and is excluded from the calculation instead of counting as a clean result.
  • The cluster score is exported to Prometheus as deckhouse_trivy_security_score, deckhouse_trivy_security_score_component, deckhouse_trivy_security_namespace_score_average, deckhouse_trivy_security_namespaces_total and deckhouse_trivy_security_namespaces_scanned. Per-namespace scores are not exported: on a large cluster that would add a time series for every namespace.
  • The RegistryScanTarget resource gained the spec.maxRepositories parameter: the number of repositories one cycle takes from the registry catalog when spec.repositories is empty, 100 by default. The catalog is read only as far as that limit, and the reports of the repositories left out are kept.
  • Added TrivyVulnerabilityDatabaseOutdated (S6) when trivy-db exceeds the configured freshness window, and TrivyVulnerabilityDatabaseMissing (S6, for: 30m) when ConfigMap trivy-db-info has no usable trivy-db.updatedAt stamp.

Improvements

This release improves:

  • Reports of registry-scanner name the version of the scanner that produced them. The scanner.version field of every RegistryImageVulnerabilityReport was empty, so a report could not be traced back to a Trivy release.
  • Vulnerability overview and CIS Benchmark results are expected from Deckhouse Console instead of the removed Grafana dashboards.
  • report-updater applies rotated registry credentials without a restart: the Docker configuration is read again on every renewal of the BDU dictionary.
  • report-updater names in the log the repository whose credentials it looked for and the registries the Docker configuration lists, when it finds no credentials and falls back to anonymous access. A configuration in which the auth field of any entry cannot be decoded is treated as invalid as a whole, and the error message names that entry.

Fixes

This release fixes:

  • A compliance report whose first generation fails at operator startup is logged and generated again a minute later instead of interrupting the reconcile. It waited for the next cron run, up to six hours by default, and a module update often left most reports empty for that time, because security-storage restarts together with the operator.
  • security-storage now chooses between a PersistentVolumeClaim and emptyDir by apiServerStorageClass. Setting only apiServerStorageClass to false left its pod waiting on a claim that was never created, and setting only storageClass to false provisioned a disk that nothing used.
  • Image scanning no longer stops when scanJob.podTemplateContainerSecurityContext is absent from the operator ConfigMap. The platform security context was applied to an empty value, so the scan jobs were never created.
  • Removing the security-scanning.deckhouse.io/enabled label from the last labeled namespace now updates the list of namespaces opted in for image scanning. The list was never reset, so the operator kept such a namespace in its scanning scope until the next Deckhouse restart. The list is also ordered now, so the operator is no longer restarted by a reordering of the same namespaces.
  • Image scanning no longer resumes in a namespace that has left the scanning scope. Even with the scope updated, the namespace list was enforced only on the watches of the workload controller, so deleting a report — by hand, or on lifetime expiry — rescanned its workload in any namespace. VulnerabilityReport left in such a namespace expires within one scanPeriods.workloadRescanPeriod and is no longer created again. ExposedSecretReport and SbomReport have no lifetime of their own and stay until their workload is deleted.
  • trivy version in the module image reported dev instead of a version number, so the shipped Trivy release could not be determined from the scanner itself. The binary is now built with its release version.
  • report-updater downloads the BDU dictionary when the registry secret stores the credentials as a username/password pair, under a key that carries a scheme or a repository path, or as a token. Such credentials were not recognized: the component accessed the registry anonymously, received 401 Unauthorized and restarted in a loop, and the module did not become ready. A password containing a colon was truncated for the same reason.
  • report-updater takes the credentials of the registry that hosts the BDU image from the system-registry secret. It read deckhouse-registry, which holds the credentials of the module source registry, so the dictionary was not downloaded when the module and the platform are delivered from different registries or under different accounts.
  • registry-scanner finds the credentials of a RegistryScanTarget when the key in the secret referenced by registrySecretRef carries a scheme or a repository path, and when the Docker Hub credentials are stored under the legacy key. The key had to match the registry field exactly, otherwise the target was scanned without credentials. An entry that holds a token alone is no longer rewritten either: the configuration passed to the scan received an auth field composed of an empty user name and password, which the scanner rejects as malformed.
  • registry-scanner stores the report of an image in which no vulnerabilities are found. The list of vulnerabilities is a required field of RegistryImageVulnerabilityReport and an empty list was passed as null, so the report was rejected and the tag was rescanned on every cycle without a report being stored.
  • registry-scanner scans every repository of a registry when spec.repositories of the RegistryScanTarget is empty. The reference has always described an empty list this way, but no repository was ever looked up: such a target finished its cycle in a fraction of a second and reported success without scanning anything. The repositories now come from the catalog API of the registry, and a registry that does not serve the catalog, or serves an empty one, puts the target into Ready=False instead of reporting a successful cycle.
  • registry-scanner reports the repositories it could not read. A repository that does not exist, a certificate the scanner refuses and a credential the registry rejects were only written to the log, while the target reported Ready=True with no reports behind it. Such a cycle now sets Ready=False, names the repositories with the error of each and counts the images it could not scan.
  • registry-scanner lists the tags of a registry with the credentials the module itself runs with, when the RegistryScanTarget names no secret of its own. The scan already used them, so a registry available to the module was scanned but listed anonymously, and its private repositories answered 401 Unauthorized while its public ones were scanned.
  • registry-scanner no longer reconciles a broken target in a loop. A target whose cycle failed reconciled about ten times a second for as long as it stayed broken, with two writes to the API server on every pass, because the controller answered its own status writes. A cycle that fails before it scans anything now retries in five minutes, and one that scanned part of its images in an hour.
  • registry-scanner starts a scan cycle as soon as the spec of a RegistryScanTarget changes. An added repository or a corrected repository path waited for the rescan period to elapse, up to a week, unless the last scan time annotation was removed by hand.
  • registry-scanner answers the probes while the Java index database is being downloaded. The download ran before the probe server started, so on a slow registry the kubelet killed the container on the liveness probe and the download began again from scratch, leaving the component in CrashLoopBackOff. A failed download is now retried every 30 seconds, and until it succeeds the component reports itself as not ready and postpones the scans.
  • The cluster SBOM (k8s-cluster) gets its ClusterVulnerabilityReport again. The operator handed the scan job an empty SBOM read from the metadata-only projection of security-storage, and a scan submitted while trivy-server was still loading its database after a module update failed and was not repeated. The operator now reads the full SBOM, and the scan waits up to 90 seconds for trivy-server.
  • The k8s-cluster report describes the current Kubernetes version. The SBOM of a previous cluster version stayed after an upgrade and shared the sbom-k8s-cluster secret with the current one, so the report could be built for either of them. The SBOM of another version is now deleted together with its report.
  • A secret that hands an SBOM to a scan job no longer blocks the scan. A secret left without an owner, for example after an operator restart, was taken for a scan in progress, and the object was never scanned again. The secret name now carries the hash of the scanned object, a leftover secret is replaced, and the module deletes sbom-* secrets that stay without an owner for more than 10 minutes.
  • A scan job that fails, for example because its pod is evicted, is repeated up to three times for the same pod spec. The workload stayed without a report until its spec changed.
  • Compliance reports (ClusterComplianceReport) count failed controls again. The operator built them from the metadata-only projection of the assessment reports without their checks, so every control was reported as passed.
  • The KSV-0110 check (default_namespace_should_not_be_used) is loaded again. The operator skipped the Rego library it depends on and logged rego_type_error at startup.
  • The metrics trivy_image_vulnerabilities and trivy_image_exposedsecrets carry the image labels again, and trivy_vulnerability_id has series again. The operator read these reports from the metadata-only projection of security-storage, which holds no image or vulnerability data.
  • registry-scanner stores the report of an image whose report exceeds the 1 MiB object limit. The report is trimmed in stages: links, descriptions, CVSS vectors and then the vulnerabilities of the lowest severities; the summary counters stay complete, and the registry-scanner.deckhouse.io/trimmed annotation lists what was dropped.
  • vulnerabilityDatabaseMaxAge: 0s is rejected by the configuration schema. The value was accepted and made the trivy-db freshness alert hook fail on every run.
  • Configuration audit checks no longer fail to compile at random after an operator start. Concurrent reconciles corrupted the cached check bundle, and the scanner kept the failed compilation, so every ConfigAuditReport came out without checks and every ClusterComplianceReport without failed controls until the operator was restarted. The bundle is no longer shared for writing, and a failed compilation is retried.

Security updates

Security updates in this release:

  • Fixed CVEs in module images and dependencies.

Upgrade notes

Before upgrading, note the following:

  • A RegistryScanTarget with an empty spec.repositories starts scanning. Such a target scanned nothing before this release, and it now takes up to spec.maxRepositories repositories from the registry catalog, 100 by default, which adds their images to the load of the Trivy server. Set spec.maxRepositories on those targets before the upgrade if that load matters, or list the repositories explicitly.
  • Every RegistryImageVulnerabilityReport is recreated under a new name during the first cycle after the upgrade. The name of a report now carries a hash of the repository and the tag it describes, so that two images whose paths differ only in a character the old name dropped no longer share one report. The reports of the previous names are removed by the first cycle that reads every repository of their target and scans every image of it. Reports of images the cycle does not scan — a repository that left the target, one that is unreadable, or one beyond spec.maxRepositories — are removed by the first cycle that reads every repository of their target and scans every image of it, and until then the Ready condition of that target says so.
  • A RegistryScanTarget whose repositories cannot all be read turns Ready=False with the ScanFailed reason. Such a target reported Ready=True before, so a check that expects every target to be ready may start failing on a target that was already scanning only part of its repositories.

Docs

Documentation changes:

  • Fixed the tagFilter example in the RegistryScanTarget reference. It was written as a double-quoted YAML string, where the regex backslash escapes are invalid, so copying the example into a manifest produced a parse error.
  • The severities parameter now states its default in the ModuleConfig reference: with the parameter unset, vulnerability reports include all severity levels.
  • The description of the scanning scope now distinguishes image scanning, which is limited to labeled namespaces, from configuration scanning, which covers every namespace. It also states which namespaces complianceReports.skipSystemResources excludes by default, how long the reports of a namespace live after its label is removed, and why the operator log reports the AllNamespaces install mode in both cases.

v0.6.7

Release date: 2026-08-26

Reduced security-storage memory usage during normal operation through internal storage optimizations.

Highlights

Changes in this release:

  • security-storage uses less memory under load thanks to storage and caching optimizations.

Improvements

This release improves:

  • Lowered the operational memory footprint of security-storage.

v0.6.6

Release date: 2026-08-14

security-storage watch requests now support sendInitialEvents=true for correct initial sync.

Highlights

Changes in this release:

  • Watch requests to security-storage accept sendInitialEvents=true, so clients receive the initial object set before further events.

Fixes

This release fixes:

  • Implemented missing sendInitialEvents=true support for security-storage watch requests.

v0.6.5

Release date: 2026-08-10

Negotiated YAML/JSON-only encoding for trivy.deckhouse.io resources and allowed a separate StorageClass for the security-storage PVC.

Highlights

Changes in this release:

  • API negotiation for trivy.deckhouse.io resources is limited to YAML and JSON.
  • The security-storage PVC StorageClass can be configured separately from the rest of the module.

v0.6.4

Release date: 2026-08-04

Updated mount points for node filesystem scanning pods for compatibility with the CSE edition of Deckhouse Kubernetes Platform (DKP).

Highlights

Changes in this release:

  • Mount points for node filesystem scanning pods are updated for CSE compatibility.

v0.6.3

Release date: 2026-08-04

Enabled node root filesystem scanning in the CSE edition and adjusted the node-agent securityContext and mount points for CSE compatibility.

Highlights

Changes in this release:

  • Node root filesystem scanning works in CSE clusters.
  • The node-agent securityContext and mount points are aligned with CSE requirements so the agent starts and runs correctly.

v0.6.2

Release date: 2026-08-03

Added mount point declarations for scanning containers for compatibility with the CSE edition of Deckhouse Kubernetes Platform (DKP).

Highlights

Changes in this release:

  • Declared mount points for scanning containers so node and workload scanning works correctly in CSE clusters.

v0.6.1

Release date: 2026-08-03

Added mount point declarations for the security-storage component and scanning containers for compatibility with the CSE edition of Deckhouse Kubernetes Platform (DKP).

Highlights

Changes in this release:

  • Declared mount points for security-storage and scanning containers so the module works correctly in CSE clusters.