All integrations

Popeye Integration with DefectDojo

Popeye Integration with DefectDojo

Popeye is an open source utility that scans a live Kubernetes cluster and reports potential problems with deployed resources and their configuration. It is developed in the derailed/popeye GitHub repository by Fernand Galiana, also the author of K9s. Popeye checks resources such as pods, deployments, services, RBAC roles and bindings, config maps, and secrets for issues like missing resource limits, unused objects, and risky settings, then grades the cluster. Reports can be written in several formats, including JSON, which DefectDojo imports.

Popeye Integration with DefectDojo

We run Popeye against our clusters because it catches the configuration drift that never shows up in an image scan: a pod with no resource limits, a service pointing at nothing, a role nobody uses. DefectDojo turns that report into tracked work. Each warning or error becomes a Finding on the Asset that owns the cluster, labeled with the sanitizer and the specific resource, so the platform team can assign it and see it close on the next scan.

Why Popeye Matters

Kubernetes clusters accumulate problems quietly. A manifest that was fine when it was applied can become a liability as workloads change around it.

  • Popeye looks at what is actually deployed, not what is sitting in a repository, so it reports the cluster's real state.
  • Its checks cover hygiene and security together, such as missing probes and limits alongside permissive RBAC.
  • Every issue carries a stable Popeye code (for example POP-106), which makes it possible to recognize the same problem across scans.
  • A Popeye score tells you the cluster got worse. It does not tell you which team owns the fix or how long the problem has been open.

Advantages of This Integration

What we gained by sending Popeye results through DefectDojo:

  • Per-resource findings. Each issue names the sanitizer, the resource, and the Popeye message, so a finding points at one namespace and object instead of a cluster-wide score.
  • Deduplication across scans. Popeye findings are hashed on title and description. Running Popeye daily against the same cluster does not create a fresh copy of every warning.
  • Lifecycle on reimport. Reimporting the next report into the same Test mitigates issues that were fixed, adds new ones, and reactivates any that come back after a redeploy.
  • Ownership. Findings can be assigned to the team that owns the namespace, commented on, risk-accepted, or pushed to Jira.
  • Context next to other scanners. Cluster configuration issues sit beside container image CVEs and IaC findings for the same Asset, which gives a fuller picture of platform risk.

How This Integration Works

DefectDojo imports Popeye results with the Popeye Scan scan type. The parser accepts both the older report layout (a sanitizers list) and the newer one (a sections list keyed by linter).

1. Produce a JSON report. Point Popeye at the cluster context you want to check, choose JSON output, and save the report:

POPEYE_REPORT_DIR=$(pwd) popeye --context prod-cluster --out json --save --output-file popeye.json

You can also redirect standard output to a file instead of using --save. The parser only needs the JSON document.

2. Import it. In the UI, open the Engagement, choose Import Scan Results, select Popeye Scan, and upload the file. For automation, use 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=Popeye Scan" \
  -F "file=@popeye.json" \
  -F "product_name=prod-cluster" \
  -F "engagement_name=Cluster Hygiene" \
  -F "auto_create_context=true"

DefectDojo Pro users can run the same import with Universal Importer:

universal-importer import \
  --defectdojo-url "https://YOUR_INSTANCE.cloud.defectdojo.com/" \
  --scan-type "Popeye Scan" \
  --report-path "./popeye.json" \
  --product-name "prod-cluster" \
  --engagement-name "Cluster Hygiene" \
  --auto-create-context

3. Reimport on a schedule. For a cluster you scan repeatedly, send later reports to /api/v2/reimport-scan/ against the same Test so fixed issues are closed and the history stays together.

Data Granularity: What Gets Imported

Popeye reports four levels: 0 (OK), 1 (Info), 2 (Warning), and 3 (Error). The parser skips level 0 entries and creates a finding for everything else.

DefectDojo Field Source in Popeye Report Notes
Title Sanitizer, resource, message For example pods ns/pod-name [POP-106] No resources requests/limits defined
Severity Issue level 1 becomes Info, 2 (Warning) becomes Low, 3 (Error) becomes High
Description Sanitizer, resource, group, level, message Labeled fields so the resource is easy to find
Vulnerability ID from tool Popeye code in the message The POP-nnn code, for example POP-106
Finding type Dynamic Popeye inspects a running cluster
Deduplication Hashcode Title, description

Within a single report, identical title and description pairs are collapsed into one finding.

There is no Medium or Critical in this mapping. Every Popeye error lands as High and every warning as Low, so SLA policy for Popeye findings effectively comes down to those two levels.

Use Cases

For scheduled cluster hygiene: A CronJob or pipeline runs Popeye nightly against each cluster and reimports the report. The platform team works the High findings from DefectDojo and watches the count fall instead of rereading the same report every morning.

Before and after an upgrade: Teams upgrading Kubernetes or a major chart import a Popeye report before and after. New findings in the second import are the changes the upgrade introduced, and mitigated ones are what it fixed.

Across many clusters: An organization with separate clusters for each environment or region imports each into its own Asset. Security leads get one view of configuration problems by cluster and can compare staging with production.

For namespace owners: Because titles include the resource path, findings can be filtered by namespace and assigned to the team that owns it, which keeps cluster-wide reports from landing on one person's desk.

Operational Tips

  • Decide what to do with Info. Level 1 issues import as Info and can be numerous. Set minimum_severity=Low on import if you only want warnings and errors.
  • Remember that warnings become Low. If your SLA for Low is long, important Popeye warnings (such as missing limits on critical workloads) may need manual severity changes.
  • Keep pod names out of your expectations. Titles include the resource name, so a pod recreated with a new suffix produces a new title and a new finding. Deployment-level and RBAC findings are more stable.
  • Use one Test per cluster and reimport into it, so findings close cleanly when the underlying resource is fixed or removed.
  • Use Popeye's own configuration file (a spinach.yaml) to exclude namespaces or checks you have consciously accepted, rather than risk-accepting the same finding again after every redeploy.
  • Tag imports with the cluster name and environment (for example tags=prod,us-east) for filtering in metrics.
  • Run Popeye with a service account that can read every namespace you care about. Resources it cannot see are simply absent from the report, and on reimport their findings would be mitigated as if they were fixed.