Bulk rule actions

edit

You can bulk create, update, and delete rules.


Bulk create

edit

This API has been deprecated since version 8.2, and is scheduled for end of life in 2024. Please use the bulk action API instead.

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 new rules.

Request URL
edit

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

Request body
edit

A JSON array of rules, where each rule contains the required fields.

Example request
edit
POST api/detection_engine/rules/_bulk_create
[
  {
    "rule_id": "process_started_by_ms_office_program_possible_payload",
    "risk_score": 50,
    "description": "Process started by MS Office program - possible payload",
    "interval": "5m",
    "name": "MS Office child process",
    "severity": "low",
    "tags": [
     "child process",
     "ms office"
     ],
    "type": "query",
    "from": "now-6m",
    "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
  },
  {
    "name": "Second bulk rule",
    "description": "Query with a rule_id for referencing an external id",
    "rule_id": "query-rule-id-2",
    "risk_score": 2,
    "severity": "low",
    "type": "query",
    "from": "now-6m",
    "query": "user.name: root or user.name: admin"
  }
]
Response code
edit
200
Indicates a successful call.
Response payload
edit

A JSON array that includes a unique ID for each rule. A unique rule ID is generated for all rules that did not include a rule_id field.


Bulk delete

edit

This API has been deprecated since version 8.2, and is scheduled for end of life in 2024. Please use the bulk action API instead.

Deletes multiple rules.

Request URL
edit

DELETE <kibana host>:<port>/api/detection_engine/rules/_bulk_delete

Request body
edit

A JSON array of id or rule_id fields of the rules you want to delete.

Example request
edit
DELETE api/detection_engine/rules/_bulk_delete
[
  {
    "rule_id": "process_started_by_ms_office_program_possible_payload"
  },
  {
    "id": "51658332-a15e-4c9e-912a-67214e2e2359"
  }
]
Response code
edit
200
Indicates a successful call.
Response payload
edit

A JSON array containing the deleted rules.


Bulk update

edit

This API has been deprecated since version 8.2, and is scheduled for end of life in 2024. Please use the bulk action API instead.

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.

Updates multiple rules.

You can use PUT or PATCH methods to bulk update rules, where:

  • PUT replaces the original rule and deletes fields that are not specified.
  • PATCH updates the specified fields.
Request URL
edit

PUT <kibana host>:<port>/api/detection_engine/rules/_bulk_update

PATCH <kibana host>:<port>/api/detection_engine/rules/_bulk_update

Request body
edit

A JSON array where each element includes:

  • The id or rule_id field of the rule you want to update.
  • The fields you want to modify.

If you call PUT to update rules, all unspecified fields are deleted. You cannot modify the id or rule_id values.

For PATCH calls, any of the fields can be modified. For PUT calls, some fields are required (see Update rule for a list of required fields).

Example request
edit
PATCH api/detection_engine/rules/_bulk_update
[
  {
    "threat": [
     {
        "framework": "MITRE ATT&CK",
        "tactic": {
           "id": "TA0001",
           "reference": "https://attack.mitre.org/tactics/TA0001",
           "name": "Initial Access"
        },
        "technique": [
           {
              "id": "T1193",
              "name": "Spearphishing Attachment",
              "reference": "https://attack.mitre.org/techniques/T1193"
           }
        ]
     }
   ],
    "rule_id": "process_started_by_ms_office_program_possible_payload"
  },
  {
    "name": "New name",
    "id": "56b22b65-173e-4a5b-b27a-82599cb1433e"
  }
]
Response code
edit
200
Indicates a successful call.
Response payload
edit

A JSON array containing the updated rules.


Bulk action

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.

Applies a bulk action to multiple rules. The bulk action is applied to all rules that match the filter or to the list of rules by their IDs.

Request URL
edit

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

URL query parameters
edit
Name Type Description Required

dry_run

Boolean

Enables dry run mode for the request call.

No

Request body
edit

A JSON object with the following properties:

Name Type Description Required

query

String

A KQL search query to match the rules.

No

ids

String[]

Array of rule IDs to which a bulk action will be applied. Only valid when query property is undefined.

No

action

Enum

A bulk action to apply.

Possible values:

  • enable
  • disable
  • delete
  • duplicate
  • export
  • edit

Yes

edit

