The playbook trigger is a filter that allows you to select alerts or incidents for which a playbook must be launched. The filter (trigger) is applied to each object (alert or incident) individually and takes a single value: either true
or false
. A trigger consists of expressions in the jq language that processes structured data in the JSON format. For more information about jq expressions, refer to jq Manual.
In Kaspersky Next XDR Expert, gojq is used. It is an implementation of jq written in the go language, which has the following differences from jq:
For more information about the differences between gojq and jq, refer to GitHub.
How to write a trigger
You can write a trigger in the Trigger section when creating or editing a playbook.
Depending on the option you select in the Scope list when creating or editing a playbook, alert data model or incident data model is used.
The names of parameters in a playbook trigger must be the same as in the data model. Note that elements of jq expressions are case-sensitive.
To avoid overloading the system, it is not recommended to specify OriginalEvents, Observables, Extra,
and Alerts
data in the trigger.
When you start writing a trigger, the following suggestions can be displayed:
The suitable values are filtered and displayed in the list of suggestions when you start typing. For convenience, some suggestions contain a search string. For example, if you want to specify an incident type ID or incident status ID, you can search the corresponding record by the name, and the ID will be specified in the trigger.
Note that default statuses (New and Closed) have the same ID in different workflows, which means that the trigger will run for all incidents with the specified status ID. To limit the scope of incidents for which the playbook will run, in the trigger you have to specify the incident status ID and the incident type.
The jq language also provides syntax highlighting and validation of jq expressions. If the trigger has invalid expressions, you cannot save the playbook.
When writing a trigger, basic syntax rules are used.
To refer to structure properties, you must use dot ".
" and specify the attribute, for example:
.MITRETactics[]
—To view the array of MITRE tactics associated with all triggered IOA rules in the alert..MITRETactics[0]
—To view the first element from the MITRE tactics array.To refer to child properties, you can either use the pipe (|
) or the same combination without the pipe, for example:
.Assignee[0].Name
or Assignee[0] | .Name
—The expression outputs the name of the user to whom the alert is assigned..MITRETactics[0].ID
or .MITRETactics[0] | .ID
—The expression outputs the ID of the first MITRE tactic.To get a value, you have to use the following operators: ==, >, <, >=, <=, !=, for example:
.Assignee[0] | .Name == "user"
—The expression returns true
if the alert is assigned to the user.(.Serverity == "high") and (.DetectSource == "KES")
—The expression returns true
if the alert severity level is high and the source of data is Kaspersky Endpoint Security.[ .DetectionTechnologies[] | . == "IOC" ] | any
—The expression returns true
if the IOC detection technology is triggered..DetectionTechnologies | length > 1
—The expression returns true
if more than one detection technology is triggered.To enumerate values in an array of objects, you can use the any
method, for example:
[.Assets[] | .Name == "W21H2-X64-3160"] | any
—The expression filters the alert where any element of the Assets
array has the W21H2-X64-3160
value in the Name
field.[.Observables[] | .Value == "127.0.0.1"] | any
—The expression filters the alert where any element of the Observables
array has the 127.0.0.1
value in the Value
field.[.Assets[].ID]
—To output the array of IDs. [.Assets[] | select(.AttackerOrVictim=="attacker") | .ID]
—To display an array of IDs for the assets filtered by the AttackerOrVictim
field.If you want to reuse calculations, specify a variable with $
. For example, the expression event.manual != true as $not_manual | [ .DetectionTechnologies[] | . == "IOC" ] | any and $not_manual
defines and uses the $not_manual
variable that contains a flag that shows if the change is manual or not.
To work with dates, you can use the following functions:
now
—To get the current Unix time in seconds, for example, now == 1690541520.537496.
todate
—To get the current Unix time in seconds, for example, now | todate == "2023-07-28T10:47:36Z".
fromdate
—To convert the date to seconds, for example:.CreatedAt | split(".")[0] + "Z"
—This command removes milliseconds and converts the string to the 2023-07-15T07:49:51Z format.(.CreatedAt | split(".")[0] + "Z") | fromdate == 1689407391
—The conversion to seconds is finished.Jq uses iterators—an interface that provides access to elements of a collection, for example, an array, and allows you to navigate through them. Iterators are always the result of calculation. The difference is in the number of elements that the iterator contains. In Kaspersky Next XDR Expert, an iterator must have only one element; the other cases are considered an error.
To write a correct trigger, you have to wrap an iterator into square brackets ([ ... ]
). For example, the .DetectionTechnologies[] == "IOC"
trigger will cause an error because it returns an iterator with two elements. The correct trigger must have the following form: [ .DetectionTechnologies == "IOC" ] | any
, where first you have to use []
to wrap the result of the comparison into an array, and then process it with the any
method that returns true
if at least one element of the array is true
. Otherwise, false
is returned.
When the trigger runs
The search for a suitable playbook starts when one of the following triggering events occurs:
The following types of alert change events are supported:
ExternalReference
field.The following types of incident change events are supported:
ExternalReference
field.The alert/incident structure does not contain any data about the alert/incident changes. This data is transferred in additional information. If in a playbook trigger you want to refer to the changes, use the event function without arguments.
By default, manual changes to an alert or incident details are ignored. If you want a playbook to launch for manual changes, you have to use the event.manual
function in the trigger, for example:
event.manual and ([ event.updateOperations[] | . == "alertReopened" ] | any)
—The trigger works only if the alert is manually reopened.[ event.updateOperations[] | . == "alertLinkedWithIncidentBySystem" ] | any
—The trigger works only if the alert is automatically linked to an incident.event.manual != null and (([ event.updateOperations[] | . == "alertChangedToNew" ] | any) | not)
—The trigger works if the alert status is changed to any status other than New, either manually or automatically.event == null and .Status == "inIncident"
—The trigger works for all alerts with the In incident status, but only when the playbook is changed, not the alert.If necessary, you can test examples of jq expressions, apply filters, and then view the results in the Jq playground service.
Page top