The module lifecycle stage: General Availability
The module has requirements for installation
Viewing resources that failed CIS compliance checks
d8 k get clustercompliancereports.aquasecurity.github.io cis -ojson |
jq '.status.detailReport.results | map(select(.checks | map(.success) | all | not))'Viewing resources that have not passed a specific CIS compliance check
By id:
check_id="5.7.3"
d8 k get clustercompliancereports.aquasecurity.github.io cis -ojson |
jq --arg check_id "$check_id" '.status.detailReport.results | map(select(.id == $check_id))'By description:
check_desc="Apply Security Context to Your Pods and Containers"
d8 k get clustercompliancereports.aquasecurity.github.io cis -ojson |
jq --arg check_desc "$check_desc" '.status.detailReport.results | map(select(.description == $check_desc))'Manual rescan of a resource
The module rescans resources every 24 hours according to the following algorithm:
- A VulnerabilityReport object is created in the namespace with each scanned resource.
- This object contains the annotation
trivy-operator.aquasecurity.github.io/report-ttl, which specifies the report lifetime (the default is24h). - After the lifetime expires, the object is deleted, which triggers a rescan of the resource.
You can force a resource rescan in one of the following ways:
- Overwrite the annotation
trivy-operator.aquasecurity.github.io/report-ttl, specifying a short report lifetime. - Delete the VulnerabilityReport object from the namespace where the scanned resource is located.
Example command for overwriting the annotation trivy-operator.aquasecurity.github.io/report-ttl:
d8 k annotate VulnerabilityReport -n <namespace> <reportName> trivy-operator.aquasecurity.github.io/report-ttl=1h --overwriteWho has access to scan results
Access to scan results (including the ability to view resources with results) is granted to users with the following access roles:
d8:manage:networking:vieweror higher;d8:manage:permission:module:operator-trivy:view.
These roles are from the experimental DKP role model.
- To grant access to reports within a specific namespace (VulnerabilityReport, ConfigAuditReport, etc.), use a RoleBinding with the use-role
d8:use:role:viewer(or higher) in that namespace. - To grant access to cluster-wide reports (ClusterComplianceReport, etc.), use a ClusterRoleBinding with
d8:manage:permission:module:operator-trivy:view(or the broaderd8:manage:security:vieweror higher).
In the current DKP role model (resources AuthorizationRule / ClusterAuthorizationRule), the following access levels are typically used:
- Namespace scope (AuthorizationRule in a specific namespace):
User,PrivilegedUser,Editor,Admin. - Cluster scope (ClusterAuthorizationRule for cluster-wide reports and/or system namespaces access):
ClusterEditor,ClusterAdmin,SuperAdmin.
You can also grant access directly via standard Kubernetes RBAC (Role/ClusterRole + RoleBinding/ClusterRoleBinding):
How to limit the list of resources scanned in a namespace
The current version does not support limiting the list of scanned resources within a namespace.
The operator scans all workloads in a namespace labeled with security-scanning.deckhouse.io/enabled="".
How to view the scan report for your application
To view the scan results of your application, use the Grafana dashboard Security / Trivy Image Vulnerability Overview.
You can filter the results by the desired namespace and resource.
You can also directly view the resources that contain scan results created for each scanned object.
Details about naming structure and resource location are available in the documentation.
How do CIS checks in DKP relate to kube-bench?
What is kube-bench?
kube-bench is a standalone utility from Aqua Security that checks Kubernetes cluster compliance with CIS Benchmark requirements. It runs shell commands on nodes to analyze configuration.
If you want to run kube-bench checks in a DKP cluster yourself, use the instructions in the deckhouse module FAQ.
How does DKP implement CIS checks?
DKP uses Trivy Operator — an integrated solution that:
- Runs as a Kubernetes operator inside the cluster
- Automatically scans all resources
- Stores results in Custom Resources (ClusterComplianceReport)
- Exports metrics to Prometheus
Identifier mapping
| CIS Section | Description | kube-bench | DKP |
|---|---|---|---|
| 1.x | API Server | [PASS/FAIL] 1.2.1 ... |
AVD-KCV-* |
| 2.x | etcd | [PASS/FAIL] 2.1 ... |
AVD-KCV-* |
| 3.x | Control Plane | Manual | Manual |
| 4.x | Worker Nodes | [PASS/FAIL] 4.2.1 ... |
AVD-KCV-* |
| 5.x | Policies | Partial | AVD-KSV-* (full coverage) |
How to compare results?
Use CIS Control ID (e.g., 1.2.1, 5.2.2) — it’s the same in both tools.
Example: If kube-bench shows [FAIL] 1.2.16 Ensure that the admission control plugin..., find it in DKP:
d8 k get clustercompliancereports.aquasecurity.github.io cis -ojson | \
jq '.status.detailReport.results | map(select(.id == "1.2.16"))'You can read more in the CIS checks documentation section.
Why do some CIS checks always show PASS for system components?
Some checks are disabled for system namespaces (kube-system and d8-*) because system components require elevated privileges.
You can read the full list of disabled checks in the CIS checks documentation section.
Why are checks 5.1.2 and 5.1.3 not shown in the dashboard?
Checks 5.1.2 (Minimize access to secrets) and 5.1.3 (Minimize wildcard use in Roles and ClusterRoles) are excluded from metrics and the dashboard due to a high number of false positives for system components.
The checks are still performed, and results are available in the ClusterComplianceReport resource:
d8 k get clustercompliancereports.aquasecurity.github.io cis -ojson | \
jq '.status.detailReport.results | map(select(.id == "5.1.2" or .id == "5.1.3"))'What CIS Benchmark version is used?
The module implements checks according to CIS Kubernetes Benchmark v1.12 specification.
Component versions (external operator-trivy module, DKP 1.75+):
| Component | Version |
|---|---|
| Trivy | v0.69.3 |
| Trivy Operator | v0.30.1 |
| k8s-node-collector | v0.3.1 |
DKP 1.74 and earlier used a built-in module with Trivy v0.55.2.
How often are CIS checks performed?
CIS Benchmark checks run:
- every 6 hours (cron:
0 */6 * * *); - on operator startup.
How to expand the module’s disk (PVC)
The module stores data on several PVCs in the d8-operator-trivy namespace:
security-storage— runtime profile data (ApplicationProfile/NetworkNeighborhood, etc.);data-trivy-server-0— the Trivy vulnerability database cache;data-trivy-provider-0— thetrivy-providercache.
The size is set in the module templates and is not configurable. If a disk runs low, a PVC can be expanded manually, provided the StorageClass in use supports volume expansion.
-
Make sure the StorageClass allows expansion (
allowVolumeExpansion: true):kubectl get storageclass <storageClass> -o jsonpath='{.allowVolumeExpansion}' -
Increase the storage request on the PVC (expansion only — a PVC cannot be shrunk):
kubectl -n d8-operator-trivy patch pvc security-storage --type merge \ -p '{"spec":{"resources":{"requests":{"storage":"10Gi"}}}}' -
Depending on the CSI driver, the volume expands online or after the consuming pod is restarted.
For PVCs created by StatefulSets (data-trivy-server-0, data-trivy-provider-0) the procedure is the same — patch the existing PVC. The volumeClaimTemplates field is immutable, so leave the template alone; the module never shrinks an already-expanded PVC back.
security-storage is an aggregated API server (spdx.softwarecomposition.kubescape.io). Restarting it briefly makes the runtime-profile API unavailable, so only restart the pod when necessary.
Disk usage is tracked automatically: the d8-operator-trivy namespace is labeled extended-monitoring.deckhouse.io/enabled, so the extended-monitoring module emits the standard PVC space-running-out alerts (such as KubernetesPersistentVolumeClaimBytesAvailable). No extra alert configuration is needed.