All integrations

Pluto Integration with DefectDojo

Pluto Integration with DefectDojo

Pluto is an open source command-line tool from Fairwinds that finds Kubernetes objects using API versions that are deprecated or already removed. It can scan manifest files in a directory, Helm releases running in a cluster, or both, and for each object it reports the API version in use, the Kubernetes version where that API was deprecated and removed, and the replacement API. Pluto writes its results as text tables, JSON, YAML, and other formats; DefectDojo imports the JSON output.

Pluto Integration with DefectDojo

Every Kubernetes upgrade we planned started with the same scramble: which of our charts and manifests still use an API the new version drops? Pluto answers that, but its answer was a terminal table that nobody owned. Importing Pluto reports into DefectDojo turns each outdated object into a Finding on the right Asset, with the migration target in the mitigation field and an owner who has until the upgrade window to fix it. Reimports show the list shrinking as teams migrate.

Why Pluto Matters

Kubernetes removes beta APIs on a published schedule. A manifest that applied fine last year can fail outright after a control plane upgrade, and workloads that need to be redeployed become stuck.

  • It catches objects on removed APIs before the upgrade, when fixing them is a change to a YAML file rather than an incident.
  • It checks both static manifests and deployed Helm releases, which covers clusters where the manifests in Git and the running state have drifted.
  • It names the replacement API for each object, so the fix is usually mechanical.
  • It also reports when the replacement API became available, which tells a team whether it can migrate now or has to wait until older clusters are upgraded.
  • Without a tracking system, upgrade readiness lives in a spreadsheet that is outdated the moment someone merges a new chart.

Advantages of This Integration

What we gained by importing Pluto output into DefectDojo:

  • Severity that matches the risk. Pluto assigns no severity, so the parser derives it: objects on a removed API are High, because they will not apply at all, and objects on a deprecated API are Medium.
  • Only problems are imported. Pluto lists objects it inspected that are fine; the parser skips anything flagged as neither deprecated nor removed.
  • Migration targets on the Finding. The mitigation names the replacement API, for example migrating a Deployment from extensions/v1beta1 to apps/v1, and the description records the deprecated-in and removed-in versions.
  • Stable deduplication. DefectDojo hashes on the API version and kind, the object, and the file path, so rescanning unchanged manifests creates no new findings.
  • Progress tracking before an upgrade. Reimporting after each migration mitigates fixed objects, giving the platform team a live count of what still blocks the upgrade.

How This Integration Works

DefectDojo imports Pluto output with the Pluto Scan scan type, which expects Pluto's JSON output.

1. Run Pluto with JSON output. To scan manifests in a repository:

pluto detect-files -d . -o json > pluto.json

To check Helm releases in the cluster your kubeconfig points at:

pluto detect-helm -o json > pluto-helm.json

Pluto evaluates deprecation against a target Kubernetes version. Set it to the version you are upgrading to so "removed" means removed in that version:

pluto detect-files -d . -o json --target-versions k8s=v1.33.0 > pluto.json

2. Import the file. In the UI, open the Engagement, choose Import Scan Results, select Pluto Scan, and upload the file. Through the API, available in Community Edition and DefectDojo Pro:

curl "https://YOUR_INSTANCE/api/v2/import-scan/" 
  -H "Authorization: Token $DD_API_TOKEN" 
  -F "scan_type=Pluto Scan" 
  -F "file=@pluto.json" 
  -F "product_name=platform-charts" 
  -F "engagement_name=K8s Upgrade Readiness" 
  -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 "Pluto Scan" 
  --report-path "./pluto.json" 
  --product-name "platform-charts" 
  --engagement-name "K8s Upgrade Readiness" 
  --auto-create-context

3. Reimport as teams migrate. Send each new report to /api/v2/reimport-scan/ for the same Test so migrated objects are mitigated.

Data Granularity: What Gets Imported

DefectDojo Field Source in Pluto JSON Notes
Title State, api.version, api.kind, name For example "Removed API extensions/v1beta1 used by Deployment/web"
Severity removed, deprecated Removed High, deprecated Medium; objects that are neither are skipped
Description Object, namespace, API version, state, deprecation details Includes deprecated-in, removed-in, replacement API, replacement-available-in, and component
Mitigation api.replacement-api "Migrate Kind/name from old version to replacement"; generic advice when no replacement exists
File Path filePath The manifest file, when Pluto reports one
Component Name api.kind and name Formatted as Kind/name
Component Version api.version The API version in use
Vuln ID from Tool api.version and api.kind Formatted as version/kind
Finding type Static All Pluto findings are static
Deduplication Hashcode Vuln ID from tool, component name, file path

Use Cases

Before a control plane upgrade: A platform team runs Pluto against every chart repository with the target version set to the planned release, imports each report into the repository's Asset, and assigns High findings to the owning teams with an SLA that ends before the upgrade window.

In a CI/CD pipeline: Each change to a manifest repository runs pluto detect-files and reimports the result, so a pull request that introduces an outdated API shows up as a new Finding.

For running clusters: Running pluto detect-helm against a cluster catches releases deployed from charts that were updated in Git but never redeployed.

For multi-cluster fleets: Each cluster's Helm results go to their own Asset, which lets a platform lead see which clusters are ready for the next version and which teams are holding an upgrade back.

Operational Tips

  • Always set --target-versions to the version you are moving to. Without it, Pluto uses its own default target, and the High and Medium split may not match your upgrade plan.
  • Keep repository scans and live cluster scans in separate Tests. They describe different things, and mixing them makes reimport results confusing.
  • Namespace is recorded in the description but is not part of the hash. If the same kind and name exist in several namespaces, as often happens with Helm releases, DefectDojo can mark the later ones as duplicates, so give each cluster or namespace group its own Test.
  • Use the SLA configuration to give High findings a deadline aligned with your upgrade date, then risk-accept anything deliberately deferred to a later upgrade with an expiration date.
  • Tag imports with the target Kubernetes version (for example tags=k8s-1.33) so readiness for different upgrades can be reported separately.
  • Push High findings to Jira so migrations land in each team's backlog with the replacement API already named.