waitForApproval
Elastic Cloud Serverless projects are autoscaled environments, fully managed by Elastic and available on Elastic Cloud. Availability This functionality is in technical preview and is ready for evaluation. Use with caution in production; it is not recommended for mission-critical workloads. Elastic will work to fix any issues, but features in technical preview are not subject to the support SLA of official GA features. Specific Support terms apply. Serverless interfaces and procedures might differ from classic Elastic Stack deployments. The Elastic Stack includes Elastic's core products such as Elasticsearch, Kibana, Logstash, and Beats. Availability This functionality is in technical preview and is ready for evaluation. Use with caution in production; it is not recommended for mission-critical workloads. Elastic will work to fix any issues, but features in technical preview are not subject to the support SLA of official GA features. Specific Support terms apply. Unless stated otherwise on the page, this functionality is available when your Elastic Stack is deployed on Elastic Cloud Hosted, Elastic Cloud Enterprise, Elastic Cloud on Kubernetes, and self-managed environments. This documentation corresponds to the latest patch available for each minor version. If you're not using the latest patch, check the release notes for changes.
Serverless
Preview
Preview
Stack
Preview
9.5+
Preview since 9.5
The waitForApproval step pauses workflow execution until a human approves or rejects the request. Use it when the decision is yes or no. The step returns approved: true or false and renders approve/reject controls in Kibana and in external notifications. Approvers respond from the workflow execution view or an external notification.
For free-form or multi-field input, use waitForInput instead. For the end-to-end human-in-the-loop pattern, refer to Human-in-the-loop.
Schema convention. In each schema table on this page, the Location column indicates where each parameter sits in the YAML:
top level: Alongsidetypeandname, at the top of the step or trigger definition.`with`: Inside the step'swith:block.`on`: Inside the trigger'son:block.
| Parameter | Location | Type | Required | Description |
|---|---|---|---|---|
name |
top level | string | Yes | Unique step identifier. |
type |
top level | string | Yes | Must be waitForApproval. |
if |
top level | string | No | Boolean or KQL expression that determines whether the step runs. When it's false, the workflow continues without requesting approval. Refer to Skip a single step for more information. |
timeout |
top level | duration | No | How long the step waits for a decision. Format: number + unit (ms/s/m/h/d/w). Defaults to 24h. If no one responds before the timeout, the step fails. |
message |
with |
string | No | Markdown message displayed to approvers. |
approveLabel |
with |
string | No | Label for the approve action. Defaults to Approve. |
rejectLabel |
with |
string | No | Label for the reject action. Defaults to Decline. |
channels |
with |
object | No | External notification channels that send approve/reject links. Responders can act without signing in to Kibana. See External channels. |
Use with.channels to notify approvers outside Kibana. Slack is the only built-in channel. Notifications include one-click approve and reject links. Responders can act without signing in to Kibana.
| Channel key | Connector type | Required fields | Notes |
|---|---|---|---|
slack |
Slack webhook (slack) |
connector-id |
Posts to the channel configured on the webhook connector. |
slack_api |
Slack API (slack_api) |
connector-id, channels (array of Slack channel IDs) |
Posts approve/reject buttons to the listed channels. |
Slack content comes from the step-level with.message plus the generated approve and reject actions.
External channels send public, short-lived resume links. Don't use them for destructive, production-impacting, or hard-to-reverse workflows.
To turn off external resume, set both hitlExternalResume.enabled keys in kibana.yml (both default to true). For the exact settings, refer to Human-in-the-loop.
After someone responds, the step output has this shape:
response:
approved: true
respondedBy: "..."
- or false
- Who responded
Downstream steps typically gate on {{ steps.<step_name>.output.response.approved }}.
While waiting for a response, the step stays in the WAITING_FOR_INPUT state. How the step resolves depends on the response it receives:
- Approve finishes the step successfully with
response.approved: true. - Decline also finishes the step successfully, but with
response.approved: false. Declining does not fail the step or cancel the workflow, so you must branch on the decision (for example, with anifguard onoutput.response.approved) to stop downstream work. - No response fails the step. By default, the step times out after
24h, whether or not you configure an external channel. Override this with a top-leveltimeout.
- name: request_approval
type: waitForApproval
timeout: 24h
with:
message: "Approve isolation for {{ event.alerts[0].host.name }}?"
approveLabel: Approve
rejectLabel: Decline
channels:
slack:
connector-id: my-slack-webhook-connector
slack_api:
connector-id: my-slack-api-connector
channels: ["C0123456789"]
- name: isolate
type: http
if: "steps.request_approval.output.response.approved : true"
connector-id: "edr-connector"
with:
method: "POST"
url: "https://edr.example.com/isolate"
body:
host: "{{ event.alerts[0].host.name }}"
- Human-in-the-loop pattern: External resume and design guidance.
waitForInputstep: Collect structured input with a custom JSON Schema.- Flow control steps: Other flow-control types you'll often combine with approval gates.
- If step: Typical gate around the post-approval action.