New to Kestra?
Use blueprints to kickstart your first workflows.
Audit DigitalOcean's latest CSPM security scan, alert Slack or auto re-scan on critical findings, and log the result for cloud security teams.
DigitalOcean's built-in CSPM scanner finds misconfigurations like an exposed Droplet port or a publicly readable Spaces bucket, but it only ever shows the latest result inside the console; nothing pages a team when a new critical finding appears, and nothing confirms a fix actually cleared it until someone goes looking again. This blueprint reads the latest scan on a schedule, reports exactly which critical findings are open right now, and can kick off an immediate re-scan once you have explicitly said this flow is allowed to, so a fix gets verified without waiting for the next scheduled scan.
This blueprint was created by Mohit Jeswani.
get_latest_scan (io.kestra.plugin.digitalocean.security.scan.GetLatest) reads the
account's most recent CSPM scan and its findings. Read-only; nothing is scanned or
changed here. allowFailure: true covers an API or auth error without failing the flow
outright.evaluate (io.kestra.plugin.core.output.OutputValues) counts and lists the
CRITICAL-severity findings with a jq filter, then classifies the result as
COMPLIANT, NOT_CONFIGURED, CRITICAL_AUTO_RESCAN, CRITICAL_NEEDS_HUMAN, or
PROBE_FAILED, folding confirm_rescan into the critical-findings classification itself.route (io.kestra.plugin.core.flow.Switch):io.kestra.plugin.digitalocean.security.scan.Create
(the safe remediation, since starting a scan changes no resources, it only asks
DigitalOcean to re-evaluate), then posts a Slack notice.summary logs the finding count and severity, closing the governance cycle.errors alerts Slack if the flow itself fails, for example a revoked API token.confirm_rescan to allow it.NOT_CONFIGURED), which is
itself a compliance gap worth paging on.security.scan
namespace used as a standing compliance gate, distinct from this repo's existing
DigitalOcean blueprints, which track account balance, snapshot cost, and alert-policy
configuration rather than security scan findings.DigitalOcean's scanner finds the issues, but it has no escalation policy, no re-scan trigger
after a fix, and no Slack integration of its own. Kestra keeps confirm_rescan as an
explicit flow input, turns a raw findings list into a severity decision, and keeps a full
execution history of every scan this flow has read and what it did in response.
DigitalOcean is a hosted cloud platform with no official standalone Docker image, so
get_latest_scan cannot be exercised against a local container; validate against a real
DigitalOcean account (a free trial credit is available) first.
DIGITALOCEAN_TOKEN: the DigitalOcean personal access token used by get_latest_scan and
start_rescan. In Kestra OSS, provide it as the base64-encoded environment variable
SECRET_DIGITALOCEAN_TOKEN.SLACK_WEBHOOK_URL: used by all four Slack alert cases and the errors block. In Kestra
OSS, provide it as the base64-encoded environment variable SECRET_SLACK_WEBHOOK_URL.| Input | Default | Purpose |
|---|---|---|
confirm_rescan |
false |
Authorizes this flow to start a fresh scan itself on critical findings |
{{ outputs.get_latest_scan.id }} / .status / .findings: the latest scan's ID, status
(IN_PROGRESS, COMPLETED, FAILED, CSPM_NOT_ENABLED, or SCAN_NOT_RUN), and findings
(rule_uuid, name, severity, details, mitigation_steps,
affected_resources_count), as DigitalOcean reports them.{{ outputs.evaluate.values.critical_count }} / .critical_summary: how many findings are
CRITICAL and a semicolon-joined name (N resource(s)) summary of each.{{ outputs.evaluate.values.severity }}: COMPLIANT, NOT_CONFIGURED,
CRITICAL_AUTO_RESCAN, CRITICAL_NEEDS_HUMAN, or PROBE_FAILED.GetLatest returns at most one page of findings (perPage, default and max 200); an
account with more than 200 open findings needs page chained across repeated calls to see
them all. This blueprint reads only page 1.status can be CSPM_NOT_ENABLED or SCAN_NOT_RUN even when the API call itself
succeeds; verified directly against the task's own Javadoc and ScanOutput.java, since
treating either as a parsing failure would silently hide a real "no compliance signal
exists" condition instead of alerting on it.confirm_rescan starts a new scan on every run that finds a critical finding, not once
per finding; a scheduled run that keeps finding the same unresolved critical finding will
re-scan every time it fires, which is harmless but not free of DigitalOcean API quota.DIGITALOCEAN_TOKEN and SLACK_WEBHOOK_URL secrets.summary logs a finding count.confirm_rescan: false and confirm
alert_critical fires.confirm_rescan: true and confirm start_rescan starts a new scan and
alert_auto_rescanned fires with its ID.daily trigger once the inputs reflect your real policy.io.kestra.plugin.digitalocean.security.scan.ListAffectedResources for the
highest-severity finding to name the exact Droplets or resources affected in the Slack
alert, not just the finding's rule name.HIGH-severity findings for a quieter, non-paging Slack channel,
separate from the CRITICAL path.page and a Loop once an account regularly carries
more than 200 open findings.