BulkEditAction[]

Edit object that describes applying an update action.

No.

Yes, if action is edit.

Dry run mode

edit

Enable dry run mode to verify that bulk actions can be applied to specified rules. Certain rules, such as prebuilt Elastic rules, can’t be edited and will return errors in the request response. Error details will contain an explanation, the rule name and/or ID, and additional troubleshooting information.

To enable dry run mode on a request, add the query parameter dry_run=true to the end of the request URL. Rules specified in the request will be temporarily updated. These updates won’t be written to Elasticsearch.

Dry run mode is not supported for the export bulk action. A 400 error will be returned in the request response.

BulkEditAction object

edit
  • type field: enum. Defines what will be updated in rules.
  • value field: any. value which will be applied in edit action.
Possible BulkEditAction object values
edit
type field value field Description

add_tags

String[]

Add tags to rules

delete_tags

String[]

Delete rules' tags

set_tags

String[]

Overwrite rules' tags

add_index_patterns

String[]

Add index patterns to rules

delete_index_patterns

String[]

Delete rules' index patterns

set_index_patterns

String[]

Overwrite rules' index patterns

set_timeline

{ timeline_id: String; timeline_title: String }

Overwrite rules' Timeline template

set_schedule

{ interval: String; lookback: String }

Overwrite rules' schedule

interval: Frequency of rule execution. For example, "1h" means the rule runs every hour.

lookback: Additional look-back time that the rule analyzes. For example, "10m" means the rule analyzes the last 10 minutes of data in addition to the frequency interval.

If interval is set to "10m" and lookback to "1m", then the rule runs every 5 minutes but analyzes the documents added to indices during the last 11 minutes.

Both interval and lookback have a format of "{integer}{time_unit}", where accepted time units are s for seconds, m for minutes, and h for hours. The integer must be positive and larger than 0. Examples: "45s", "30m", "6h"

add_rule_actions

{ actions: actions[] , throttle: throttle }

Add actions to rules

set_rule_actions

{ actions: actions[] , throttle: throttle }

Overwrite rules' existing actions

Actions are shown in order of oldest to newest in the edit array payload’s property.

actions schema
edit

These fields are required when calling PUT to modify the actions object:

Name Type Description

action_type_id

String

The action type used for sending notifications, can be:

  • .slack
  • .email
  • .pagerduty
  • .webhook

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.
throttle schema
edit

throttle defines the maximum interval in which a rule’s actions are executed. It accepts the following values:

  • "rule": Execute actions on each rule execution
  • "1h": Execute actions once per hour
  • "1d": Execute actions once per day
  • "7d": Execute actions once per week
Example requests
edit

Example 1

The following request activates all rules with the test tag:

POST api/detection_engine/rules/_bulk_action
{
  "query": "alert.attributes.tags: \"test\"",
  "action": "enable"
}
Response code
edit
200
Indicates a successful call.
Response payload
edit

For enable, disable, delete, edit, and duplicate actions, a JSON object containing the action’s outcome: number of failed and successful outcomes, number of rules, and number of rule objects created, deleted or updated (depending on the action).

