Create rule

edit

When used with API key authentication, the user’s key gets assigned to the affected rules. If the user’s key gets deleted or the user becomes inactive, the rules will stop running.

If the API key that is used for authorization has different privileges than the key that created or most recently updated the rule, the rule behavior might change.

Creates a new detection rule.

You can create the following types of rules:

  • Custom query: Searches the defined indices and creates an alert when a document matches the rule’s KQL query.
  • Event correlation: Searches the defined indices and creates an alert when results match an Event Query Language (EQL) query.
  • Threshold: Searches the defined indices and creates an alert when the number of times the specified field’s value meets the threshold during a single execution. When there are multiple values that meet the threshold, an alert is generated for each value.

    For example, if the threshold field is source.ip and its value is 10, an alert is generated for every source IP address that appears in at least 10 of the rule’s search results. If you’re interested, see Terms Aggregation for more information.

  • Indicator match: Creates an alert when fields match values defined in the specified Elasticsearch index. For example, you can create an index for IP addresses and use this index to create an alert whenever an event’s destination.ip equals a value in the index. The index’s field mappings should be ECS-compliant.
  • New terms: Generates an alert for each new term detected in source documents within a specified time range.
  • ES|QL: Uses Elasticsearch Query Language (ES|QL) to find events and aggregate search results.
  • Machine learning rules: Creates an alert when a machine learning job discovers an anomaly above the defined threshold (see Anomaly detection).

To create machine learning rules, you must have the appropriate license or use a cloud deployment. Additionally, for the machine learning rule to function correctly, the associated machine learning job must be running.

To retrieve machine learning job IDs, which are required to create machine learning jobs, call the Elasticsearch Get jobs API. Machine learning jobs that contain siem in the groups field can be used to create rules:

...
"job_id": "linux_anomalous_network_activity_ecs",
"job_type": "anomaly_detector",
"job_version": "7.7.0",
"groups": [
  "auditbeat",
  "process",
  "siem"
],
...

Additionally, you can set up notifications for when rules create alerts. The notifications use the Kibana Alerting and Actions framework. Each action type requires a connector. Connectors store the information required to send notifications via external systems. The following connector types are supported for rule notifications:

  • Slack
  • Email
  • PagerDuty
  • Webhook
  • Microsoft Teams
  • IBM Resilient
  • Jira
  • ServiceNow ITSM

For more information on PagerDuty fields, see Send a v2 Event.

To retrieve connector IDs, which are required to configure rule notifications, call the Kibana Find objects API with "type": "action" in the request payload.

For detailed information on Kibana actions and alerting, and additional API calls, see:

Request URL

edit

POST <kibana host>:<port>/api/detection_engine/rules

Request body

edit

A JSON object that defines the rule’s values:

Required fields for all rule types

edit
Name Type Description

description

String

The rule’s description.

name

String

The rule’s name.

risk_score

Integer

A numerical representation of the alert’s severity from 0 to 100, where:

  • 0 - 21 represents low severity
  • 22 - 47 represents medium severity
  • 48 - 73 represents high severity
  • 74 - 100 represents critical severity

severity

String

Severity level of alerts produced by the rule, which must be one of the following:

  • low: Alerts that are of interest but generally not considered to be security incidents
  • medium: Alerts that require investigation
  • high: Alerts that require immediate investigation
  • critical: Alerts that indicate it is highly likely a security incident has occurred

type

String

Data type on which the rule is based:

  • eql: EQL query (see Event Query Language).
  • esql: ES|QL query (see Elasticsearch Query Language).
  • query: query with or without additional filters.
  • saved_query: saved search, identified in the saved_id field.
  • machine_learning: rule based on a machine learning job’s anomaly scores.
  • threat_match: rule that matches event values with values in the specified Elasticsearch index.
  • threshold: rule based on the number of times a query matches the specified field.
  • new_terms: rule that alerts on values that have not been seen before

Required fields for query, indicator match, threshold, new terms, event correlation, and ES|QL rules

edit
Name Type Description

query

String

Query used by the rule to create alerts.

  • For indicator match rules, only the query’s results are used to determine whether an alert is generated.
  • ES|QL rules have additional query requirements. Refer to Create ES|QL rules for more information.

Required field for threshold rules

edit
Name Type Description

threshold

Object

Defines the field and threshold value for when alerts are generated, where:

  • cardinality (Array of length 1): The field on which the cardinality is applied.
  • cardinality.field (string, required): The field on which to calculate and compare the cardinality.
  • cardinality.value (integer, required): The threshold value from which an alert is generated based on unique number of values of cardinality.field.
  • field (string or string[], required): The field on which the threshold is applied. If you specify an empty array ([]), alerts are generated when the query returns at least the number of results specified in the value field.
  • value (integer, required): The threshold value from which an alert is generated.

Required field for saved query rules

edit
Name Type Description

saved_id

String

Kibana saved search used by the rule to create alerts.

Required field for event correlation rules

edit
Name Type Description

language

String

Must be eql.

Required field for ES|QL rules

edit
Name Type Description

language

String

Must be esql.

Required fields for machine learning rules

edit
Name Type Description

anomaly_threshold

Integer

Anomaly score threshold above which the rule creates an alert. Valid values are from 0 to 100.

machine_learning_job_id

String[]

Machine learning job ID(s) the rule monitors for anomaly scores.

Required fields for indicator match rules

edit
Name Type Description

threat_index

String[]

Elasticsearch indices used to check which field values generate alerts.

threat_query

String

Query used to determine which fields in the Elasticsearch index are used for generating alerts.

threat_mapping

Object[]

