InsightConnect Workflow Best Practices

Welcome to the InsightConnect workflow building best practices page! We’re so happy you’re here. If you’ve never built a workflow and need some ideas to help you get started, first check out our Build a Workflow documentation.

When you’re ready to start building, reference this page for workflow best practices and formatting help.

Workflow names

<Verb> <Object(s)> with <Tool> (<from> <Interface to Trigger Workflow>)

Avoid capitalizing conjunctions in workflow names, such as from and with. Regard all other words in a workflow name as proper nouns.


  • Enrich Indicators with OSInt from Slack
  • Disable User Account in Active Directory from Microsoft Teams
  • Create Ticket in Cherwell from Slack
  • Block Host with Checkpoint Firewall from Slack
  • Get Asset Details and Scan Asset with InsightVM
    • This workflow uses an API trigger, so the <from> <Interface to Trigger Workflow> is not needed
  • Scan Asset with InsightVM from Microsoft Teams
  • Enrich InsightIDR Alerts with Threat Intelligence from VirusTotal

Security terminology

When using security terminology, capitalize all acronyms and initialisms, such as the IP in IP address. As long as vendor-specific terminology does not apply, we recommend that you use the following terms when creating a workflow for specific use cases:

Use caseRecommended term
Disabling something, either temporarily or indefinitelySuspend
Finding and purging data of some kindSearch and Delete
Quarantining a deviceIsolate
Denying access to a user or preventing traffic to or from a specific endpointBan

Additionally, we recommend using the following shorthand editions of these terms to help keep your workflow text concise:

TermShorthand version
IP AddressIP
MAC AddressMAC
SHA256 HashSHA256

Vendor specific terminology

Whenever possible, use up-to-date naming terminology as supplied by the software vendor. For example, VMware Carbon Black EDR is the current name for the legacy Carbon Black Response name. The following terminology examples contain a few of our recommendations for Microsoft software naming:

  • Microsoft Teams - Use the full name because Teams is often overloaded.
  • Azure AD
  • Office 365 - Don't forget to use a space. Do not use o365 or Office365.
  • Active Directory

Be mindful of how software vendors use capitalization and spacing in their product names. The following products are common examples of this:

  • Darktrace
  • CrowdStrike
  • Check Point NGFW

Workflow tags

The following examples are good options for workflow tags:

  • Alerting & Notifications
  • Application Management
  • Asset Inventory
  • Cloud Security
  • Credential Management
  • Data Enrichment
  • Data Utility
  • DevOps
  • Offensive Security
  • Remediation Management
  • Reporting & Analytics
  • Threat Detection & Response
  • User Management
  • Vulnerability Management

Workflow steps

Steps that require users to change user inputs should have change_me as the input to those steps.


For similar enrichment workflows with different vendors, overload the trigger so that all workflows trigger when the single message is posted. Consider this example:

@Slackbot enrich-url <url> would trigger three different enrichment workflows. Include the trigger syntax in the ChatOps trigger step name. This makes it very easy to find and remember what the trigger command is:

enrich-url Trigger or !enrich-url Trigger


@Rapid7 InsightConnect <verb-with-many-words> (<single param> | <param1>=”<value1>” <param2>=”<value2>”)

Trigger commands should not be prefixed with anything and should use lowercase commands and dashes. This is because the bot must be explicitly tagged, therefore we expect a chat command when the bot is tagged (for example, block-host).

When posting messages in Slack, the best practice is to use threads and reply back where the workflow was triggered from. This way, only the trigger step needs user configuration because the channel and ID can be dynamically passed in all subsequent Slack steps:

  • Use the {{["Slack Message Trigger"].[message].[channel_id]}} variable for the Slack Channel
  • Use the {{["Slack Message Trigger"].[message].[ts]}} variable for the thread

Microsoft Teams

!<verb-with-many-words> (<single param> | <param1>=”<value1>” <param2>=”<value2>”)

