Run detection rules on demand
This guide walks through building a workflow that triggers a manual execution of one or more detection rules over a specific time range. Use it for gap-filling after a detection rule change, post-incident review, scheduled health checks, or any time you need to run rules outside their normal cadence.
The workflow is adapted from manually-run-rules.yaml in the elastic/workflows library.
If you're new to workflows, complete Build your first workflow first.
- Permissions.
Allon Analytics > Workflows and on Security > Detection rules in the target space. Refer to Kibana privileges. - Rule IDs. The
rule_idvalues of the detection rules you want to run. You can copy them from the Rules table in Elastic Security or from a saved-object export. - Time range. The lookback window for this manual run. The default in this workflow is the last 15 minutes, which matches the interval of most default rules.
The workflow runs on demand with a list of rule IDs:
- Manual trigger with a
rule_idsarray input. foreachstep iterates the rule IDs.- For each rule, a
kibana.requeststep calls the detection engine'sPOST /api/detection_engine/rules/_bulk_actionendpoint with therunaction and a configurable time range.
-
Declare the rule IDs and time window as inputs
Inputs make the workflow reusable without editing YAML. Declare both the list of rule IDs and the lookback window in minutes:
inputs: - name: rule_ids type: array description: Detection rule IDs to run. required: true - name: lookback_minutes type: number description: How many minutes back to run the rule. default: 15 triggers: - type: manual -
Loop over the rule IDs
Use a
foreachstep to iterate. Inside the loop,foreach.itemis the current rule ID:steps: - name: for_each_rule type: foreach foreach: "${{ inputs.rule_ids }}" steps: # Per-rule step goes here. Use foreach.item for the current rule ID.Note the
${{ inputs.rule_ids }}form. Use${{ ... }}whenever you're passing an array or object to a step parameter, so the value isn't stringified. Refer to Templating engine for the{{ }}vs.${{ }}distinction. -
Trigger the rule run with
kibana.requestCall the detection engine's bulk action endpoint to run the rule over the lookback window. Build the
startandendtimestamps with Liquid date filters:- name: run_rule type: kibana.request with: method: POST path: /api/detection_engine/rules/_bulk_action body: action: run ids: - "{{ foreach.item }}" run: start_date: "{{ 'now' | date: '%s' | minus: inputs.lookback_minutes | times: 60 | date: '%Y-%m-%dT%H:%M:%S' }}.000Z" end_date: "{{ 'now' | date: '%Y-%m-%dT%H:%M:%S' }}.000Z"The two Liquid expressions compute ISO timestamps: the start is
now - lookback_minutes minutes, and the end isnow. Adjust the expressions if you need a different window shape.
Full workflow YAML
name: security--run-rules-on-demand
description: Manually run one or more detection rules over a configurable lookback window.
enabled: true
tags: ["rule-ops", "detection"]
inputs:
- name: rule_ids
type: array
description: Detection rule IDs to run.
required: true
- name: lookback_minutes
type: number
description: How many minutes back to run the rule.
default: 15
triggers:
- type: manual
steps:
- name: for_each_rule
type: foreach
foreach: "${{ inputs.rule_ids }}"
steps:
- name: log_rule
type: console
with:
message: "Running rule {{ foreach.item }}"
- name: run_rule
type: kibana.request
with:
method: POST
path: /api/detection_engine/rules/_bulk_action
body:
action: run
ids:
- "{{ foreach.item }}"
run:
start_date: "{{ 'now' | date: '%s' | minus: inputs.lookback_minutes | times: 60 | date: '%Y-%m-%dT%H:%M:%S' }}.000Z"
end_date: "{{ 'now' | date: '%Y-%m-%dT%H:%M:%S' }}.000Z"
- Run on a schedule. Replace the
manualtrigger with a scheduled trigger that fires every hour and passes a fixed rule list throughconsts. - Audit before you run. Chain a
kibana.requestGET /api/detection_engine/rulesstep first to fetch each rule's status and skip rules that are disabled or in error. - Summarize results. After the loop, post the number of rules run to Slack or index a summary document with
elasticsearch.requestfor dashboarding. - Stop on first failure. Replace the per-iteration error handling with a strict
on-failure: abortso the workflow fails fast if any one rule can't be triggered.
- Manage detection rules at scale: The outcome this workflow supports.
- Kibana action steps: Reference for
kibana.requestand named Kibana actions. - Scheduled triggers: Turn this into a recurring job.
- Detection rule concepts: Background on how detection rules run.
elastic/workflowsdetection folder: More rule-operations examples.