The module lifecycle stage: General Availability
The module has requirements for installation
In a DKP cluster, vulnerability scanning is made with Trivy Operator. It automatically generates Software Bill Of Materials (SBOM) for all workloads and runs the scanner for specified objects without any manual actions required.
Supported object types for scanning
The following object types are supported:
- Container images stored in a registry.
- Node host filesystems in the cluster.
Analysis architecture
Regardless of object type, the scanning is made in three stages:
| Stage | Description |
|---|---|
| 1. Scanning | The scanner traverses the target object, runs analyzers to extract installed packages, dependency manifests, and configuration files, and builds an SBOM (Software Bill Of Materials) |
| 2. Filtering | Collected data is matched against vulnerability databases and policies. Filters apply by severity, fix status, and dependency type |
| 3. Reporting | Results are formatted as a VulnerabilityReport custom resource and published in the cluster in the namespace that contains the target object |
Vulnerability scanning mechanism
The vulnerability scanner is Trivy’s core component: it detects known CVEs using vulnerability databases. The operator-trivy module scans OS packages and components (binaries, libraries) and application dependencies (libraries, modules, and other deps).
The operator automatically triggers scans when new or changed workloads appear in namespaces where scanning is enabled.
Operating system packages
The scanner detects the target OS distribution and applies data from the CVE databases officially provided by Deckhouse. This improves detection accuracy and reduces false positives.
Data sources used to build the CVE databases are listed below:
- FSTEC of Russia threat database (BDU)
- AlmaLinux Errata
- Alpine SecDB
- ALTRepo Errata OVAL
- Amazon Linux Security Advisories
- Arch Linux Security Tracker
- Debian Security Tracker
- GitHub Security Advisory Database
- National Vulnerability Database (NVD)
- Oracle OVAL
- Photon Security Advisory
- Red Hat OVAL
- RED SOFT OVAL
- Rocky Linux UpdateInfo
- SUSE Security CVRF
- Ubuntu CVE Tracker
- Wolfi SecDB
Application dependencies
The scanner discovers and analyzes package manager manifests and lockfiles across more than twenty ecosystems. Per ecosystem it uses specialized vulnerability databases (primarily based on GitLab Advisory Database and GitHub Advisory Database).
| Language / ecosystem | Files analyzed |
|---|---|
| Node.js (npm, Yarn) | package.json, package-lock.json, yarn.lock |
| Python (pip, Poetry, Pipenv) | requirements.txt, Pipfile.lock, poetry.lock |
| Java (Maven, Gradle) | pom.xml, build.gradle, *.jar, *.war |
| Go | go.mod, go.sum, Go binaries |
| .NET (NuGet) | *.csproj, packages.lock.json |
| Ruby (Bundler) | Gemfile.lock |
| PHP (Composer) | composer.lock |
| Rust (Cargo) | Cargo.lock |
| Swift (SwiftPM) | Package.resolved |
| Dart (pub) | pubspec.lock |
Scan results and the VulnerabilityReport resource
Vulnerability scan results are stored in the cluster as the VulnerabilityReport custom resource in group aquasecurity.github.io. Each report is created in the workload namespace, named <kind>-<workload-name>-<container-name>, and lists discovered CVEs with severity, fix status, affected packages, and references.
The report is tied to the parent resource via ownerReferences: when the image changes or the workload is removed, the stale VulnerabilityReport is garbage-collected and recreated if needed. This implements periodic rescanning of workloads.
SBOM generation and processing
Generated SBOM is stored in the cluster as the SbomReport CRD in group aquasecurity.github.io. Each report is created in the workload namespace and includes:
- container image metadata (repository, tag, digest);
- component inventory in CycloneDX format: OS packages and app dependencies with PURLs, licenses, and supplier information;
- a dependency graph between components;
- summaries of component and dependency counts.
The operator watches cluster resources. When a workload is created or updated, a scan job runs and produces both SbomReport and VulnerabilityReport. Both follow the <kind>-<workload-name>-<container-name> naming scheme and use ownerReferences — when the workload is deleted, reports are removed by Kubernetes garbage collection.
SbomReport and VulnerabilityReport complement each other: VulnerabilityReport lists CVEs, while SbomReport captures the full software inventory.
Registry scanning
In addition to scanning images running in the cluster, the module supports periodic scanning of image repositories stored in external container registries.
Enable the feature in ModuleConfig/operator-trivy:
spec:
settings:
registryScanning:
enabled: trueSetting up registry repositories scanning
A scan target is declared as a cluster-scoped RegistryScanTarget resource:
apiVersion: deckhouse.io/v1alpha1
kind: RegistryScanTarget
metadata:
name: preprod-myapp
spec:
registry: preprod.registry.example.com
repositories:
- myapp/backend
- myapp/frontend
rescanPeriod: 1d
tagFilter: "^v[0-9]+" # Optional: Scan only tags matching the regular expression.
maxTags: 50 # Optional: Scan at most 50 tags per repo (default 100).
registrySecretRef: # Optional: Credentials for a private registry.
name: image-pull-credentials-secret
namespace: myapp| Field | Required | Description |
|---|---|---|
registry |
Yes | Registry hostname (for example, registry.example.com). |
repositories |
Yes | List of repository path to scan. |
rescanPeriod |
Yes | Rescan interval for each image tag. Allowed values: 12h, 1d, 2d, 7d. |
tagFilter |
No | Regular expression. Only tags whose names match are scanned. |
maxTags |
No | Maximum number of tags to scan per repository after filtering. Default: 100. The first N tags in lexicographic order are selected. |
registrySecretRef |
No | Reference to a kubernetes.io/dockerconfigjson Secret containing registry credentials. |
insecure |
No | Allow plain HTTP or disables TLS verification for this registry. |
If the registry requires a CA certificate that is not in the system trust store, add it via additionalRegistryCA.
Scan results
Results are stored as cluster-scoped RegistryImageVulnerabilityReport resources, one resource per scanned image tag. Each report is owned by its RegistryScanTarget. When a RegistryScanTarget is deleted, all its reports are garbage-collected automatically.
# List all registry scan reports.
d8 k get registryimagevulnerabilityreport
# Inspect a specific report.
d8 k describe registryimagevulnerabilityreport <name>The report is re-created after the interval specified by rescanPeriod elapses. To force an immediate rescan, remove the registry-scanner.deckhouse.io/last-scan-time annotation from the RegistryScanTarget object.
The controller will start a new scan cycle immediately, without waiting for the next scheduled run.
Checking the scan state
The RegistryScanTarget status shows the time of the last scan cycle and its result:
d8 k get registryscantarget
d8 k describe registryscantarget my-registryThe Ready condition is True after a successful cycle and False while a scan is in progress or if it failed.
To distinguish between a running and failed scan, look at the reason field.
Blocking vulnerable containers
This feature requires the admission-policy-engine module (enabled by default in the module bundles Default and Managed).
The module enforces policy on running containers that use vulnerable images at Kubernetes admission time. It combines OPA Gatekeeper (the admission-policy-engine module) and Trivy: Trivy acts as a data provider for Gatekeeper with up-to-date scan results, and a Rego policy admits or denies the resource based on that data.
The constraint applies when Pod, Deployment, StatefulSet, and DaemonSet resources are created or updated in namespaces labeled security.deckhouse.io/trivy-provider: "".
The policy is evaluated only at admission (create/update). Gatekeeper audit mode does not evaluate this constraint.
Configuration
Blocking is controlled by the denyVulnerableImages module setting:
| Parameter | Default | Description |
|---|---|---|
enabled |
false |
Enable blocking of vulnerable images in labeled namespaces. |
allowedSeverityLevels |
— | Images that contain vulnerabilities only at the listed severities are not blocked. Allowed values: UNKNOWN, LOW, MEDIUM, HIGH, CRITICAL. |
registrySecrets |
[] |
List of additional kubernetes.io/dockerconfigjson Secrets to use when pulling images for admission-time scanning. Secret containing credentials for the DKP registry is always included automatically. Add entries here for workloads that pull images from private registries not covered by that secret. |
Configuration example
spec:
settings:
denyVulnerableImages:
enabled: true
allowedSeverityLevels:
- UNKNOWN
- LOW
- MEDIUM
registrySecrets:
- name: my-private-registry-pull-secret
namespace: my-appIn this example, images with HIGH or CRITICAL vulnerabilities are blocked. Images with only UNKNOWN, LOW, or MEDIUM findings are allowed. The my-private-registry-pull-secret Secret is used so that trivy-provider can pull images from that registry during admission checks.
registrySecrets only affects the credentials used during the admission-time check. It has no effect on scheduled workload scan jobs or registry scanning. The Secret must exist in the cluster before denyVulnerableImages is enabled.
Suppressing vulnerabilities with VEX attestations
VEX (Vulnerability Exploitability eXchange) is a machine-readable statement that declares whether a known CVE is actually exploitable in a specific product version. A VEX statement can say, for example, that a vulnerability exists in a library the image ships but is not reachable because the affected code path is never called.
When useVEXFromOCI is enabled, Trivy fetches VEX attestations that are attached to scanned images in the OCI registry (as OCI referrers) and uses them to filter CVE findings. A vulnerability is omitted from the resulting VulnerabilityReport or RegistryImageVulnerabilityReport if a VEX statement marks it as not_affected or fixed for that image.
This applies to both workload scanning (images running in the cluster) and registry scanning (RegistryScanTarget).
VEX attestations are authored and published by the image vendor — usually the team that maintains the image. The image must have a VEX attestation attached to it in the registry for suppression to take effect. If no attestation is present, scanning proceeds as normal and nothing gets filtered.
Requirements
- The registry must support the OCI Referrers API (OCI Distribution Spec v1.1+). Most modern registries (Harbor, Quay, GHCR, ECR) support it.
- VEX attestations must be stored as OCI referrers of the image.
Enabling
Add the following option to the ModuleConfig/operator-trivy
spec:
settings:
useVEXFromOCI: trueCompliance reports
The module deploys ClusterComplianceReport resources for selected compliance frameworks. Each report is regenerated every 6 hours and maps controls of a framework to the underlying configuration and workload checks performed by Trivy.
The set of deployed reports is controlled by the complianceReports.enabled parameter.
| Framework | Default | Description |
|---|---|---|
CIS |
enabled | CIS Kubernetes Benchmark v1.12. |
PCI-DSS |
enabled | PCI DSS v4.0 — key controls for protecting cardholder data. |
NSA |
enabled | NSA-CISA Kubernetes Hardening Guidance v1.0. |
GDPR |
disabled | GDPR — security-relevant articles (Art. 5, 25, 32). |
HIPAA |
disabled | HIPAA Security Rule — key technical safeguards (§164.308 and §164.312). |
FSTEC-21 |
enabled | Order of FSTEC of Russia No. 21 — personal data protection in personal data information systems. |
FZ-187 |
enabled | Order of FSTEC of Russia No. 239 — security requirements for significant CII objects (Federal Law 187-FZ). |
Configuration example
complianceReports:
enabled:
- CIS
- NSA
- FSTEC-21
- FZ-187In this example only four reports are deployed. To inspect a report, use:
d8 k get clustercompliancereports
d8 k describe clustercompliancereport fstec-21What compliance reports cover
By default compliance reports focus on your workloads — what the cluster owner can actually fix. The module automatically excludes from compliance:
- resources owned by Deckhouse and its modules;
- Kubernetes system components (built-in RBAC, control plane defaults, etc.).
The control plane itself is still checked against the relevant infrastructure controls (for example, CIS Kubernetes Benchmark section 1.x for kube-apiserver, etcd, kube-scheduler settings) — only generic workload-level findings about platform pods are filtered out.
Vulnerability scanning is independent of these filters and keeps reporting CVEs and secrets for every scanned image, including platform ones.
To exclude an additional namespace from compliance — for example, an experimental or short-lived environment — label the namespace:
d8 k label namespace my-namespace security.deckhouse.io/skip-compliance=trueWorking with private and insecure registries
By default the module expects all container registries to serve trusted TLS certificates. For environments that use self-signed certificates, plain HTTP, or that disable TLS verification, the following parameters are available.
Custom CA certificates (additionalRegistryCA)
Use additionalRegistryCA to specify root certificates for private registries.
Each entry has a name (human-readable label, purely informational) and ca (PEM-encoded certificate or chain). When specifying a chain, concatenate the certificates in PEM format with no extra blank lines between them.
spec:
settings:
additionalRegistryCA:
- name: corporate CA
ca: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
- name: CA with intermediate
ca: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----Insecure registries (insecureRegistries)
Use insecureRegistries to allow the scanner to connect to specific registries over plain HTTP or HTTPS with unverified certificates. Each entry is a registry hostname (optionally with port).
spec:
settings:
insecureRegistries:
- my.internal-registry.example.com
- legacy-registry.example.com:5000This setting applies to workload scanning (scan jobs), admission-time checking (denyVulnerableImages), and registry scanning (RegistryScanTarget).
insecureRegistries disables certificate verification only for the listed hosts. To disable TLS verification for the Trivy vulnerability database download (not registry scanning), use the separate insecureDbRegistry parameter.
Database management
The module automatically downloads, maintains, and caches the required databases during scans. Data is kept current through periodic automatic updates.
| Database container image | Purpose |
|---|---|
<deckhouse-repo>/security/trivy-db:2 |
Main vulnerability database — aggregates NVD, Red Hat, Alpine, Ubuntu, Debian, GitLab Advisory DB, GitHub Advisory DB, and other sources. |
<deckhouse-repo>/security/trivy-java-db:1 |
Specialized database for Java artifacts (JAR, WAR, EAR) with file-hash binding. |
<deckhouse-repo>/security/trivy-checks:0 |
Rego policies for IaC misconfiguration checks. |
<deckhouse-repo>/security/trivy-bdu:1 |
Mapping between third-party vulnerability IDs and FSTEC BDU identifiers. |
In air-gapped environments you can mirror database images and use them offline with the d8 CLI utility (via the d8 mirror command).