New to Kestra?
Use blueprints to kickstart your first workflows.
Audit Kestra for orphaned namespace configuration with no flows, alert Slack, and log the result for platform teams running Kestra itself.
A namespace in Kestra can end up with saved configuration, namespace-level files, variables, and in many installs secrets, long after every flow that used it has been deleted or moved elsewhere. Nothing in Kestra itself flags that gap: the namespace still exists, still holds whatever was configured in it, and nobody is looking at it anymore. This is Kestra auditing itself: it reads the real list of namespaces with a stored configuration, compares it against the real list of namespaces that still own a flow, and reports exactly which ones are left over.
This blueprint was created by Mohit Jeswani.
list_existing_namespaces (io.kestra.plugin.kestra.namespaces.List, existingOnly: true) lists every namespace backed by a stored configuration. Read-only.list_namespaces_with_flows (io.kestra.plugin.kestra.namespaces.NamespacesWithFlows)
lists every namespace that currently owns at least one flow. Read-only.evaluate (io.kestra.plugin.core.output.OutputValues) computes the set difference
between the two lists with a jq filter and classifies the result as COMPLIANT,
ORPHANED_NAMESPACES_FOUND, or PROBE_FAILED.route (io.kestra.plugin.core.flow.Switch) logs when clean, or posts the exact
orphaned namespace names to Slack otherwise. The Kestra plugin has no task to delete a
namespace, so clearing one out stays a human decision.summary logs the orphaned count and severity, closing the governance cycle.errors alerts Slack if the flow itself fails, for example an expired API token.namespaces.List and namespaces.NamespacesWithFlows used together as a compliance
gate, distinct from this repo's existing Kestra self-management blueprint, which recovers
stuck paused executions rather than auditing namespace configuration.Kestra's own API can list namespaces and list namespaces with flows, but it has no policy
comparing the two, no schedule, and no Slack integration of its own for this. Kestra keeps
namespace_prefix and max_orphaned_count as flow inputs, turns two raw lists into a
governance decision, and keeps a full execution history of every audit and which namespaces
it flagged.
The official kestra/kestra Docker image (docker run kestra/kestra server local) is the
standard way to run a local Kestra instance for testing this blueprint against itself.
KESTRA_API_TOKEN: the Kestra API token used by both probe tasks. In Kestra OSS, provide
it as the base64-encoded environment variable SECRET_KESTRA_API_TOKEN.SLACK_WEBHOOK_URL: used by both 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 |
|---|---|---|
kestra_url |
http://localhost:8080 |
Kestra instance to audit |
namespace_prefix |
`` (empty) | Scope the audit to namespaces starting with this prefix |
max_orphaned_count |
1 |
Orphaned-namespace count that triggers the Slack alert |
{{ outputs.list_existing_namespaces.namespaces }} / {{ outputs.list_namespaces_with_flows.namespaces }}:
the two raw namespace lists, as Kestra's own API reports them.{{ outputs.evaluate.values.orphaned_count }} / .orphaned_namespaces: how many
namespaces are orphaned and their names, semicolon-joined.{{ outputs.evaluate.values.severity }}: COMPLIANT, ORPHANED_NAMESPACES_FOUND, or
PROBE_FAILED.existingOnly: true on namespaces.List excludes transient namespaces (ones that only
exist implicitly because a flow references them); verified directly against the task's
own description, since this is the exact flag that makes the comparison meaningful; without
it, every namespace a flow references would already count as "existing" and the diff
would find nothing.page is left unset; a very large
number of namespaces makes each run take proportionally longer.KESTRA_API_TOKEN and SLACK_WEBHOOK_URL secrets.docker run kestra/kestra server local and create a
namespace-level variable for a namespace with no flows in it.alert_orphaned fires naming that namespace.log_compliant fires instead.weekly trigger once namespace_prefix reflects the scope you want audited.namespace_prefix per team and deploy one copy of this flow per team's namespace
tree, routing each team's Slack alert to its own channel.