Tines

View as Markdown

runZero integrates with Tines so you can automate workflows around your asset data. A video demo shows the end result of these instructions.

Requirements

  • A Tines account
  • runZero Export API and Organization API tokens

You can integrate runZero and Tines in two ways:

Tines custom story

A Tines story is a collection of actions that work together toward a goal, like a playbook. The Tines Story Library has ready-made automated playbooks; when none matches your needs, these steps show you how to build a custom story.

Step 1: Creating a Tines story and adding runZero API credentials

  1. Sign in to Tines and create a new story.
  2. Use the + in the credentials section to add a text credential.
  3. Use the + in the credentials section to add another text credential.

Step 2: Creating a Tines webhook action

  1. Add a Webhook action to your story.
  2. Click the Webhook action and copy the webhook URL, which looks like https://<tenant-name>.tines.com/webhook/<guid>.

Step 3: Creating a runZero alert template

  1. Create an alert template in runZero:
    • Name: a name for the template
    • Template type: JSON
    • Subject line for message: leave empty
    • Body of message: this JSON example includes the rule name and the search URL in the alert message body: {"rule_name":"{{rule.name}}","search_url":"{{search.url}}"}
  2. Create an alert channel in runZero:
    • Name: a name for the alert channel
    • Channel type: webhook
    • Webhook URL: the webhook URL you copied from Tines

Step 4: Creating a rule in runZero

With the template ready, pick the triggers to alert on. Common examples:

  • Asset query results: a query in runZero matches after a scan completes
  • New assets found: a scan completes with new assets
  • Agent offline: your runZero Explorer stops checking in to the console
  • Task failed: a task fails for any reason

The rest of the steps use asset query results, with any asset that has an open Telnet port (port:23) as the example. You can see more example queries; for more on rules and alerts, see Using the rules engine.

  1. Create an alert rule.
  2. Select asset-query-results and click Configure rule.
  3. Enter values for the rule:
    • Name: the name of the rule.
    • Conditions: optional parameters; the alert triggers when all conditions match.
      • Query: the query the assets must match, port:23 in this example.
      • Number of matches: the numeric comparison to apply to the value.
      • Value: the match threshold that triggers the rule.
      • Limit to organization: limits the alert to a specific organization in runZero.
      • Limit to site: limits the alert to a specific site in runZero.
      • Action: notify
        • Notification channel: the alert channel you created in step 3.
        • Notification template: the alert template you created in step 3.

Step 5: Handling the data in Tines

  1. The Webhook action you created in Step 2 is the entry point for the runZero alert in Tines.
  2. Add an Event Transform to parse the search out of the URL in the runZero alert. If you connect the Webhook action to this one, some parameters populate automatically.
    • Mode: extract
    • Matchers:
      • Path: path_to_alert_search, for example receive_alerts_from_runzero.body.search_url if your Webhook action is named “RECEIVE alerts from runZero”
      • Regex: \?.*
      • Extract to: search
  3. Add an Event Transform that takes the output of the previous step. If you connect the previous Event Transform action to this one, some parameters populate automatically.
    • Mode: explode
    • Matchers:
      • Path: path_to_extraction_transform, for example get_search_from_url.search if your previous Event Transform action is named “GET search from URL”
      • To: individual_item
  4. Add an HTTP Request that calls the runZero Export API.
    • URL: the path_to_explosion_transform appended to the runZero API endpoint URL, for example https://console.runZero.com/api/v1.0/export/org/assets.json<<get_search_from_regex.individual_item>> if your previous Event Transform action is named “GET search from regex”
    • Content Type: JSON
    • Method: get
    • Use the + Option button to add Headers:
      • Change header to Authorization
      • Change value to Bearer CREDENTIAL.runzero_export_token
  5. Add an Event Transform that takes the runZero Export API output and loops through each value.
    • Mode: explode
    • Path: path_to_HTTP_request, for example get_assets_from_runzero.body if your HTTP Request action is named “GET assets from runZero”
    • To: individual_item

Step 6: Personalized automation in Tines

With the alert received, the search parsed, and the assets fetched from the runZero Export API, it’s time to add your own flair. The sample story includes these two actions as examples, though you will likely want something more tailored.

  1. Send an email to the destination of your choice for each asset. The sample JSON shows how to put the context you want in the Subject and Body of the email.
  2. The HTTP Request action shows how to reach back into runZero and tag the assets after you gather other data.

runZero sample story

You can import the sample story below into Tines to get all of the actions from the steps above. Save its contents as a JSON file and upload it with the Import button in Tines. After importing, complete these steps.

Step 1: Update credentials in Tines

  1. Replace the runzero_export_token credential:
  2. Replace the runzero_org_token credential:

Step 2: Create runZero alert template

  1. Create an alert template in runZero:
    • Name: a name for the template
    • Template type: JSON
    • Subject line for message: leave empty
    • Body of message: this JSON example includes the rule name and the search URL in the alert message body: {"rule_name":"{{rule.name}}","search_url":"{{search.url}}"}
  2. Create an alert channel in runZero:
    • Name: a name for the alert channel
    • Channel type: webhook
    • Webhook URL: the webhook URL you copied from Tines

