Creating alert templates

Community Platform

With the Rules Engine, you can define rules that alert you on specific events, such as changes to scans, assets, and Explorers. To customize the alert messages, you can create custom templates to standardize and format alerts triggered from rules. With custom templates, you can include more context and data for your alerts.

Templates can output in HTML, JSON, and text for use in emails, internal notifications, or webhooks. You can customize the contents of these templates as needed.

Template building basics

You can define the contents of an alert message using the Mustache templating language. As long as you know a little bit about how the Mustache syntax works, you can build custom HTML and JSON templates to reference and pull in runZero data.

  • For Slack notifications, you can use Slack’s Block Kit and their interactive Block Kit Builder to construct a rich message in JSON format, and then use Mustache to insert the relevant data.

  • For Microsoft Teams, you can use the Adaptive Cards format to build rich messages, and again insert data via Mustache.

Our templates have two fields for template data: subject and body. Both subject and body can be customized using the Mustache syntax.

Inserting a data in a template

A standard set of objects is passed to the {{template engine}}, you just have to indicate the fields from the objects you want to insert into your template. Use the Mustache template syntax, {{variable}}, to include alert values when a rule matches certain conditions.

For HTML and JSON templates, values inserted using {{ }} are automatically escaped according to the appropriate rules. To avoid escaping a particular value, use triple curly braces, like this: {{{task.name}}}.

For JSON templates, the special self variable {{.}} will output all available variables and their values as JSON. Similarly, outputing an object such as {{event}} will output the object with all of its attributes as JSON.

Inserting a value

To insert a value, put the variable name in double curly brackets, like this {{variablename}}.

The following example shows how to insert the console address:

The runZero Console is at {{console}}.

Inserting a value from an object

To insert a value from a specific object, separate the object name and field name with a dot, like this {{object.fieldname}}.

The following example shows how to insert the organization name:

The organization name is {{organization.name}}.

Inserting multiple values from an object