{
   "success":true,
   "rules_count": 1,
   "attributes":{
      "results":{
         "updated":[
            {
               "id":"8bc7dad0-9320-11ec-9265-8b772383a08d",
               "updated_at":"2022-02-21T17:05:50.883Z",
               "updated_by":"elastic",
               "created_at":"2022-02-21T14:14:13.801Z",
               "created_by":"elastic",
               "name":"DNS Tunneling [Duplicate]",
               "tags":[
                  "Elastic",
                  "Network",
                  "Threat Detection",
                  "ML"
               ],
               "interval":"15m",
               "enabled":true,
               "description":"A machine learning job detected unusually large numbers of DNS queries for a single top-level DNS domain, which is often used for DNS tunneling. DNS tunneling can be used for command-and-control, persistence, or data exfiltration activity. For example, dnscat tends to generate many DNS questions for a top-level domain as it uses the DNS protocol to tunnel data.",
               "risk_score":21,
               "severity":"low",
               "license":"Elastic License v2",
               "author":[
                  "Elastic"
               ],
               "false_positives":[
                  "DNS domains that use large numbers of child domains, such as software or content distribution networks, can trigger this alert and such parent domains can be excluded."
               ],
               "from":"now-45m",
               "rule_id":"7289bf08-4e91-4c70-bf01-e04c4c5d7756",
               "max_signals":100,
               "risk_score_mapping":[

               ],
               "severity_mapping":[

               ],
               "threat":[

               ],
               "to":"now",
               "references":[
                  "https://www.elastic.co/guide/en/security/current/prebuilt-ml-jobs.html"
               ],
               "version":6,
               "exceptions_list":[

               ],
               "immutable":false,
               "related_integrations": [],       
               "required_fields": [],            
               "setup": "",                      
               "type":"machine_learning",
               "anomaly_threshold":50,
               "machine_learning_job_id":[
                  "packetbeat_dns_tunneling"
               ],
               "throttle":"no_actions",
               "actions":[

               ],
               "execution_summary": {                 
                 "last_execution": {
                   "date": "2022-03-23T16:06:12.787Z",
                   "status": "partial failure",
                   "status_order": 20,
                   "message": "This rule attempted to query data from Elasticsearch indices listed in the \"Index pattern\" section of the rule definition, but no matching index was found.",
                   "metrics": {
                       "total_search_duration_ms": 135,
                       "total_indexing_duration_ms": 15,
                       "execution_gap_duration_s": 0,
                   }
                 }
               }
            }
         ],
         "created":[

         ],
         "deleted":[

         ]
      },
      "summary":{
         "failed":0,
         "succeeded":1,
         "total":1
      }
   }
}

[dev] This functionality is in development and may be changed or removed completely in a future release. These features are unsupported and not subject to the support SLA of official GA features. These fields are under development and their usage or schema may change: related_integrations, required_fields, setup, and execution_summary.

For an export action, an .ndjson file containing exported rules.

Example 2, Partial failure

The following request adds tags tag-1 and tag-2 to the rules that have the IDs sent in the payload:

POST api/detection_engine/rules/_bulk_action
{
  "ids":[
    "8bc7dad0-9320-11ec-9265-8b772383a08d",
    "8e5c1a40-9320-11ec-9265-8b772383a08d",
  ],
  "action": "edit",
  "edit": [{ action: "add_tags", value:["tag-1", "tag-2"] }]
}
Response code
edit
500
Indicates partial bulk action failure.
Response payload
edit

If processing of any rule fails, a partial error outputs the ID and/or name of the affected rule and the corresponding error, as well as successfully processed rules (in the same format as a successful 200 request).

Example payload

