Kyverno Integration with DefectDojo
Kyverno Integration with DefectDojo
Kyverno is an open source, Kubernetes-native policy engine and a graduated project of the Cloud Native Computing Foundation (CNCF). Policies are written as Kubernetes resources, and Kyverno uses them to validate, mutate, and generate configuration at admission time and in background scans of existing resources. Kyverno records the outcome of each evaluation in policy report objects, using either the wgpolicyk8s.io PolicyReport format or the newer openreports.io Report format, and its CLI can produce the same reports for files outside a cluster.
Kyverno Integration with DefectDojo
Kyverno enforces our policies at the cluster's front door, but plenty of resources predate a policy or run in Audit mode, and those violations sit quietly in report objects. Exporting the reports and importing them into DefectDojo turns each failing resource into a Finding with an owner and an SLA. Severity comes from the policy author's own annotation when it is set, so the policy team's judgment carries through, and reimporting after each cleanup shows which namespaces are actually coming into compliance.
Why Kyverno Matters
Policy as code only helps if someone acts on the violations, and Kyverno produces two kinds that are easy to miss.
- Policies in Audit mode admit violating resources and only record a warning, which nobody sees unless they read the reports.
- Background scans evaluate resources that were created before a policy existed, so long-lived workloads get checked too.
- Policies carry metadata, including a severity annotation and a category, that gives each result context.
- Report objects live inside the cluster, so without exporting them there's no history or cross-cluster view.
Advantages of This Integration
What DefectDojo adds to Kyverno policy reports:
- Only violations are imported. Results of
fail,warn, anderrorbecome Findings.passandskipresults are left out. - The policy author's severity. When a policy sets the
policies.kyverno.io/severityannotation, Kyverno copies it onto each result and DefectDojo uses it directly (critical, high, medium, low, info). - A sensible fallback. Without the annotation, severity is derived from the result:
failis Medium,warnis Low (Audit mode admitted it), anderroris High (the rule couldn't be evaluated). The description says which route was taken. - One Finding per resource. When a result names several resources, each becomes its own Finding, because each is a separate fix.
- Deduplication across exports. The hash uses the policy and rule (as vulnerability ID) and the resource (as component), so daily exports update existing Findings.
How This Integration Works
DefectDojo imports Kyverno reports with the Kyverno Scan scan type. It accepts PolicyReport and ClusterPolicyReport (wgpolicyk8s.io), Report and ClusterReport (openreports.io), and a Kubernetes List wrapping several reports.
1. Produce a report. Export the reports a cluster has already produced:
kubectl get policyreport -A -o json > kyverno.json
Or evaluate policies against files with the Kyverno CLI:
kyverno apply policy.yaml --resource resource.yaml --policy-report --output-format json > kyverno.json
2. Import it. In the UI, open the Engagement, choose Import Scan Results, select Kyverno Scan, and upload the file. With the API, in Community Edition or DefectDojo Pro:
curl "https://YOUR_INSTANCE/api/v2/import-scan/"
-H "Authorization: Token $DD_API_TOKEN"
-F "scan_type=Kyverno Scan"
-F "file=@kyverno.json"
-F "product_name=prod-cluster"
-F "engagement_name=Policy Compliance"
-F "auto_create_context=true"
DefectDojo Pro users can use Universal Importer:
universal-importer import
--defectdojo-url "https://YOUR_INSTANCE.cloud.defectdojo.com/"
--scan-type "Kyverno Scan"
--report-path "./kyverno.json"
--product-name "prod-cluster"
--engagement-name "Policy Compliance"
--auto-create-context
3. Reimport on a schedule. Send each new export to /api/v2/reimport-scan/ against the same Test so resolved violations are mitigated.
DefectDojo also has a generic OpenReports scan type. For Kyverno output, use Kyverno Scan: it accepts the cluster-scoped report kinds as well as namespaced ones, filters passes and skips, and takes severity from the policy.
Data Granularity: What Gets Imported
| DefectDojo Field | Source in Kyverno Report | Notes |
|---|---|---|
| Title | policy, rule, resource |
policy/rule: kind/namespace/name |
| Severity | severity, else result |
Declared severity maps directly; otherwise fail Medium, warn Low, error High |
| Description | message, policy, rule, result, category, severity source, resource, API version, source, scored, properties |
Notes whether severity was declared or derived |
| Component Name | resources[] |
kind/namespace/name, skipping absent parts |
| Vulnerability ID from Tool | policy and rule |
policy/rule |
| Finding type | Static | All Kyverno findings are static |
| Deduplication | Hashcode | Vulnerability ID from tool, component name |
The parser doesn't set a mitigation field. Kyverno's result message usually states what the policy requires, and it is the first line of the description.
Use Cases
For Audit mode rollouts: A team introduces a new policy in Audit mode so nothing breaks. Exporting reports into DefectDojo each day gives them a list of violating workloads, each assigned to its owner, and they switch to Enforce once the list is empty.
For existing workloads: Background scans catch resources created before a policy existed. Importing those results shows the security team how much legacy configuration still violates current standards, per namespace.
In a CI/CD pipeline: Pipelines run kyverno apply against rendered manifests and reimport into the service's Test, so a policy violation is caught and tracked before the change reaches a cluster.
For multi-cluster compliance reporting: Each cluster maps to an Asset. Security leads report on open policy violations by cluster and category without logging into each cluster to read report objects.
Operational Tips
- Set the
policies.kyverno.io/severityannotation on every policy you care about. It is the only way to get Critical in DefectDojo, and it keeps SLA rules tied to the policy team's intent. - Don't ignore
errorresults. They mean Kyverno couldn't evaluate the rule, so the resource is unverified, which is why they import as High when no severity is declared. - Use one Test per cluster. Component names include the namespace, but namespaces can repeat between clusters.
- Export with
-Ato include all namespaces, and export ClusterPolicyReports or ClusterReports too if you use cluster-scoped policies. - Use
minimum_severityto keep Low results from Audit mode policies out until you are ready to work them. - Record approved exceptions as risk acceptances, or use Kyverno's own exception mechanism so the resource stops failing at the source.