Step 3: Create the rule in runZero

With the template ready, pick the triggers to alert on. Common examples:

  • Asset query results: a query in runZero matches after a scan completes.
  • New assets found: a scan completes with new assets.
  • Agent offline: your runZero Explorer stops checking in to the console.
  • Task failed: a task fails for any reason.

The rest of the steps use asset query results, with any asset that has an open Telnet port (port:23) as the example. You can see more example queries.

  1. Create a new alert rule.
  2. Select asset-query-results and click Configure rule.
  3. Enter values for the rule:
    • Name: the name of the rule.
    • Conditions: optional parameters; the alert triggers when all conditions match.
      • Query: the query the assets must match, port:23 in this example.
      • Number of matches: the numeric comparison to apply to the value.
      • Value: the match threshold that triggers the rule.
      • Limit to organization: limits the alert to a specific organization in runZero.
      • Limit to site: limits the alert to a specific site in runZero.
      • Action: notify
        • Notification channel: the alert channel you created in step 2.
        • Notification template: the alert template you created in step 2.

runZero sample story JSON

{
  "schema_version": 4,
  "standard_lib_version": 6,
  "name": "runZero Sample Story",
  "description": null,
  "guid": "7706b502e51b4c68f0dbe9721c88d665",
  "slug": "runzero_sample_story",
  "exported_at": "2022-10-27T22:22:37Z",
  "agents": [
    {
      "type": "Agents::WebhookAgent",
      "name": "RECEIVE alerts from runZero",
      "disabled": false,
      "guid": "ab1f5bf7be49c943d893ab993ade9421",
      "options": {
        "path": "da6e90c0b276bdda97e6bfa31ad50787",
        "secret": "5e290305e0a483bf843f1213f0f21dda",
        "verbs": "get,post"
      },
      "reporting": {
        "time_saved_value": 0,
        "time_saved_unit": "minutes"
      },
      "monitoring": {
        "monitor_all_events": false,
        "monitor_failures": false,
        "monitor_no_events_emitted": null
      },
      "width": null
    },
    {
      "type": "Agents::HTTPRequestAgent",
      "name": "GET assets from runZero",
      "disabled": false,
      "guid": "d54d8f3f5b0ea857308f45f61a224547",
      "options": {
        "url": "https://console.runZero.com/api/v1.0/export/org/assets.json<<get_search_from_regex.individual_item>>",
        "content_type": "application_json",
        "method": "get",
        "headers": {
          "Authorization": "Bearer <<CREDENTIAL.runzero_export_token>>"
        }
      },
      "reporting": {
        "time_saved_value": 0,
        "time_saved_unit": "minutes"
      },
      "monitoring": {
        "monitor_all_events": false,
        "monitor_failures": false,
        "monitor_no_events_emitted": null
      },
      "width": null,
      "schedule": []
    },
    {
      "type": "Agents::EventTransformationAgent",
      "name": "GET search from URL",
      "disabled": false,
      "guid": "d62ddd189bb9080d778d900f2292504d",
      "options": {
        "mode": "extract",
        "matchers": [
          {
            "path": "=receive_alerts_from_runzero.body.search_url",
            "regexp": "\\?.*",
            "to": "search"
          }
        ]
      },
      "reporting": {
        "time_saved_value": 0,
        "time_saved_unit": "minutes"
      },
      "monitoring": {
        "monitor_all_events": false,
        "monitor_failures": false,
        "monitor_no_events_emitted": null
      },
      "width": null,
      "schedule": null
    },
    {
      "type": "Agents::EventTransformationAgent",
      "name": "GET search from regex",
      "disabled": false,
      "guid": "41afc5c4d4c0fdb694d14e1eb380688a",
      "options": {
        "mode": "explode",
        "path": "=get_search_from_url.search",
        "to": "individual_item"
      },
      "reporting": {
        "time_saved_value": 0,
        "time_saved_unit": "minutes"
      },
      "monitoring": {
        "monitor_all_events": false,
        "monitor_failures": false,
        "monitor_no_events_emitted": null
      },
      "width": null,
      "schedule": null
    },
    {
      "type": "Agents::EventTransformationAgent",
      "name": "LOOP through assets for follow up actions",
      "disabled": false,
      "guid": "b9ada61162bdf006f09d264845ebd304",
      "options": {
        "mode": "explode",
        "path": "=get_assets_from_runzero.body",
        "to": "individual_item"
      },
      "reporting": {
        "time_saved_value": 0,
        "time_saved_unit": "minutes"
      },
      "monitoring": {
        "monitor_all_events": false,
        "monitor_failures": false,
        "monitor_no_events_emitted": null
      },
      "width": null,
      "schedule": null
    },
    {
      "type": "Agents::EmailAgent",
      "name": "SEND Email Action",
      "disabled": false,
      "guid": "0e9647b114f315d480f1f85c58e481d3",
      "options": {
        "recipients": "youremail@email.com",
        "reply_to": "youremail@email.com",
        "sender_name": "Your Name",
        "subject": "<<receive_alerts_from_runzero.body.rule_name>>",
        "body": "Alert: <<receive_alerts_from_runzero.body.rule_name>>\n\\<br />\n\\<br />\nLink to asset: https://console.runzero.com/inventory/<<loop_through_assets_for_follow_up_actions.individual_item.id>>\n\\<br />\n\\<br />\nAddresses: <<loop_through_assets_for_follow_up_actions.individual_item.addresses>>\n\\<br />\n\\<br />\nServices:\n<<NEWLINE_TO_BR(NEAT_JSON(loop_through_assets_for_follow_up_actions.individual_item.services))>>"
      },
      "reporting": {
        "time_saved_value": 0,
        "time_saved_unit": "minutes"
      },
      "monitoring": {
        "monitor_all_events": false,
        "monitor_failures": false,
        "monitor_no_events_emitted": null
      },
      "width": null,
      "schedule": null
    },
    {
      "type": "Agents::HTTPRequestAgent",
      "name": "TAG assets in runZero",
      "disabled": false,
      "guid": "c3171fed91ec40d39572260295a63ae0",
      "options": {
        "url": "https://console.runZero.com/api/v1.0/org/assets/<<loop_through_assets_for_follow_up_actions.individual_item.id>>/tags",
        "content_type": "application_json",
        "method": "patch",
        "headers": {
          "Authorization": "Bearer <<CREDENTIAL.runzero_org_token>>"
        },
        "payload": {
          "tags": "hello=from_tines"
        }
      },
      "reporting": {
        "time_saved_value": 0,
        "time_saved_unit": "minutes"
      },
      "monitoring": {
        "monitor_all_events": false,
        "monitor_failures": false,
        "monitor_no_events_emitted": null
      },
      "width": null,
      "schedule": []
    }
  ],
  "diagram_notes": [
    {
      "content": "Hello! Thanks for importing the runZero Sample Story. \n\nThis story is a basic example of what you can do with runZero and Tines. \n\nPrerequisites:\n1. Create a text [credential](https://www.tines.com/docs/credentials/text) called `runzero_export_token`. Set the value as your [runZero export token](docs/leveraging-the-api.md), which can be obtained from the desired [runZero organization](https://console.runzero.com/organizations) page. Export tokens start with `ET`.\n2. Create a text [credential](https://www.tines.com/docs/credentials/text) called `runzero_org_token`. Set the value as your as your [organization API token](docs/leveraging-the-api.md), which can be obtained from the desired [runZero organization](https://console.runzero.com/organizations). Organization API tokens start with `OT`. \n\nThe steps are as follows:\n\n1. **RECEIVE alerts** provides the webhook destination for your runZero alerts \n\n2. **GET search from URL** parses out the search string from the URL provided in the runZero alert \n\n3. **GET search from regex** takes the list provided in step 2 and allows you to use the individual value \n\n4. **GET assets from runZero** uses the runZero Export API to get the list of assets related to the alert \n\n5. **LOOP through assets for follow up actions** takes the list of assets and sends each to the next steps individually \n\n6. **NOTE**: this is the step that you could implement more custom logic in most cases. All of the initial runZero and Tines data transfer is done, but it's your chance to customize this story to fit your use case. \n\n7. **SEND email action** simply sends an email to the destination of your choice \n\n8. **TAG assets in runZero** adds a tag in runZero to each asset showing an example of how you might reach back into runZero after doing other automated activities ",
      "position": [
        165.0,
        180.0
      ],
      "guid": "0e4b9b331dc65316849f7b089bf7bde2",
      "width": 375
    }
  ],
  "links": [
    {
      "source": 0,
      "receiver": 2
    },
    {
      "source": 1,
      "receiver": 4
    },
    {
      "source": 2,
      "receiver": 3
    },
    {
      "source": 3,
      "receiver": 1
    },
    {
      "source": 4,
      "receiver": 6
    },
    {
      "source": 4,
      "receiver": 5
    }
  ],
  "diagram_layout": "{\"ab1f5bf7be49c943d893ab993ade9421\":[555,180],\"d54d8f3f5b0ea857308f45f61a224547\":[555,450],\"d62ddd189bb9080d778d900f2292504d\":[555,270],\"41afc5c4d4c0fdb694d14e1eb380688a\":[555,360],\"b9ada61162bdf006f09d264845ebd304\":[555,555],\"0e9647b114f315d480f1f85c58e481d3\":[555,690],\"c3171fed91ec40d39572260295a63ae0\":[780,690]}",
  "send_to_story_enabled": false,
  "entry_agent_guid": null,
  "exit_agent_guids": [],
  "exit_agent_guid": null,
  "keep_events_for": 604800,
  "reporting_status": true,
  "send_to_story_access": null,
  "send_to_stories": [],
  "form": null,
  "forms": []
}
Updated