Array of entries objects that define mappings between the source event fields and the values in the Elasticsearch threat index. Each entries object must contain these fields:

  • field: field from the event indices on which the rule runs
  • type: must be mapping
  • value: field from the Elasticsearch threat index

You can use Boolean and and or logic to define the conditions for when matching fields and values generate alerts. Sibling entries objects are evaluated using or logic, whereas multiple entries in a single entries object use and logic. See below for an example that uses both and and or logic.

Required fields for new terms rules

edit
Name Type Description

new_terms_fields

String[]

Fields to monitor for new values. Must contain 1–3 field names.

history_window_start

String

Start date to use when checking if a term has been seen before. Supports relative dates – for example, now-30d will search the last 30 days of data when checking if a term is new. We do not recommend using absolute dates, which can cause issues with rule performance due to querying increasing amounts of data over time.

Optional fields for all rule types

edit
Name Type Description

actions

actions[]

Array defining the automated actions (notifications) taken when alerts are generated.

author

String[]

The rule’s author.

building_block_type

String

Determines if the rule acts as a building block. By default, building-block alerts are not displayed in the UI. These rules are used as a foundation for other rules that do generate alerts. Its value must be default. For more information, refer to About building block rules.

enabled

Boolean

Determines whether the rule is enabled. Defaults to true.

false_positives

String[]

String array used to describe common reasons why the rule may issue false-positive alerts. Defaults to an empty array.

from

String

Time from which data is analyzed each time the rule executes, using a date math range. For example, now-4200s means the rule analyzes data from 70 minutes before its start time. Defaults to now-6m (analyzes data from 6 minutes before the start time).

interval

String

Frequency of rule execution, using a date math range. For example, "1h" means the rule runs every hour. Defaults to 5m (5 minutes).

license

String

The rule’s license.

max_signals

Integer

Maximum number of alerts the rule can create during a single run (the rule’s Max alerts per run advanced setting value). Defaults to 100.

This setting can be superseded by the Kibana configuration setting xpack.alerting.rules.run.alerts.max, which determines the maximum alerts generated by any rule in the Kibana alerting framework. For example, if xpack.alerting.rules.run.alerts.max is set to 1000, the rule can generate no more than 1000 alerts even if max_signals is set higher.

meta

Object

Placeholder for metadata about the rule.

NOTE: This field is overwritten when you save changes to the rule’s settings.

note

String

Notes to help investigate alerts produced by the rule.

references

String[]

Array containing notes about or references to relevant information about the rule. Defaults to an empty array.

required_fields

Object[]

Elasticsearch fields and their types that need to be present for the rule to function. The object has these fields:

  • name (string, required): The field’s name.
  • type (string, required): The field’s data type.
  • ecs (Boolean, optional): Indicates whether the field is ECS-compliant. This property is only present in responses. Its value is computed based on field’s name and type.

NOTE: The value of required_fields does not affect the rule’s behavior, and specifying it incorrectly won’t cause the rule to fail. Use required_fields as an informational property to document the fields that the rule expects to be present in the data.

rule_id

String

Unique ID used to identify rules. For example, when a rule is converted from a third-party security solution. Automatically created when it is not provided.

setup

String

Populates the rule’s setup guide with instructions on rule prerequisites such as required integrations, configuration steps, and anything else needed for the rule to work correctly.

tags

String[]

String array containing words and phrases to help categorize, filter, and search rules. Defaults to an empty array.

threat

threat[]

Object containing attack information about the type of threat the rule monitors, see ECS threat fields. Defaults to an empty array.

throttle

String

Determines how often actions are taken:

The rule level throttle field is deprecated in Elastic Security 8.8 and will remain active for at least the next 12 months.

In Elastic Security 8.8 and later, you can use the (frequency) field to define frequencies for individual actions. Actions without frequencies will acquire a converted version of the rule’s throttle field. In the response, the converted throttle setting appears in the individual actions' frequency field.

  • no_actions: Never
  • rule: Every time new alerts are detected
  • 1h: Every hour
  • 1d: Every day
  • 7d: Every week

Required when actions are used to send notifications.

version

Integer

The rule’s version number. Defaults to 1.

investigation_fields

Object

Specify highlighted fields for personalized alert investigation flows:

  • field_names: String[] , required

related_integrations

Object[]

