Triggers
This section describes triggers, their conditions and kinds, and use with relationships.
Triggers definition
Triggers are where the active part of patterns begin. Triggers define the conditions in which the body of the pattern are evaluated. From the point of view of pattern authors, conditions are based on data events - creation or modification of nodes in the datastore. Triggers take the form:
*on* _name_ := [*relationship*] _node_kind_ [_change_kind_ ]
[*where* _trigger_condition_]
*end triggers*;
In a simple example:
*on* process := DiscoveredProcess *where* cmd *matches* regex "Xvnc";
*end triggers*;
The name assigned to the trigger is made available as a variable in the pattern body.
Trigger "with priority"
You can add the optional "with priority" clause after the trigger so that the trigger conditions are considered ahead of others that may match. Use this functionality to ensure that a particular node is created before others so that relationships between them can be inferred. For example, you might want a Cluster node to be created before the SoftwareInstance nodes running on that Cluster.
Trigger conditions
Trigger conditions consist of a subset of the more general where clauses available in searches (described later in the section on search expressions). The only operations supported are simple attribute comparisons of the form:
and combinations of such comparisons using and and or.
The only operators available are:
= | Exact equality |
matches | Regular expression match |
exists | Attribute existence check — does not take an expression. |
To avoid "greedy" triggers that trigger on almost all data, not expressions are not permitted in triggers.
Expressions must be literal values, constants, or expressions based entirely on literal values and constants.
Trigger kind
By default, patterns only trigger when a node is created. In some circumstances, it might be necessary to only trigger when a node is modified, not when it is created. It might also be necessary to trigger if a node is superseded / destroyed.
Patterns can trigger when a node is confirmed to exist, even if it is not modified. Such a pattern triggers when a pattern confirms the existence of a node using one of the Model node assertion functions and, for Host nodes, when a Host is confirmed to exist during a scan.
Triggers can specify a comma-separated set of "change kinds". The kinds are created, confirmed, modified, and destroyed.
For example:
*on* process := SoftwareInstance *confirmed where* type *matches*
regex "Apache";
*end triggers;*
The pattern will only trigger when a matching Software Instance is confirmed to exist, not when a matching Software Instance is first created.
More than one change kind can be selected by separating them with commas. For example:
*on* process := DiscoveredProcess *created, modified where* cmd *matches* regex "Xvnc";
*end triggers;*
The default change kind is created.
When triggering on a node being modified, great care must be taken if the triggering node is modified in the pattern, since the modification inside the pattern causes the pattern to trigger again.
Relationship triggers
To trigger on relationships rather than nodes, simply use a prefix of relationship to the kind in the trigger:
// Trigger whenever a HostContainment relationship is created
*on* rel := *relationship* HostContainment;
*end triggers*;
A trigger on a relationship can of course include a where clause.
Existing data
Patterns normally only trigger when data in the datastore changes (or is confirmed by another pattern for the confirmed trigger) — if nodes matching a pattern's trigger conditions already exist at the time the pattern is activated, the pattern will not execute for those nodes. Patterns can be executed against existing nodes using Executing-patterns-manually.