OpenReports Integration with DefectDojo
OpenReports Integration with DefectDojo
OpenReports is an open Kubernetes API for reporting the results of policy engines, scanners, and other cluster tooling in one shape. It defines two custom resources in the openreports.io API group, a namespaced Report and a cluster-scoped ClusterReport, each holding a list of results and a summary. The project lists producers such as Kyverno, Trivy Operator, Falco, Kubewarden, and Tracee, and it cites the earlier Kubernetes Policy Working Group policy report API as background. DefectDojo imports Report resources exported from a cluster as JSON.
OpenReports Integration with DefectDojo
We point DefectDojo at OpenReports because it gives us one export format for everything our cluster tools say about our workloads. Instead of writing a parser per in-cluster scanner, we pull every Report with kubectl and import the lot. Image CVEs and policy failures land on the Asset for the cluster with the namespace and workload attached, get deduplicated against the last export, and fall under the same SLAs as the rest of our findings.
Why OpenReports Matters
Kubernetes security tooling tends to report inside the cluster, as custom resources that disappear when a workload is deleted and that nobody outside the platform team ever sees.
- A common schema means one integration covers results from several producers that write OpenReports.
- Each report is scoped to a Kubernetes object, so results arrive tied to a specific Deployment, Pod, or other resource in a namespace.
- Results carry a status (pass, fail, warn, error, skip), a severity, a category, and for vulnerability scans the package, installed version, and fixed version.
- Getting results out of the cluster and into a tracked workflow is what turns in-cluster reports into remediation.
Advantages of This Integration
- Workload context on every finding. The parser builds the Service field as
namespace/kind/namefrom the report's scope, so each finding names the workload it belongs to. - Status handled sensibly. Results with
passorskipimport as inactive, whilefailandwarnimport as active and verified. Passing checks are kept as history without adding to the open count. - CVE-aware findings. When a result's policy is a CVE ID, the title becomes "CVE in package", the CVE is recorded as a vulnerability ID, and the fixed version populates both Mitigation and Fix Version.
- Deduplication across exports. DefectDojo hashes OpenReports findings on vulnerability IDs, component name, component version, and severity, so the same CVE in the same package version is matched from one export to the next.
- Filtering by producer. Each finding is tagged with its category, its source tool, and the scope kind, so a team can separate image scanner results from policy engine results inside one Test.
How This Integration Works
DefectDojo imports these exports with the OpenReports scan type.
1. Export the reports. With access to the cluster, write every namespaced Report to a file:
kubectl get reports -A -ojson > reports.json
The parser accepts a single Report object, an array of Reports, or a Kubernetes List object (which is what the command above produces). Items whose kind is not Report are skipped.
2. Import it. In the UI, open the Engagement, choose Import Scan Results, select OpenReports, and upload the file. To automate, use the API, which is available in Community Edition and DefectDojo Pro:
curl "https://YOUR_INSTANCE/api/v2/import-scan/"
-H "Authorization: Token $DD_API_TOKEN"
-F "scan_type=OpenReports"
-F "file=@reports.json"
-F "product_name=prod-cluster-eu"
-F "engagement_name=Cluster Reports"
-F "auto_create_context=true"
DefectDojo Pro users can run Universal Importer from a scheduled job:
universal-importer import
--defectdojo-url "https://YOUR_INSTANCE.cloud.defectdojo.com/"
--scan-type "OpenReports"
--report-path "./reports.json"
--product-name "prod-cluster-eu"
--engagement-name "Cluster Reports"
--auto-create-context
3. Reimport on a schedule. Run the export and a reimport to /api/v2/reimport-scan/ against the same Test (daily, for example) so fixed CVEs and remediated policy failures are mitigated in DefectDojo.
Data Granularity: What Gets Imported
| DefectDojo Field | Source in OpenReports | Notes |
|---|---|---|
| Title | policy, properties.pkgName, message |
"CVE in package" for CVE policies, otherwise "policy: message" |
| Severity | severity |
critical, high, medium, low, info; missing or unknown become Info |
| Description | Message, category, policy, result, source, package, installed version, URL | Labeled fields |
| Mitigation | properties.fixedVersion |
"Upgrade to version: X" when present |
| Fix Available / Fix Version | properties.fixedVersion |
|
| References | properties.primaryURL |
|
| Component Name / Version | pkgName, installedVersion |
|
| Service | Report namespace and scope kind and name |
Format namespace/kind/name |
| Vulnerability IDs | policy |
Only when the policy starts with CVE- |
| Vuln ID from Tool | policy |
|
| Tags | Category, source, scope kind | |
| Active / Verified | result |
pass and skip inactive; fail and warn verified |
| Finding type | Static | |
| Deduplication | Hashcode | Vulnerability IDs, component name, component version, severity |
Use Cases
Cluster-wide image CVEs: A platform team runs an image scanner that writes OpenReports. A nightly job exports Reports from each cluster and reimports them into one Asset per cluster, so the team sees which CVEs are new since yesterday and which Deployments carry them.
Policy compliance reporting: Policy engine results for configuration rules import with the policy name and message in the title. Failures stay active until the workload is fixed, and passing results remain as inactive history that shows the control was evaluated.
Hand-off to application teams: Because the Service field names the namespace and workload, findings can be filtered and assigned to the team that owns that namespace, or pushed to Jira with the workload in the ticket.
Multi-cluster view: An organization with clusters in several regions imports each into its own Asset under one Organization and reports Kubernetes findings across all of them from DefectDojo, instead of querying each cluster.
Operational Tips
- Export with
-Aso every namespace is included, and keep the same export command between runs so reimports compare like with like. - ClusterReport items are skipped by this parser, which reads kind
Reportonly. If a producer writes cluster-scoped results, those won't appear. - Deduplication doesn't include the title or the workload. Two non-CVE policy results with the same severity and no package can hash alike, so review duplicates on policy-heavy imports before trusting the counts.
- Severity comes from the producer. Policy authors set it for policy results, so agree on a severity convention before attaching SLAs.
- Use the source tag to split work: route image scanner findings to the teams that own images and policy findings to whoever owns the manifests.
- Pass
minimum_severityif Info and Low results from a chatty producer would bury actionable findings.