Elastic integrations the rule depends on. The object has these fields:

  • package (String, required): The integration package’s name, as used by the Elastic Package Registry.
  • integration (String, optional): The integration’s name. This field is optional for packages with only one integration whose name matches the package name, but it’s required for packages with multiple integrations.
  • version: (String, required): Integration (package containing the integration) version constraint in semantic versioning format. For version ranges, you must use tilde or caret syntax. For example, ~1.2.3 is from 1.2.3 to any patch version less than 1.3.0, and ^1.2.3 is from 1.2.3` to any minor and patch version less than 2.0.0.

Optional fields for indicator match rules

edit
Name Type Description

threat_filters

Object[]

Query and filter context array used to filter documents from the Elasticsearch index containing the threat values.

threat_indicator_path

String

Much like an ingest processor, users can use this field to define where their threat indicator can be found on their indicator documents. Defaults to threatintel.indicator.

Optional fields for query, indicator match, threshold, and new terms rules

edit
Name Type Description

language

String

Determines the query language, which must be kuery or lucene. Defaults to kuery.

Optional fields for event correlation, query, threshold, indicator match, new terms, and ES|QL rules

edit
Name Type Description

filters

Object[]

The query and filter context array used to define the conditions for when alerts are created from events. Defaults to an empty array.

This field is not supported for ES|QL rules.

index

String[]

Indices on which the rule functions. Defaults to the Security Solution indices defined on the Kibana Advanced Settings page (KibanaStack ManagementAdvanced SettingssecuritySolution:defaultIndex).

This field is not supported for ES|QL rules.

risk_score_mapping

Object[]

Overrides generated alerts' risk_score with a value from the source event:

  • field (string, required): Source event field used to override the default risk_score. This field must be an integer.
  • operator (string, required): Must be equals.
  • value(string, required): Must be an empty string ("").

rule_name_override

String

Sets which field in the source event is used to populate the alert’s signal.rule.name value (in the UI, this value is displayed on the Rules page in the Rule column). When unspecified, the rule’s name value is used. The source field must be a string data type.

severity_mapping

Object[]

Overrides generated alerts' severity with values from the source event:

  • field (string, required): Source event field used to override the default severity.
  • operator (string, required): Must be equals.
  • severity (string, required): Mapped severity value, must be low, medium, high, or critical.
  • value(string, required): Field value used to determine the severity.

timestamp_override

String

Sets the time field used to query indices. When unspecified, rules query the @timestamp field. The source field must be an Elasticsearch date data type.

exceptions_list

Object[]

Array of exception containers, which define exceptions that prevent the rule from generating alerts even when its other criteria are met. The object has these fields:

  • id (string, required): ID of the exception container.
  • list_id (string, required): List ID of the exception container.
  • namespace_type (string required): Determines whether the exceptions are valid in only the rule’s Kibana space (single) or in all Kibana spaces (agnostic).
  • type (string, required): The exception type, which must be either a detection rule exception (detection) or an endpoint exception (endpoint).

Optional fields for event correlation rules

edit
Name Type Description

event_category_field

String

Contains the event classification, such as process, file, or network. This field is typically mapped as a field type in the keyword family. Defaults to the event.category ECS field.

tiebreaker_field

String

Sets a secondary field for sorting events (in ascending, lexicographic order) if they have the same timestamp.

timestamp_field

String

Contains the event timestamp used for sorting a sequence of events. This is different from timestamp_override, which is used for querying events within a range. Defaults to the @timestamp ECS field.

Optional alert suppression fields for query, indicator match, threshold, event correlation (non-sequence queries only), new terms, ES|QL, and machine learning rules

edit

Alert suppression is in technical preview for event correlation rules. The functionality may be changed or removed in a future release. Elastic will work to fix any issues, but features in technical preview are not subject to the support SLA of official GA features.

Query, indicator match, event correlation (non-sequence queries only), new terms, ES|QL, and machine learning rules
edit
Name Type Description

alert_suppression

Object

Defines alert suppression configuration. Available fields:

  • group_by (string[], required): An array of 1-3 field names to use for suppressing alerts.
  • duration (duration object, optional): The time period in which alerts will be suppressed, beginning when the rule first meets its criteria and creates the alert. If not specified, alerts will be suppressed on rule execution only.
  • missing_fields_strategy (string, optional): Defines how to handle events with missing suppression fields. Possible values:

    • doNotSuppress: Create a separate alert for each matching event.
    • suppress: Create one alert for each group of events with missing fields.
Threshold rule
edit
Name Type Description

alert_suppression

Object

Defines alert suppression configuration. Available fields:

  • duration (duration object, required): The time period in which alerts will be suppressed, beginning when the rule first meets its criteria and creates the alert.

actions schema

edit

All fields are required:

Name Type Description

action_type_id

String

The connector type used for sending notifications, can be:

  • .slack
  • .slack_api
  • .email
  • .index
  • .pagerduty
  • .swimlane
  • .webhook
  • .servicenow
  • .servicenow-itom
  • .servicenow-sir
  • .jira
  • .resilient
  • .opsgenie
  • .teams
  • .torq
  • .tines
  • .d3security

group

String

Optionally groups actions by use cases. Use default for alert notifications.

id

String

The connector ID.

params

Object

Object containing the allowed connector fields, which varies according to the connector type:

  • For Slack:

    • message (string, required): The notification message.
  • For email:

    • to, cc, bcc (string): Email addresses to which the notifications are sent. At least one field must have a value.
    • subject (string, optional): Email subject line.
    • message (string, required): Email body text.
  • For Webhook:

    • body (string, required): JSON payload.
  • For PagerDuty:

    • severity (string, required): Severity of on the alert notification, can be: Critical, Error, Warning or Info.
    • eventAction (string, required): Event action type, which can be trigger, resolve, or acknowledge.
    • dedupKey (string, optional): Groups alert notifications with the same PagerDuty alert.
    • timestamp (DateTime, optional): ISO-8601 format timestamp.
    • component (string, optional): Source machine component responsible for the event, for example security-solution.
    • group (string, optional): Enables logical grouping of service components.
    • source (string, optional): The affected system. Defaults to the Kibana saved object ID of the action.
    • summary (string, options): Summary of the event. Defaults to No summary provided. Maximum length is 1024 characters.
    • class (string, optional): Value indicating the class/type of the event.
Optional action fields
edit
Name Type Description

frequency

String

Object containing an action’s frequency:

  • summary (Boolean, required): Defines whether to send notifications as a summary of alerts or for each generated alert.
  • notifyWhen (String, required`): Defines how often alerts generate actions. Valid values are:

    • onActiveAlert: Actions run when the alert is generated.
    • onThrottleInterval: Actions run on the specified throttle interval and summarize new alerts generated during that interval.
  • throttle (String, optional): Defines how often an alert generates repeated actions. This custom action interval must be specified in seconds, minutes, hours, or days. For example, 10m or 1h. This property is used only if notifyWhen is onThrottleInterval.

alerts_filter

Object