edit
{
    "message": "Bulk edit partially failed",
    "status_code": 500,
    "attributes": {
        "errors": [
            {
                "message": "Index patterns can't be added. Machine learning rule doesn't have index patterns property",
                "status_code": 500,
                "rules": [
                    {
                        "id": "8bc7dad0-9320-11ec-9265-8b772383a08d",
                        "name": "DNS Tunneling [Duplicate]"
                    }
                ]
            }
        ],
        "results": {
            "updated": [
                {
                    "id": "8e5c1a40-9320-11ec-9265-8b772383a08d",
                    "updated_at": "2022-02-21T16:56:22.818Z",
                    "updated_by": "elastic",
                    "created_at": "2022-02-21T14:14:17.883Z",
                    "created_by": "elastic",
                    "name": "External Alerts [Duplicate]",
                    "tags": [
                        "Elastic",
                        "Network",
                        "Windows",
                        "APM",
                        "macOS",
                        "Linux"
                    ],
                    "interval": "5m",
                    "enabled": true,
                    "description": "Generates a detection alert for each external alert written to the configured indices. Enabling this rule allows you to immediately begin investigating external alerts in the app.",
                    "risk_score": 47,
                    "severity": "medium",
                    "license": "Elastic License v2",
                    "rule_name_override": "message",
                    "timestamp_override": "event.ingested",
                    "author": [
                        "Elastic"
                    ],
                    "false_positives": [],
                    "from": "now-6m",
                    "rule_id": "941faf98-0cdc-4569-b16d-4af962914d61",
                    "max_signals": 10000,
                    "risk_score_mapping": [
                        {
                            "field": "event.risk_score",
                            "value": "",
                            "operator": "equals"
                        }
                    ],
                    "severity_mapping": [
                        {
                            "severity": "low",
                            "field": "event.severity",
                            "value": "21",
                            "operator": "equals"
                        },
                        {
                            "severity": "medium",
                            "field": "event.severity",
                            "value": "47",
                            "operator": "equals"
                        },
                        {
                            "severity": "high",
                            "field": "event.severity",
                            "value": "73",
                            "operator": "equals"
                        },
                        {
                            "severity": "critical",
                            "field": "event.severity",
                            "value": "99",
                            "operator": "equals"
                        }
                    ],
                    "threat": [],
                    "to": "now",
                    "references": [],
                    "version": 5,
                    "exceptions_list": [],
                    "immutable": false,
                    "related_integrations": [],       
                    "required_fields": [],            
                    "setup": "",                      
                    "type": "query",
                    "language": "kuery",
                    "index": [
                        "apm-*-transaction*",
                        "traces-apm*",
                        "auditbeat-*",
                        "filebeat-*",
                        "logs-*",
                        "packetbeat-*",
                        "winlogbeat-*",
                        "added-by-id-*"
                    ],
                    "query": "event.kind:alert and not event.module:(endgame or endpoint)\n",
                    "throttle": "no_actions",
                    "actions": [],
                    "execution_summary": {                 
                    "last_execution": {
                      "date": "2022-03-23T16:06:12.787Z",
                      "status": "partial failure",
                      "status_order": 20,
                      "message": "This rule attempted to query data from Elasticsearch indices listed in the \"Index pattern\" section of the rule definition, but no matching index was found.",
                      "metrics": {
                          "total_search_duration_ms": 135,
                          "total_indexing_duration_ms": 15,
                          "execution_gap_duration_s": 0,
                      }
                    }
                  }
                }
            ],
            "created": [],
            "deleted": []
        },
        "summary": {
            "failed": 1,
            "succeeded": 1,
            "total": 2
        }
    }
}

[dev] This functionality is in development and may be changed or removed completely in a future release. These features are unsupported and not subject to the support SLA of official GA features. These fields are under development and their usage or schema may change: related_integrations, required_fields, setup, and execution_summary.

Example 3, Dry run

The following request will validate that the add_index_patterns bulk action can be successfully applied to three rules. Each rule (specified by its rule ID) is different: one is a prebuilt Elastic rule, another is a custom machine learning rule, and another is a custom query rule. Because dry run mode is enabled, changes to these rules will not be permanent or saved to Elasticsearch.

POST api/detection_engine/rules/_bulk_action?dry_run=true
{
    "action": "edit",
    "edit": [
        {
            "value": [
                "test-*"
            ],
            "type": "add_index_patterns"
        }
    ],
    "ids": ["81aa0480-06af-11ed-94fb-dd1a0597d8d2", "dc015d10-0831-11ed-ac8b-05a222bd8d4a", "de8f5af0-0831-11ed-ac8b-05a222bd8d4a"]
}
Response code
edit
500
Indicates a partial bulk action failure.
Response payload
edit

The attributes.errors section of the response shows that two rules failed to update and one succeeded. The same results would be returned if you ran the request without dry run mode enabled. Notice that there are no arrays in attributes.results. In dry run mode, rule updates are not applied and saved to Elasticsearch, so the endpoint wouldn’t return results for rules that have been updated, created, or deleted.

Response body
edit
{
    "message": "Bulk edit partially failed",
    "status_code": 500,
    "attributes": {
        "errors": [
            {
                "message": "Elastic rule can't be edited",
                "status_code": 500,
                "err_code": "IMMUTABLE",
                "rules": [
                    {
                        "id": "81aa0480-06af-11ed-94fb-dd1a0597d8d2",
                        "name": "Unusual AWS Command for a User"
                    }
                ]
            },
            {
                "message": "Machine learning rule doesn't have index patterns",
                "status_code": 500,
                "err_code": "MACHINE_LEARNING_INDEX_PATTERN",
                "rules": [
                    {
                        "id": "dc015d10-0831-11ed-ac8b-05a222bd8d4a",
                        "name": "Suspicious Powershell Script [Duplicate]"
                    }
                ]
            }
        ],
        "results": {
            "updated": [],
            "created": [],
            "deleted": []
        },
        "summary": {
            "failed": 2,
            "succeeded": 1,
            "total": 3
        }
    }
}