Teams workflows must be triggered appending a ! to the command and should use lowercase commands and dashes. This is because it is not a bot and we need a special character to indicate that this is a command and not just a test a user is typing that should not be triggered (for example, !block-host).

When posting messages in Teams, the best practice is to use threads and reply back where the workflow was triggered from. This way only the trigger step needs user configuration because the channel and ID can be dynamically passed in all subsequent Teams steps.

  • Use the {{["Microsoft Teams Trigger"].[channel_name]}} variable for the Teams Channel
  • Use the {{["Microsoft Teams Trigger"].[team_name]}} variable for the Team name

Built-in steps

  • Timer Steps
    • Indicate in the trigger name the frequency of the timer (for example, "Daily trigger").
  • Decision Steps
    • Step name should be framed as a question (for example, "Found Hash in VirusTotal?").
  • Loop Steps
    • Loop steps should be named as <Verb> <Collection> (for example, "Process Emails," "Enrich IDR Alerts")
  • Pattern Match Steps for chat-triggered workflows
    • If using a chat trigger, use the Automatic Indicator Extraction feature of Teams and Slack instead of Pattern Match, when possible.
    • If you must match chat commands with Pattern Match, match as much of the command as you can so chat workflows are overloaded without causing unrelated workflows to run.
    • For Slack, if extracting unblock-host and block-host commands and then an indicator to block, use the following expression:
<.*> {{command:/block-host/}} {{indicator:/.*/}}

This will match the Slack bot ID (<ABC123>) and both block-host and unblock-host and store them in a variable called command, as well as any indicator after and store it in a variable called indicator.

  • Action Steps
    • As a general rule, include the action name in the step name.
    • Use your best judgment. If the action name is not at all descriptive, then name the step in a more descriptive manner (for example, "Delete Email," "Scan Asset," "list Investigations").

Workflow building principles

In this section you will find a list of workflow building tips and tricks, as well as useful built-in features that make it easy to manipulate variables and data when building out workflows.

  • If the workflow is triggered from a ChatOps command, let the user know that the workflow has been triggered by posting to the chat thread immediately after the trigger. This gives confidence to the user that the command worked without making them wait for the workflow to complete.
  • The Automatic Indicator Extraction capabilities of the chat integrations make it easy to extract variables and security indicators from a chat message to use later in the workflow.
  • Use Global Artifacts to store data globally across all your workflows. Global Artifacts allow you to leverage outputs or data from your existing workflows and create data that can be reused in multiple workflows, increasing efficiency across your organization.
  • Use Loop Outputs to allow the output from an entire loop of steps to be treated as a single data point in later steps in the workflow.
  • Use the Pattern Match step to match a specific format of data against regex and define this format as a variable that you can use later in your workflow. When the Automatic Indicator Extraction capability is not applicable, the Pattern Match step is a great alternative for data extraction.
  • Use artifact steps along the way to describe functionality and comment on your workflow!

Advanced workflow patterns

The following lists some more advanced workflow patterns such as using lists as Python3 input, utilizing regular expressions on objects, removing newlines from artifacts, Slack messages, and Teams messages.

Use lists as Python3 input

Use an artifact to check for emptiness.

def run(params={}):
import ast
if '{{["Split Nested to List"].[list]}}':
list1 = '{{["Split Nested to List"].[list]}}'
list1 = ast.literal_eval(list1)
list1 = []
if '{{["Split Top Level to List"].[list]}}':
list2 = '{{["Split Top Level to List"].[list]}}'
list2 = ast.literal_eval(list2)
list2 = []
out_list = list(set(list1))
return {"list": out_list}

Use Handlebars to ensure no null arrays:

{"list":"{{#if [\"Triggered\"].[list]}}{{[\"Triggered\"].[list]}}{{else}}[]{{/if}}"}

Utilize regular expressions on objects

Surround any variables in quotes to turn it into a string.

Remove new lines from artifacts

  • {{~#each}}
  • {{this}}
  • {{~/each}}