Object containing an action’s conditional filters:

  • timeframe (Object, optional): Object containing the time frame for when this action can be run.

    • days (Array of integers, required): List of days of the week on which this action can be run. Days of the week are expressed as numbers between 1-7, where 1 is Monday and 7 is Sunday. To select all days of the week, enter an empty array.
    • hours (Object, required): The hours of the day during which this action can run. Hours of the day are expressed as two strings in the format hh:mm in 24 hour time. A start of 00:00 and an end of 24:00 means the action can run all day.

      • start (String, required)
      • end (String, required)
    • timezone (String, required): An ISO timezone name, such as Europe/Madrid or America/New_York. Specific offsets such as UTC or UTC+1 will also work, but lack built-in DST.
  • query (Object, optional): Object containing a query filter which gets applied to an action and determines whether the action should run.

    • kql (String, required): A KQL string.
    • filters (Array of objects, required): A filter object, as defined in the kbn-es-query package.
Alert notification placeholders
edit

You can use mustache syntax to add variables to notification messages. The action frequency you choose determines the variables you can select from.

The following variables can be passed for all rules:

Refer to Action frequency: Summary of alerts to learn about additional variables that can be passed if the rule’s action frequency is Summary of alerts.

  • {{context.alerts}}: Array of detected alerts
  • {{{context.results_link}}}: URL to the alerts in Kibana
  • {{context.rule.anomaly_threshold}}: Anomaly threshold score above which alerts are generated (machine learning rules only)
  • {{context.rule.description}}: Rule description
  • {{context.rule.false_positives}}: Rule false positives
  • {{context.rule.filters}}: Rule filters (query rules only)
  • {{context.rule.id}}: Unique rule ID returned after creating the rule
  • {{context.rule.index}}: Indices rule runs on (query rules only)
  • {{context.rule.language}}: Rule query language (query rules only)
  • {{context.rule.machine_learning_job_id}}: ID of associated machine learning job (machine learning rules only)
  • {{context.rule.max_signals}}: Maximum allowed number of alerts per rule execution
  • {{context.rule.name}}: Rule name
  • {{context.rule.query}}: Rule query (query rules only)
  • {{context.rule.references}}: Rule references
  • {{context.rule.risk_score}}: Default rule risk score

    This placeholder contains the rule’s default values even when the Risk score override option is used.

  • {{context.rule.rule_id}}: Generated or user-defined rule ID that can be used as an identifier across systems
  • {{context.rule.saved_id}}: Saved search ID
  • {{context.rule.severity}}: Default rule severity

    This placeholder contains the rule’s default values even when the Severity override option is used.

  • {{context.rule.threat}}: Rule threat framework
  • {{context.rule.threshold}}: Rule threshold values (threshold rules only)
  • {{context.rule.timeline_id}}: Associated Timeline ID
  • {{context.rule.timeline_title}}: Associated Timeline name
  • {{context.rule.type}}: Rule type
  • {{context.rule.version}}: Rule version
  • {{date}}`: Date the rule scheduled the action
  • {{kibanaBaseUrl}}: Configured server.publicBaseUrl value, or empty string if not configured
  • {{rule.id}}: ID of the rule
  • {{rule.name}}: Name of the rule
  • {{rule.spaceId}}: Space ID of the rule
  • {{rule.tags}}: Tags of the rule
  • {{rule.type}}: Type of rule
  • {{state.signals_count}}: Number of alerts detected

The following variables can only be passed if the rule’s action frequency is for each alert:

  • {{alert.actionGroup}}: Action group of the alert that scheduled actions for the rule
  • {{alert.actionGroupName}}: Human-readable name of the action group of the alert that scheduled actions for the rule
  • {{alert.actionSubgroup}}: Action subgroup of the alert that scheduled actions for the rule
  • {{alert.id}}: ID of the alert that scheduled actions for the rule
  • {{alert.flapping}}: A flag on the alert that indicates whether the alert status is changing repeatedly

response actions schema

edit

All fields are required:

Name Type Description

action_type_id

String

The response action you want to add to a rule.

  • .osquery
  • .endpoint

    To learn more about the requirements for using the isolate endpoint response action, refer to Isolate a host.

    Host isolation involves quarantining a host from the network to prevent further spread of threats and limit potential damage. Be aware that automatic host isolation can cause unintended consequences, such as disrupting legitimate user activities or blocking critical business processes.

params

Object

Object containing the allowed response action fields, which varies according to the response action.

Osquery

For Osquery (.osquery), use a single query, a saved query, or a query pack:

  • query (string, optional): To run a single query, use the query field and enter a SQL query. Example: "query": "SELECT * FROM processes;"
  • saved_query_id (string, optional): To run a saved query, use the saved_query_id field and specify the saved query ID. Example: "saved_query_id": "processes_elastic"
  • packId (string, optional): To specify a query pack, use the packId field. Example: "packId": "processes_elastic"
  • ecs_mapping (object, required): Map Osquery results columns or static values to Elastic Common Schema (ECS) fields. Example: "ecs_mapping": {"process.pid": {"field": "pid"}}
  • timeout (number, optional): A timeout period, in seconds, after which the query will stop running. Overwriting the default timeout allows you to support queries that require more time to complete. The default and minimum supported value is 60. The maximum supported value is 900. Example: "timeout": 120.

Refer to Create live query API for more information about running Osquery queries and packs.

Endpoint Security

For Endpoint Security (.endpoint), specify an endpoint response action command and provide an optional comment:

  • command (string, optional): To run an endpoint response action, specify a value for the command field. Example: "command": "isolate"

    The only action that’s available is the isolate host response action (isolate).

  • comment (string, optional): Add a note that explains or describes the action. You can find your comment in the response actions history log. Example: "comment": "Check processes"

threat schema

edit

All fields are required:

Name Type Description

framework

String

Relevant attack framework.

tactic

Object

Object containing information on the attack type:

  • id - string, required
  • name - string, required
  • reference - string, required

technique

Array

Array containing information on the attack techniques (optional):

  • id - string, required
  • name - string, required
  • reference - string, required
  • subtechnique - Array, optional

subtechnique

Array

Array containing more specific information on the attack technique:

  • id - string, required
  • name - string, required
  • reference - string, required

Only threats described using the MITRE ATT&CKTM framework are displayed in the UI (RulesDetection rules (SIEM)Rule name).

alert_suppression.duration schema

edit

All fields are required:

Name Type Description

unit

string

Time unit. Possible values are: s(seconds), m(minutes), or h(hours).

value

number

Positive number.

Example requests

edit

Example 1

Query rule that searches for processes started by MS Office:

POST api/detection_engine/rules
{
  "rule_id": "process_started_by_ms_office_program",
  "risk_score": 50,
  "description": "Process started by MS Office program - possible payload",
  "interval": "1h", 
  "name": "MS Office child process",
  "severity": "low",
  "tags": [
   "child process",
   "ms office"
   ],
  "type": "query",
  "from": "now-70m", 
  "query": "process.parent.name:EXCEL.EXE or process.parent.name:MSPUB.EXE or process.parent.name:OUTLOOK.EXE or process.parent.name:POWERPNT.EXE or process.parent.name:VISIO.EXE or process.parent.name:WINWORD.EXE",
  "language": "kuery",
  "filters": [
     {
      "query": {
         "match": {
            "event.action": {
               "query": "Process Create (rule: ProcessCreate)",
               "type": "phrase"
            }
         }
      }
     }
  ],
  "required_fields": [
    { name: "process.parent.name", "type": "keyword" }
  ],
  "related_integrations": [
    { "package": "o365", "version": "^2.3.2"}
  ],
  "enabled": false
}

The rule runs every hour.

When the rule runs it analyzes data from 70 minutes before its start time.

If the rule starts to run at 15:00, it analyzes data from 13:50 until 15:00. When it runs next, at 16:00, it will analyze data from 14:50 until 16:00.

Example 2

Threshold rule that detects multiple failed login attempts to a Windows host from the same external source IP address, and maps the severity value to custom source event fields:

POST api/detection_engine/rules
{
  "description": "Detects when there are 20 or more failed login attempts from the same IP address with a 2 minute time frame.",
  "enabled": true,
  "exceptions_list": [ 
    {
      "id": "int-ips",
      "namespace_type": "single",
      "type": "detection"
    }
  ],
  "from": "now-180s",
  "index": [
    "winlogbeat-*"
  ],
  "interval": "2m",
  "name": "Windows server prml-19",
  "query": "host.name:prml-19 and event.category:authentication and event.outcome:failure",
  "required_fields": [
    { "name": "source.ip", "type": "ip" }
  ],
  "risk_score": 30,
  "rule_id": "liv-win-ser-logins",
  "severity": "low",
  "severity_mapping": [ 
    {
      "field": "source.geo.city_name",
      "operator": "equals",
      "severity": "low",
      "value": "Manchester"
    },
    {
      "field": "source.geo.city_name",
      "operator": "equals",
      "severity": "medium",
      "value": "London"
    },
    {
      "field": "source.geo.city_name",
      "operator": "equals",
      "severity": "high",
      "value": "Birmingham"
    },
    {
      "field": "source.geo.city_name",
      "operator": "equals",
      "severity": "critical",
      "value": "Wallingford"
    }
  ],
  "tags": [
    "Brute force"
  ],
  "threshold": { 
    "field": "source.ip",
    "value": 20
  },
  "type": "threshold"
}

Exception list container used to exclude internal IP addresses.

Alert severity levels are mapped according to the defined field values.

Alerts are generated when the same source IP address is discovered in at least 20 results.

Example 3

Machine learning rule that creates alerts, and sends Slack notifications, when the linux_anomalous_network_activity_ecs machine learning job discovers anomalies with a threshold of 70 or above:

POST api/detection_engine/rules
{
  "anomaly_threshold": 70,
  "rule_id": "ml_linux_network_high_threshold",
  "risk_score": 70,
  "machine_learning_job_id": "linux_anomalous_network_activity_ecs",
  "description": "Generates alerts when the job discovers anomalies over 70",
  "interval": "5m",
  "name": "Anomalous Linux network activity",
  "note": "Shut down the internet.",
  "setup": "This rule requires data coming in from Elastic Defend."
  "severity": "high",
  "tags": [
   "machine learning",
   "Linux"
   ],
  "type": "machine_learning",
  "from": "now-6m",
  "enabled": true,
  "actions": [
    {
      "action_type_id": ".slack",
      "group": "default",
      "id": "5ad22cd5-5e6e-4c6c-a81a-54b626a4cec5",
      "params": {
        "message": "Urgent: {{context.rule.description}}"
      }
    }
  ]
}

Example 4

Event correlation rule that creates alerts when the Windows rundll32.exe process makes unusual network connections:

POST api/detection_engine/rules
{
  "rule_id": "eql-outbound-rundll32-connections",
  "risk_score": 21,
  "description": "Unusual rundll32.exe network connection",
  "name": "rundll32.exe network connection",
  "severity": "low",
  "tags": [
   "EQL",
   "Windows",
   "rundll32.exe"
   ],
  "type": "eql",
  "language": "eql",
  "query": "sequence by process.entity_id with maxspan=2h [process where event.type in (\"start\", \"process_started\") and (process.name == \"rundll32.exe\" or process.pe.original_file_name == \"rundll32.exe\") and ((process.args == \"rundll32.exe\" and process.args_count == 1) or (process.args != \"rundll32.exe\" and process.args_count == 0))] [network where event.type == \"connection\" and (process.name == \"rundll32.exe\" or process.pe.original_file_name == \"rundll32.exe\")]",
  "required_fields": [
    { "name": "event.type", "type": "keyword" },
    { "name": "process.args", "type": "keyword" },
    { "name": "process.args_count", "type": "long" },
    { "name": "process.entity_id", "type": "keyword" },
    { "name": "process.name", "type": "keyword" },
    { "name": "process.pe.original_file_name", "type": "keyword" }
  ]
}

Example 5

Indicator match rule that creates an alert when one of the following is true:

  • The event’s destination IP address and port number matches destination IP and port values in the threat_index index.
  • The event’s source IP address matches a host IP address value in the threat_index index.
POST api/detection_engine/rules
{
    "type": "threat_match",
    "actions": [],
    "index": [
        "packetbeat-*"
    ],
    "query": "destination.ip:* or host.ip:*",
    "threat_index": [
        "ip-threat-list" 
    ],
    "threat_query": "*:*", 
    "threat_mapping": [
        {
            "entries": [ 
                {
                    "field": "destination.ip",
                    "type": "mapping",
                    "value": "destination.ip"
                },
                {
                    "field": "destination.port",
                    "type": "mapping",
                    "value": "destination.port"
                }
            ]
        },
        {
            "entries": [ 
                {
                    "field": "source.ip",
                    "type": "mapping",
                    "value": "host.ip"
                }
            ]
        }
    ],
    "required_fields": [
      { "name": "destination.ip", "type": "ip" },
      { "name": "destination.port", "type": "long" },
      { "name": "host.ip", "type": "ip" }
    ],
    "risk_score": 50,
    "severity": "medium",
    "name": "Bad IP threat match",
    "description": "Checks for bad IP addresses listed in the ip-threat-list index"
}

The Elasticsearch index used for matching threat values.

Query defining which threat index fields are used for matching values. In this example, all values from the ip-threat-list index are used.

Multiple objects in a single entries element are evaluated using and logic. In this example, both the event’s destination.ip and destination.port values must match the corresponding field values in the ip-threat-list.

Sibling entries are evaluated using or logic. An alert is generated when at least one entries object evaluates to true.

Example 6

New terms rule that creates alerts a new IP address is detected for a user:

POST api/detection_engine/rules
{
  "risk_score": 21,
  "description": "Detects a user associated with a new IP address",
  "name": "New User IP Detected",
  "severity": "medium",
  "type": "new_terms",
  "language": "kuery",
  "query": "*",
  "new_terms_fields": ["user.id", "source.ip"],
  "history_window_start": "now-30d",
  "index": ["auditbeat*"],
  "required_fields": [
    { "name": "user.id", "type": "keyword" },
    { "name": "source.ip", "type": "ip" }
  ]
}

Example 7

ES|QL rule that creates alerts from events that match an Excel parent process:

POST api/detection_engine/rules
{
  "type": "esql",
  "language": "esql",
  "query": "from auditbeat-8.10.2 METADATA _id, _version, _index | where process.parent.name == \"EXCEL.EXE\"",
  "name": "Find Excel events",
  "description": "Find Excel events",
  "tags": [],
  "interval": "5m",
  "from": "now-360s",
  "to": "now",
  "enabled": false,
  "risk_score": 21,
  "severity": "low",
  "required_fields": [
    { "name": "process.parent.name", "type": "keyword" }
  ]
}

Example 8

Query rule that searches for processes started by MS Office and suppresses alerts by the process.parent.name field within a 5-hour time period:

POST api/detection_engine/rules
{
  "rule_id": "process_started_by_ms_office_program",
  "risk_score": 50,
  "description": "Process started by MS Office program - possible payload",
  "interval": "1h",
  "name": "MS Office child process",
  "severity": "low",
  "tags": [
   "child process",
   "ms office"
   ],
  "type": "query",
  "from": "now-70m",
  "query": "process.parent.name:EXCEL.EXE or process.parent.name:MSPUB.EXE or process.parent.name:OUTLOOK.EXE or process.parent.name:POWERPNT.EXE or process.parent.name:VISIO.EXE or process.parent.name:WINWORD.EXE",
  "language": "kuery",
  "filters": [
     {
      "query": {
         "match": {
            "event.action": {
               "query": "Process Create (rule: ProcessCreate)",
               "type": "phrase"
            }
         }
      }
     }
  ],
  "enabled": false,
  "alert_suppression": {
    "duration": { "unit": "h", "value": 5 },
    "group_by": [
        "process.parent.name"
    ],
    "missing_fields_strategy": "suppress"
  }
}

Response code

edit
200
Indicates a successful call.

Response payload

edit

A JSON object that includes a unique ID, the time the rule was created, and its version number. If the request payload did not include a rule_id field, a unique rule ID is also generated.

Example response for a query rule:

{
  "created_at": "2020-04-07T14:51:09.755Z",
  "updated_at": "2020-04-07T14:51:09.970Z",
  "created_by": "elastic",
  "description": "Process started by MS Office program - possible payload",
  "enabled": false,
  "false_positives": [],
  "from": "now-70m",
  "id": "6541b99a-dee9-4f6d-a86d-dbd1869d73b1",
  "immutable": false,
  "interval": "1h",
  "rule_id": "process_started_by_ms_office_program",
  "max_signals": 100,
  "risk_score": 50,
  "name": "MS Office child process",
  "references": [],
  "severity": "low",
  "updated_by": "elastic",
  "tags": [
    "child process",
    "ms office"
  ],
  "to": "now",
  "type": "query",
  "threat": [],
  "version": 1,
  "actions": [],
  "filters": [
    {
      "query": {
        "match": {
          "event.action": {
            "query": "Process Create (rule: ProcessCreate)",
            "type": "phrase"
          }
        }
      }
    }
  ],
  "query": "process.parent.name:EXCEL.EXE or process.parent.name:MSPUB.EXE or process.parent.name:OUTLOOK.EXE or process.parent.name:POWERPNT.EXE or process.parent.name:VISIO.EXE or process.parent.name:WINWORD.EXE",
  "language": "kuery",
  "related_integrations": [
    { "package": "o365", "version": "^2.3.2" },
    { "package": "azure", "version": "^1.11.4", "integration": "graphactivitylogs" }
  ],
  "required_fields": [
    { "name": "process.parent.name", "type": "keyword", "ecs": true }
  ],
  "setup": ""
}

Example response for a machine learning job rule:

{
  "created_at": "2020-04-07T14:45:15.679Z",
  "updated_at": "2020-04-07T14:45:15.892Z",
  "created_by": "elastic",
  "description": "Generates alerts when the job discovers anomalies over 70",
  "enabled": true,
  "false_positives": [],
  "from": "now-6m",
  "id": "83876f66-3a57-4a99-bf37-416494c80f3b",
  "immutable": false,
  "interval": "5m",
  "rule_id": "ml_linux_network_high_threshold",
  "max_signals": 100,
  "risk_score": 70,
  "name": "Anomalous Linux network activity",
  "references": [],
  "severity": "high",
  "updated_by": "elastic",
  "tags": [
    "machine learning",
    "Linux"
  ],
  "to": "now",
  "type": "machine_learning",
  "threat": [],
  "version": 1,
  "actions": [
    {
      "action_type_id": ".slack",
      "group": "default",
      "id": "5ad22cd5-5e6e-4c6c-a81a-54b626a4cec5",
      "params": {
        "message": "Urgent: {{context.rule.description}}"
      },
      "frequency": {
        "summary": true,
        "notifyWhen": "onActiveAlert",
        "throttle": null
      }
    }
  ],
  "note": "Shut down the internet.",
  "status": "going to run",
  "status_date": "2020-04-07T14:45:21.685Z",
  "anomaly_threshold": 70,
  "machine_learning_job_id": "linux_anomalous_network_activity_ecs",
  "related_integrations": [],
  "required_fields": [],
  "setup": ""
}

Example response for a threshold rule:

{
  "author": [],
  "created_at": "2020-07-22T10:27:23.486Z",
  "updated_at": "2020-07-22T10:27:23.673Z",
  "created_by": "elastic",
  "description": "Detects when there are 20 or more failed login attempts from the same IP address with a 2 minute time frame.",
  "enabled": true,
  "false_positives": [],
  "from": "now-180s",
  "id": "15dbde26-b627-4d74-bb1f-a5e0ed9e4993",
  "immutable": false,
  "interval": "2m",
  "rule_id": "liv-win-ser-logins",
  "max_signals": 100,
  "risk_score": 30,
  "risk_score_mapping": [],
  "name": "Windows server prml-19",
  "references": [],
  "severity": "low",
  "severity_mapping": [
    {
      "field": "source.geo.city_name",
      "operator": "equals",
      "severity": "low",
      "value": "Manchester"
    },
    {
      "field": "source.geo.city_name",
      "operator": "equals",
      "severity": "medium",
      "value": "London"
    },
    {
      "field": "source.geo.city_name",
      "operator": "equals",
      "severity": "high",
      "value": "Birmingham"
    },
    {
      "field": "source.geo.city_name",
      "operator": "equals",
      "severity": "critical",
      "value": "Wallingford"
    }
  ],
  "updated_by": "elastic",
  "tags": [
    "Brute force"
  ],
  "to": "now",
  "type": "threshold",
  "threat": [],
  "version": 1,
  "exceptions_list": [
    {
      "id": "int-ips",
      "namespace_type": "single",
      "type": "detection"
    }
  ],
  "actions": [],
  "index": [
    "winlogbeat-*"
  ],
  "query": "host.name:prml-19 and event.category:authentication and event.outcome:failure",
  "language": "kuery",
  "threshold": {
    "field": "source.ip",
    "value": 20
  },
  "related_integrations": [
    { "package": "o365", "version": "^2.3.2" }
  ],
  "required_fields": [
    { "name": "source.ip", "type": "ip", "ecs": true }
  ],
  "setup": ""
}

Example response for an EQL rule:

{
  "author": [],
  "created_at": "2020-10-05T09:06:16.392Z",
  "updated_at": "2020-10-05T09:06:16.403Z",
  "created_by": "elastic",
  "description": "Unusual rundll32.exe network connection",
  "enabled": true,
  "false_positives": [],
  "from": "now-6m",
  "id": "93808cae-b05b-4dc9-8479-73574b50f8b1",
  "immutable": false,
  "interval": "5m",
  "rule_id": "eql-outbound-rundll32-connections",
  "max_signals": 100,
  "risk_score": 21,
  "risk_score_mapping": [],
  "name": "rundll32.exe network connection",
  "references": [],
  "severity": "low",
  "severity_mapping": [],
  "updated_by": "elastic",
  "tags": [
    "EQL",
    "Windows",
    "rundll32.exe"
  ],
  "to": "now",
  "type": "eql",
  "threat": [],
  "version": 1,
  "exceptions_list": [],
  "throttle": "no_actions",
  "query": "sequence by process.entity_id with maxspan=2h [process where event.type in (\"start\", \"process_started\") and (process.name == \"rundll32.exe\" or process.pe.original_file_name == \"rundll32.exe\") and ((process.args == \"rundll32.exe\" and process.args_count == 1) or (process.args != \"rundll32.exe\" and process.args_count == 0))] [network where event.type == \"connection\" and (process.name == \"rundll32.exe\" or process.pe.original_file_name == \"rundll32.exe\")]",
  "language": "eql",
  "related_integrations": [
    { "package": "o365", "version": "^2.3.2" }
  ],
  "required_fields": [
    { "name": "event.type", "type": "keyword", "ecs": true },
    { "name": "process.args", "type": "keyword", "ecs": true },
    { "name": "process.args_count", "type": "long", "ecs": true },
    { "name": "process.entity_id", "type": "keyword", "ecs": true },
    { "name": "process.name", "type": "keyword", "ecs": true },
    { "name": "process.pe.original_file_name", "type": "keyword", "ecs": true }
  ],
  "setup": ""
}

Example response for an indicator match rule:

{
  "author": [],
  "created_at": "2020-10-06T07:07:58.227Z",
  "updated_at": "2020-10-06T07:07:58.237Z",
  "created_by": "elastic",
  "description": "Checks for bad IP addresses listed in the ip-threat-list index",
  "enabled": true,
  "false_positives": [],
  "from": "now-6m",
  "id": "d5daa13f-81fb-4b13-be2f-31011e1d9ae1",
  "immutable": false,
  "interval": "5m",
  "rule_id": "608501e4-c768-4f64-9326-cec55b5d439b",
  "max_signals": 100,
  "risk_score": 50,
  "risk_score_mapping": [],
  "name": "Bad IP threat match",
  "references": [],
  "severity": "medium",
  "severity_mapping": [],
  "updated_by": "elastic",
  "tags": [],
  "to": "now",
  "type": "threat_match",
  "threat": [],
  "version": 1,
  "exceptions_list": [],
  "index": [
    "packetbeat-*"
  ],
  "query": "destination.ip:* or host.ip:*",
  "language": "kuery",
  "threat_query": "*:*",
  "threat_index": [
    "ip-threat-list"
  ],
  "threat_mapping": [
    {
      "entries": [
        {
          "field": "destination.ip",
          "type": "mapping",
          "value": "destination.ip"
        },
        {
          "field": "destination.port",
          "type": "mapping",
          "value": "destination.port"
        }
      ]
    },
    {
      "entries": [
        {
          "field": "source.ip",
          "type": "mapping",
          "value": "host.ip"
        }
      ]
    }
  ],
  "related_integrations": [
    { "package": "o365", "version": "^2.3.2" }
  ],
  "required_fields": [
    { "name": "destination.ip", "type": "ip", "ecs": true },
    { "name": "destination.port", "type": "long", "ecs": true },
    { "name": "host.ip", "type": "ip", "ecs": true }
  ],
  "setup": ""
}

Example response for a new terms rule:

{
  "author": [],
  "created_at": "2020-10-06T07:07:58.227Z",
  "updated_at": "2020-10-06T07:07:58.237Z",
  "created_by": "elastic",
  "description": "Detects a user associated with a new IP address",
  "enabled": true,
  "false_positives": [],
  "from": "now-6m",
  "id": "eb7225c0-566b-11ee-8b4f-bbf3afdeb9f4",
  "immutable": false,
  "interval": "5m",
  "rule_id": "c6f5d0bc-7be9-47d4-b2f3-073d22641e30",
  "max_signals": 100,
  "risk_score": 21,
  "risk_score_mapping": [],
  "name": "New User IP Detected",
  "references": [],
  "severity": "medium",
  "severity_mapping": [],
  "updated_by": "elastic",
  "tags": [],
  "to": "now",
  "type": "new_terms",
  "threat": [],
  "version": 1,
  "exceptions_list": [],
  "index": [
    "auditbeat*"
  ],
  "query": "*",
  "language": "kuery",
  "new_terms_fields": ["user.id", "source.ip"],
  "history_window_start": "now-30d",
  "related_integrations": [
    { "package": "o365", "version": "^2.3.2" }
  ],
  "required_fields": [
    { "name": "user.id", "type": "keyword", "ecs": true },
    { "name": "source.ip", "type": "ip", "ecs": true }
  ],
  "setup": ""
}

Example response for an ES|QL rule:

{
  "name": "Find Excel events",
  "description": "Find Excel events",
  "risk_score": 21,
  "severity": "low",
  "output_index": "",
  "tags": [],
  "interval": "5m",
  "enabled": false,
  "author": [],
  "false_positives": [],
  "from": "now-360s",
  "max_signals": 100,
  "risk_score_mapping": [],
  "severity_mapping": [],
  "threat": [],
  "to": "now",
  "references": [],
  "version": 1,
  "exceptions_list": [],
  "actions": [],
  "id": "d0f20490-6da4-11ee-b85e-09e9b661f2e2",
  "updated_at": "2023-10-18T10:55:14.269Z",
  "updated_by": "elastic",
  "created_at": "2023-10-18T10:55:14.269Z",
  "created_by": "elastic",
  "revision": 0,
  "rule_id": "e4b53a89-debd-4a0d-a3e3-20606952e589",
  "immutable": false,
  "related_integrations": [
    { "package": "o365", "version": "^2.3.2" }
  ],
  "required_fields": [
    { "name": "process.parent.name", "type": "keyword", "ecs": true }
  ],
  "setup": "",
  "type": "esql",
  "language": "esql",
  "query": "from auditbeat-8.10.2 METADATA _id | where process.parent.name == \"EXCEL.EXE\""
}