Flow control steps
Flow control steps shape a workflow's logic. They decide what runs, what gets skipped, when the workflow loops, and where it pauses. 9.4 ships the full set of 8 step types: if, foreach, while, switch, wait, loop.break, loop.continue, and waitForInput.
| Pattern | Step |
|---|---|
| Branch on a condition | if |
| Iterate over an array | foreach |
| Loop until a condition is false | while |
| Multi-way dispatch on a value | switch |
| Pause for a fixed duration | wait |
| Exit a loop early | loop.break |
| Skip to the next loop iteration | loop.continue |
| Pause for operator input (human-in-the-loop) | waitForInput |
For fan-out across independent workflow executions, see workflow.executeAsync in the composition reference.
Conditional branching. Evaluates a Kibana Query Language (KQL) or boolean expression and runs the steps block if true, or the optional else block if false.
- name: route_severity
type: if
condition: "event.alerts[0].kibana.alert.risk_score >= 70"
steps:
- name: high_priority
type: console
with: { message: "High priority alert" }
else:
- name: low_priority
type: console
with: { message: "Standard alert" }
For expression syntax and additional examples, see If step.
Iterate over an array, running nested steps once per item. Inside the loop, the current item is available as foreach.item, the zero-based position as foreach.index, and the total count as foreach.total.
- name: process_alerts
type: foreach
foreach: "${{ event.alerts }}"
steps:
- name: log_alert
type: console
with:
message: "[{{ foreach.index }}/{{ foreach.total }}] {{ foreach.item._id }}"
For the full parameter reference, see Foreach step.
Loop while a KQL condition evaluates to true. Optional max-iterations caps the number of iterations; without it, the loop continues as long as the condition holds.
- name: poll_until_ready
type: while
condition: "steps.check.output.status : pending"
max-iterations:
limit: 60
on-limit: fail
steps:
- name: check
type: elasticsearch.search
with:
index: "jobs"
size: 1
- name: backoff
type: wait
with:
duration: "5s"
For the full parameter reference and gotchas, see While step.
Multi-way branching. The engine evaluates an expression once and routes to the matching case. Each case has a match value and a steps array; an optional default runs when no case matches.
- name: dispatch_by_category
type: switch
expression: "{{ steps.classify.output.category }}"
cases:
- match: "malware"
steps:
- name: handle_malware
type: console
with: { message: "malware path" }
- match: "phishing"
steps:
- name: handle_phishing
type: console
with: { message: "phishing path" }
default:
- name: handle_other
type: console
with: { message: "other" }
For the full parameter reference, see Switch step.
Pause execution for a specified duration, then continue to the next step.
- name: backoff
type: wait
with:
duration: "30s"
For the full parameter reference, see Wait step.
Exit the innermost enclosing loop (foreach or while) immediately. Takes no parameters.
- name: stop_on_match
type: if
condition: "foreach.item.severity : critical"
steps:
- name: exit
type: loop.break
For the full reference, see Loop break step.
Skip to the next iteration of the innermost enclosing loop. Takes no parameters.
- name: skip_empty
type: if
condition: "foreach.item.empty : true"
steps:
- name: next
type: loop.continue
For the full reference, see Loop continue step.
Pause the workflow until an operator submits input through the resume API or the Kibana UI. The primary human-in-the-loop primitive.
- name: review
type: waitForInput
with:
message: "Review the AI classification and confirm the action."
schema:
type: object
properties:
approved:
type: boolean
title: "Approve"
notes:
type: string
title: "Notes"
required: ["approved"]
For the complete HITL pattern, see Human-in-the-loop. For the step parameter reference, see waitForInput step.
- Composition steps:
workflow.executeAsyncfor fan-out across independent executions. - Pass data and handle errors:
on-failurestrategies for individual steps inside loops. - Human-in-the-loop: Full HITL pattern using
waitForInput.