To insert multiple values from an object easily, use a section. You will need to start the section with {{#objectname}} and close it with a matching {{/objectname}} The following example shows how to insert the results from a scan that include total assets and number of assets changed:

Here are the results:
{{#scan}}
Scan found {{assets_total}} assets and changed {{assets_changed}} of them.
{{/scan}}

What happens if a field contains multiple values?

If a section refers to a field which contains multiple values, the template engine will loop through the values in the field, processing the section inside for each individual value.

The following example loops through all of the assets in report.new, and for each one, outputs its names and addresses fields. If there is nothing stored in report.new, the section between the tags will not be rendered.

{{#report.new}}
{{names}} {{addresses}}
{{/report.new}}

Note that within a loop, you can still refer to values from the outer object. If a named value isn’t found in the current loop object, the template engine will check the outer object. For example, this can be useful for referring to the {{console}} variable, which provides the root runZero console URL.

Using boolean values

You can use boolean values with the {{#field}}{{/field}} tags. If the value of the field is false, the section between the tags is not rendered.

For example:

{{#query.truncated}}
(Additional results were found but not included in this report)
{{/query.truncated}}

Objects and fields reference

To include runZero data and details in your alerts, you can build your template using the following objects and fields.

globals

Field Contents Example
console The base URL of the runZero web console. https://console.runzero.com

event

The following fields are available in the event object:

Field Contents Example
action The action which triggered the event task-completed
created_at When the event was created 2021-04-02 12:50:26 -0500
id The UUID of the event b4b871db-bdf1-4a42-b82d-18ae99972228
source_name Name of the thing which caused the event Weekly security scan
source_type Type of thing which caused the event task
success Whether the event succeeded true
target_name Name of the object targeted by the event Head Office
target_type The type of the object targeted by the event site

task

For events triggered by a task, the following fields are available in the task object:

Field Contents Example
created_at When the task was created 2021-04-02 12:50:26 -0500
created_by The user who created the task user@example.com
description The description of the task Weekly scan of main network
error The text of any error message for the task explorer unavailable after 4h
id The UUID of the task b4b871db-bdf1-4a42-b82d-18ae99972228
name The name of the task Weekly Scan
start_time When the task started 2021-04-02 12:50:26 -0500
status The status of the task processed
type The type of task scan
updated_at When the task was last updated 2021-04-02 12:50:26 -0500
url A URL linking to the task details

organization

The following fields are available in the organization object:

Field Contents Example
id The UUID of the organization 86f12ee1-f0f1-419a-8799-63fff555777a
name The name of the organization IT Dept.

site

The following fields are available in the site object:

Field Contents Example
id The UUID of the site 49f9323a-fea1-4afc-b490-2414c3aaaeee
name The name of the site Head Office

rule

The following fields are available in the rule object:

Field Contents Example
action The action the rule said to take notify
created_at When the rule was created 2021-03-08 12:43:59 -0600
created_by The user who created the rule user@example.com
event The event triggering the rule scan-completed
id The UUID of the rule b2269a2c-69a1-4652-bcdf-899938886c17
name The name of the Rule Alert on scan
updated_at When the rule was last updated 2021-04-01 17:09:40 -0500

scan

For events triggered by a scan task, the following additional fields are available in a scan object:

Field Contents Example
explorer_id The UUID of the runZero Explorer which carried out the scan 0fd44a62-d827-41c0-b26c-4837222d8888
assets_changed The number of assets changed as a result of the scan 9
assets_ignored The number of assets ignored by the scan 2
assets_new The number of new assets detected by the scan 2
assets_offline The number of assets which were previously online but now offline 1
assets_online The number of assets previously offline but now online again 2
assets_total The total number of assets for the site scanned (including offline) 11
assets_unchanged The number of assets unchanged by the scan 1
assets_updated The total number of assets up-to-date as a result of the scan (changed + unchanged) 15
duration Duration of the scan in seconds 26
end_time When the scan ended 2021-04-02 12:50:26 -0500
excludes Any IP addresses excluded from the scan 10.0.1.123
id The UUID of the scan task 894a112c-3fb9-4301-8da7-8ce7fffb4443
name The name of the scan task Weekly security scan
rate The scan rate 1000
recv_bytes How many bytes were received during the scan 45176
recv_error How many receive errors were detected 1
recv_packets How many data packets were received during the scan 555
scheduled_time When the scan was scheduled to run 2021-04-02 12:48:00 -0500
sent_bytes How many bytes were sent during the scan 44740
sent_error How many send errors were detected 0
sent_packets How many data packets were sent during the scan 577
start_time When the scan actually started 2021-04-02 12:49:55 -0500
tags An array of tags associated with the scan task
targets The CIDR address ranges scanned 10.0.1.0/24
type The type of operation scan

explorer

For events triggered by a scan task, the following additional fields are available in an explorer object (runZero 2.1.8+):

Field Contents Example
id The UUID of the runZero Explorer which carried out the scan 0fd44a62-d827-41c0-b26c-4837222d8888
name The name of the Explorer which carried out the scan MM34B-2
internal_ip The internal IP address of the Explorer which carried out the scan 10.0.1.200

For events triggered by a search query rule, the following additional fields are available in a search object:

Field Contents Example
url A link to perform the same search https://console.runzero.com/inventory/?search=…
found The number of matches found 3
comparator The operation used to compare the number of matches >=
value The value the number of matches was compared against 1

report

For “scan completed” events, a report object contains the following results from the scan:

Field Contents
truncated Whether the set of objects was truncated due to large numbers of assets
changed An array of changed assets (see below)
new An array of new assets (see below)
offline An array of assets now offline (see below)
online An array of assets now online (see below)

The limit on the number of objects passed to the template is 25 for email notifications, 10 for Webhook notifications.

asset (from a scan report)

Each asset returned as part of a scan report has the following fields:

Field Contents
addresses The IP address(es) of the asset 10.0.1.123
alive Whether the asset responded to probes true
created_at The timestamp when the asset record was created 2021-04-02 12:50:26 -0500
criticality_rank The criticality rank from (0-5) 1
detected_by The method by which the asset was detected arp
domains Any domains the asset was found in WORKGROUP
first_seen The timestamp when the asset was first seen 2021-04-02 12:50:26 -0500
hw A summary of the asset hardware HP LaserJet Pro
id The UUID of the asset b38295fb-bef1-fa42-b82d-18ae99972228
last_seen The timestamp when the asset was most recently seen 2021-04-02 12:50:26 -0500
macs Any MAC addresses detected for the asset 00:56:55:00:91:04
modified_risk_rank The risk rank after applying user overrides 2
names Any names detected for the asset LP538N
os A summary of the asset’s operating system Linux
outlier_score The normalized outlier score (0-5) 2
risk_rank The normalized risk rank (0-4) 4
service_count How many services the asset is running 4
software_count How many software entries were identified on the asset 10
type The type of asset Router
updated_at The timestamp when the asset record was last updated 2021-04-02 12:50:26 -0500
vulnerability_count How many vulnerabilies were identified on the asset 4

query

For query events, the following data is provided in the query variable:

Field Contents
count The number of rows matching the search query
assets If it was an asset search, the array of assets matching the query
services If it was a service search, the array of services matching the query
wlans If it was a wireless network search, the array of wireless networks matching the query
truncated Whether the set of assets was truncated due to the query returning a large number

The limit on the number of assets passed to the template from a query is 25 for email notifications, 10 for Webhook notifications.

asset (from a query)

For assets returned from a query rule, the following fields are available:

Field Contents
addresses The IP address(es) of the asset 10.0.1.123
alive Whether the asset responded to probes true
comments Any comments set in the asset record
created_at The timestamp when the asset record was created 2021-04-02 12:50:26 -0500
detected_by The method by which the asset was detected arp
domains Any domains the asset was found in WORKGROUP
first_seen The timestamp when the asset was first seen 2021-04-02 12:50:26 -0500
hw A summary of the asset hardware ThinkPad X1
id The UUID of the asset b38295fb-bef1-fa42-b82d-18ae99972228
last_seen The timestamp when the asset was most recently seen 2021-04-02 12:50:26 -0500
macs The list of MAC addresses associated with the asset [F4:F5:E8:89:92:31, 00:D0:2D:9F:47:77]
names Any names detected for the asset laptop.local
organization The organization the asset belongs to IT
os A summary of the asset’s operating system Windows 10
service_count How many services the asset is running 4
site The site the asset was detected at New York
tags An array of tags set on the asset
type The type of asset Thermostat
updated_at The timestamp when the asset record was last updated 2021-04-02 12:50:26 -0500

service (from a query)

For services returned from a query rule, the following fields are available, some of which are taken from the associated asset:

Field Contents Example
id The UUID of the service (not the asset) b38efadb-61f1-f332-b92d-18ae99972228
created_at When the service record was created 2021-04-02 12:50:26 -0500
summary A summary of the service ciscoSystems
port The TCP/UDP port the service is on 53
vhost The vhost of the service ftp.example.com
address The TCP/IP address of the service 192.168.33.44
transport The transport udp
protocol The name of the protocol, if known ssh
organization The name of the organization the service’s asset belongs to HR
site The name of the site the service’s asset belongs to Lab
alive Whether the asset offering the service was alive true
last_seen When the asset was last seen 2021-04-02 12:50:26 -0500
first_seen When the asset was first seen 2021-02-11 09:38:17 -0500
type The asset type offering the service Laptop
os The OS offering the service Linux
hw The hardware offering the service APC UPS
addresses A list of other IP addresses associated with the asset offering the service [192.168.0.2, 192.168.0.3]
macs The list of MAC addresses associated with the asset [F4:F5:E8:89:92:31, 00:D0:2D:9F:47:77]
names Any names associated with the asset [fw-3, fw-3a]
tags Tags set on the asset
domains Any domain associated with the asset LOCAL
service_count A count of how many services the asset offers 4
comments Any comments set on the asset

wlan (wireless LAN, from a query)

For wireless lans (wlans) returned from a query rule, the following fields are available:

Field Contents Example
id The UUID of the wireless LAN in runZero’s database f938934b-ae23-f112-b23d-18ae99972228
last_seen When the wlan was last seen 2021-04-02 12:50:26 -0500
essid The ESSID of the network Free WiFi
bssid The ESSID of the network c4:41:1e:99:88:77
type The type of wireless network infrastructure
authentication The authentication used to access the network WPA2-PSK
encryption The encryption used to protect data AES
signal The signal strength as a percentage 86
channels The channel of the network 11
organization The name of the organization the service’s asset belongs to HR
site The name of the site the service’s asset belongs to Lab

Example: Alert when scan completes

Let’s take an example of something you might want to get alerted on: completed scans. We can create a rule that emails us when a scan completes, and provides us with some details, such as the number of new, online, offline, and modified assets. We’ll build these details into our template.

Step 1. Create a template.

You can create a template from the Alerts page.

  • Name the template something like Email the team when a scan completes.
  • For the template type, choose HTML, since we want to use this template for emails.
  • For the subject line, enter something that’s descriptive, like runZero scan {{scan.name}} completed at {{scan.end_time}}. You can use the Mustache syntax for the subject.

Step 2. Create the body message

Now, let’s create the email body. We want the email to tell us how many new, online, offline, and modified assets there are, as well as give us details on the new assets discovered.

The body looks like this:

<h1>{{site.name}}</h1>

<h2>Scan Results</h2>
{{#scan}}
<ul>
<li>{{assets_new}} new assets</li>
<li>{{assets_online}} online assets</li>
<li>{{assets_offline}} offline assets</li>
<li>{{assets_changed}} modified assets</li>
</ul>
{{/scan}}

<h2>New assets</h2>
<ul>
{{#report.new}}
<li>{{names}} {{addresses}} {{os}}</li>
{{/report.new}}
{{^report.new}}
<li>No new assets were discovered.</li>
{{/report.new}}
</ul>

<p><a href="{{task.url}}">View the scan results</a></p>

See that caret (^)? It represents inverted sections. These sections only render when the list is empty or the value is empty or false.

Step 3. Save the template and create a rule

The template is now available for you to choose when you create a rule.

Sample JSON templates

A JSON array of new assets found by a scan

[
  {{#report.new}}
    {
      "addresses": "{{addresses}}",
      "alive": "{{alive}}",
      "detected_by": "{{detected_by}}",
      "domains": "{{domains}}",
      "first_seen": "{{first_seen}}",
      "hw": "{{hw}}",
      "names": "{{names}}",
      "os": "{{os}}",
      "type": "{{type}}"
    },
  {{/report.new}}
  null
]

The trailing null in the array is so that the array is valid JSON, because JSON doesn’t allow trailing commas.

All available attributes

Output all available variables and their attributes as a JSON object:

{{.}}

Alternatively, you can build your own JSON array with all attributes:

{
  "event": {
    "action": "{{event.action}}",
    "created_at": "{{event.created_at}}",
    "id": "{{event.id}}",
    "source_name": "{{sevent.ource_name}}",
    "source_type": "{{event.source_type}}",
    "success": "{{event.success}}",
    "target_name": "{{event.target_name}}",
    "target_type": "{{tevent.arget_type}}"
  },
  "organization": {
    "name": "{{organization.name}}",
    "id": "{{organization.id}}"
  },
  "site": {
    "name": "{{site.name}}",
    "id": "{{site.id}}"
  },
  "report": {
    "truncated": "{{report.truncated}}",
    "changed": "{{report.changed}}",
    "new": "{{report.new}}",
    "offline": "{{report.offline}}",
    "online": "{{report.online}}"
  },
  "rule": {
    "action": "{{rule.action}}",
    "created_at": "{{rule.created_at}}",
    "created_by": "{{rule.created_by}}",
    "event": "{{rule.event}}",
    "id": "{{rule.id}}",
    "name": "{{rule.name}}",
    "updated_at": "{{rule.updated_at}}"
  },
  "scan": {
    "explorer_id": "{{scan.explorer_id}}",
    "assets_changed": "{{scan.assets_changed}}",
    "assets_ignored": "{{scan.assets_ignored}}",
    "assets_new": "{{scan.assets_new}}",
    "assets_offline": "{{assets_offline}}",
    "assets_online": "{{scan.assets_online}}",
    "assets_total": "{{scan.assets_total}}",
    "assets_unchanged": "{{scan.assets_unchanged}}",
    "assets_updated": "{{scan.assets_updated}}",
    "duration": "{{scan.duration}}",
    "end_time": "{{scan.end_time}}",
    "excludes": "{{scan.excludes}}",
    "id": "{{scan.id}}",
    "name": "{{scan.name}}",
    "rate": "{{scan.rate}}",
    "recv_bytes": "{{scan.recv_bytes}}",
    "recv_error": "{{scan.recv_error}}",
    "recv_packets": "{{scan.recv_packets}}",
    "scheduled_time": "{{scan.scheduled_time}}",
    "sent_bytes": "{{scan.sent_bytes}}",
    "sent_error": "{{scan.sent_error}}",
    "sent_packets": "{{scan.sent_packets}}",
    "start_time": "{{scan.start_time}}",
    "tags": "{{scan.tags}}",
    "targets": "{{scan.targets}}",
    "type": "{{scan.type}}"
  },
  "explorer": {
    "id": "{{explorer.id}}",
    "name": "{{explorer.name}}",
    "internal_ip": "{{explorer.internal_ip}}"
  },
  "search": {
    "url": "{{search.url}}",
    "found": "{{search.found}}",
    "comparator": "{{search.comparator}}",
    "value": "{{search.value}}"
  },
  "query": {
    "count": "{{query.count}}",
    "assets": "{{query.assets}}",
    "services": "{{query.services}}",
    "wlans": "{{query.wlans}}",
    "truncated": "{{query.truncated}}"
  }
}

Event attributes only

{
  "event": {{event}}
}

or

{
  "action": "{{event.action}}",
  "created_at": "{{event.created_at}}",
  "id": "{{event.id}}",
  "source_name": "{{sevent.ource_name}}",
  "source_type": "{{event.source_type}}",
  "success": "{{event.success}}",
  "target_name": "{{event.target_name}}",
  "target_type": "{{tevent.arget_type}}"
}

Organization attributes only

{
  "organization": {{organization}}
}

or

{
  "name": "{{organization.action}}",
  "id": "{{organization.id}}"
}

Site attributes only

{
  "site": {{site}}
}

or

{
  "name": "{{site.action}}",
  "id": "{{site.id}}"
}

Report attributes only

{
  "report": {{report}}
}

or

{
  "truncated": "{{report.truncated}}",
  "changed": "{{report.changed}}",
  "new": "{{report.new}}",
  "offline": "{{report.offline}}",
  "online": "{{report.online}}"
}

Rule attributes only

{
  "rule": {{rule}}
}

or

{
  "action": "{{rule.action}}",
  "created_at": "{{rule.created_at}}",
  "created_by": "{{rule.created_by}}",
  "event": "{{rule.event}}",
  "id": "{{rule.id}}",
  "name": "{{rule.name}}",
  "updated_at": "{{rule.updated_at}}"
}

Scan attributes only

{
  "scan": {{scan}}
}

or

{
  "explorer_id": "{{scan.explorer_id}}",
  "assets_changed": "{{scan.assets_changed}}",
  "assets_ignored": "{{scan.assets_ignored}}",
  "assets_new": "{{scan.assets_new}}",
  "assets_offline": "{{assets_offline}}",
  "assets_online": "{{scan.assets_online}}",
  "assets_total": "{{scan.assets_total}}",
  "assets_unchanged": "{{scan.assets_unchanged}}",
  "assets_updated": "{{scan.assets_updated}}",
  "duration": "{{scan.duration}}",
  "end_time": "{{scan.end_time}}",
  "excludes": "{{scan.excludes}}",
  "id": "{{scan.id}}",
  "name": "{{scan.name}}",
  "rate": "{{scan.rate}}",
  "recv_bytes": "{{scan.recv_bytes}}",
  "recv_error": "{{scan.recv_error}}",
  "recv_packets": "{{scan.recv_packets}}",
  "scheduled_time": "{{scan.scheduled_time}}",
  "sent_bytes": "{{scan.sent_bytes}}",
  "sent_error": "{{scan.sent_error}}",
  "sent_packets": "{{scan.sent_packets}}",
  "start_time": "{{scan.start_time}}",
  "tags": "{{scan.tags}}",
  "targets": "{{scan.targets}}",
  "type": "{{scan.type}}"
}

Explorer attributes only

{
  "explorer": {{explorer}}
}

or

{
  "id": "{{explorer.id}}",
  "name": "{{explorer.name}}",
  "internal_ip": "{{explorer.internal_ip}}"
}

Search attributes only

{
  "search": {{search}}
}

or

{
  "url": "{{search.url}}",
  "found": "{{search.found}}",
  "comparator": "{{search.comparator}}",
  "value": "{{search.value}}"
}

Query attributes only

{
  "query": {{query}}
}

or

{
  "count": "{{query.count}}",
  "assets": "{{query.assets}}",
  "services": "{{query.services}}",
  "wlans": "{{query.wlans}}",
  "truncated": "{{query.truncated}}"
}

Asset, service, or wireless query alert to SIEM or SOAR

{
  "organization": {
    "name": "{{organization.name}}",
    "id": "{{organization.id}}"
  },
  "site": {
    "name": "{{site.name}}",
    "id": "{{site.id}}"
  },
  "rule": {
    "action": "{{rule.action}}",
    "created_at": "{{rule.created_at}}",
    "created_by": "{{rule.created_by}}",
    "event": "{{rule.event}}",
    "id": "{{rule.id}}",
    "name": "{{rule.name}}",
    "updated_at": "{{rule.updated_at}}"
  },
  "search": {
    "url": "{{search.url}}",
    "found": "{{search.found}}",
    "comparator": "{{search.comparator}}",
    "value": "{{search.value}}"
  }
}

Asset, service, or wireless query alert to Slack

{
  "blocks": [
    {
      "type": "section",
      "text": {
        "type": "mrkdwn",
        "text": ":red_circle: *runZero Alert* - {{rule.name}}"
      }
    },
    {
      "type": "divider"
    },
    {
      "type": "section",
      "text": {
        "type": "mrkdwn",
        "text": "*Rule information*\n\n_Name_: {{rule.name}}\n_Type_: {{rule.event}}\n_Link_: https://console.runzero.com/alerts/rule/{{rule.id}}"
      }
    },
    {
      "type": "section",
      "text": {
        "type": "mrkdwn",
        "text": "*Match information*\n\n_Organization_: {{organization.name}}\n_Site_: {{site.name}}\n_Match count_: {{search.found}}\n_Search_: {{search.value}}\n_Link_: https://console.runzero.com/alerts/rule/{{search.url}}"
      }
    }
  ]
}

Asset, service, or wireless query alert to Microsoft Teams

{
  "type": "message",
  "attachments": [
    {
      "contentType": "application/vnd.microsoft.card.adaptive",
      "contentUrl": null,
      "content": {
        "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
        "type": "AdaptiveCard",
        "version": "1.5",
        "body": [
          {
            "type": "TextBlock",
            "text": "runZero Alert - {{rule.name}}"
          },
          {
            "type": "TextBlock",
            "text": "**Rule information**\n\n_Name_: {{rule.name}}\n\n_Type_: {{rule.event}}\n\n_Link_: [Rule](https://console.runzero.com/alerts/rule/{{rule.id}})",
            "wrap": true
          },
          {
            "type": "TextBlock",
            "text": "**Match information**\n\n_Organization_: {{organization.name}}\n\n_Site_: {{site.name}}\n\n_Match count_: {{search.found}}\n\n_Search_: {{search.value}}\n\n_Link_: [Search](https://console.runzero.com/alerts/rule/{{search.url}})",
            "wrap": true,
            "spacing": "Medium"
          }
        ]
      }
    }
  ]
}

Data type accepted by each channel

When you create a rule, the channel you select must accept the data type used by the template. For example, if you want to send a Slack notification, the template must be in plain text or JSON.

Here are the data types accepted by each channel:

Channel Data type
Email Plain text, HTML, JSON
Webhook Plain text, JSON
Internal notification Plain text

Managing templates

Go to Alerts > Templates. From this page, you can create, edit, and delete templates. Before deleting templates, make sure they are not in use by any rules. If you delete a template that is in use by a rule, the rule will revert to the default template.

Updated