Cisco SecureX Integration Workflows

Getting Started

Users can generate API client credentials, which can be used to access the Cisco SecureX threat response APIs programmatically.

Refer to the Cisco Threat Response API Client Documentation for more info on how to create an API client.

Global API Endpoint URLs

To find the correct API endpoint URL query https://visibility.amp.cisco.com/clouds.json and present the user with the name of the region. Then save it and use the appropriate URLs for the region.

The current available regional API endpoints are:

Create API Client in Threat Response UI

When creating your API client, you will receive a Client ID and Client Password which will be used to retrieve an access token in the next step.

_images/ctg-api-creds.png

Scopes

There are twelve scopes available when adding a new client. A single scope can be selected or any mix of the scopes can be chosen.

Casebook Access and modify your casebooks
Enrich Query your configured modules for threat intelligence (Read Only)
Global Intelligence Access AMP Global Intelligence (Read Only)
Inspect Extract observables and data from text (Read Only)
Integration Manage your modules (Read Only)
Private Intelligence Access AMP Private Intelligence
Profile Get your profile information
Registry Manage registry entries
Response List and execute response actions using configured modules
SSE SSE Integration. Manage your Devices (Read Only)
Telemetry Collect application data for analytics (Write Only)
Ui Settings Save user settings
Users Manage users of your organization

The scopes can be selected when creating API Clients at https://visibility.amp.cisco.com/settings/apiClients

Warning

Security access control best practice requires providing a user or service least access. When designing API workflows, it is often desirable to have more than one set of API client credentials for destructive and non destructive API operations. API clients can be created to have different combinations of scopes which can be used to map out and provide least access to different parts of a client application.

Using API Client Credentials to Get Access Token

You cannot access the API directly using the Client ID and Client Password because Threat Response requires the use of an Access Token. You can request a token from the OAuth2 Token Api.

http

POST https://visibility.amp.cisco.com/iroh/oauth2/token HTTP/1.1
Content-Type: application/json
Accept: application/json

{
    "client_id": "client-38bbc74d-f7d1-452b-8777-fb8c7d985475",
    "client_password": "FIz1FDf40ms0mNpc9oS8AJQJ2Vyw0aUtE17XWZWEQ71IMs13J8AQFD",
    "grant_type": "client_credentials"
}

Example using Bash with a curl command:

client_id="client-38bbc74d-f7d1-452b-8777-fb8c7d985475"
client_password="FIz1FDf40ms0mNpc9oS8AJQJ2Vyw0aUtE17XWZWEQ71IMs13J8AQFD"
    curl -X POST \
     -u "$client_id:$client_password" \
     --header 'Content-Type: application/x-www-form-urlencoded' \
     --header 'Accept: application/json' \
     -d 'grant_type=client_credentials' \
     'https://visibility.amp.cisco.com/iroh/oauth2/token'

JSON Response:

{
  "access_token":"eyJhbGciO...",
  "token_type":"bearer",
  "expires_in":600,
  "scope":"enrich:read casebook inspect:read"
}

Description of Response:

access_token Indicates what you pass in the authorization header
token_type Indicates it should be presented as a certain type of token
expires_in Indicates how many seconds this token is valid. You will need to request a new one after it expires, using the same API call
scope Contains a list of scopes that were granted to this token. It may not include all of the scopes for which the client was authorized if your user identity has lost privileges since the API Client was created

Once an Access Token has been created, you can call the APIs you granted the API Client permissions to access. See documentation here.

Authentication

All Threat Response APIs use an Access Token for authentication. This is an opaque value which is passed in as an HTTP header: Authorization: Bearer <Access Token>. Access Tokens are short-lived, and can be requested or refreshed from the OAuth2 Token Api.

For more information please see: https://visibility.amp.cisco.com/help/integration

Rate Limits

To protect our infrastructure, we apply rate limits to API requests. The current limit is 8000 requests per rolling 60 minute window. When you make a request, the X-Ratelimit-Org-Limit header will tell you the rate limit being applied.

Warning

If you go over your rate limit, you will get a 429 Too Many Requests response code. When developing your integration with Cisco SecureX threat response, you should ensure the you are staying under the quota, as well as handling the HTTP 429 error gracefully and throttling your requests.

More information and examples of rate limits can be found at: https://visibility.amp.cisco.com/help/integration

API Endpoints

There are six available APIs used for integrations. These include:

Inspect Parses a string of text and extracts supported observables
Enrich Manage users of your organization Used to get query for information about an observable or to pivot to a product UI
Response Used to take action on an observable within a product
OAuth2 Used to get a token
Global-Intel Global instance of CTIA only has read access
Private-Intel Customer specific instance of CTIA where Casebooks, Snapshots, Investigations, etc are stored

More information can be found at: https://visibility.amp.cisco.com/help/integration

Pivot into threat response

Note

When launching investigations from a dynamically built URL, Threat Response populates an ephermal workbench for an analyst to dig in to the observables passed in to the URL. In order for the data to be saved a user must take a snapshot or add the observables to a case.

Launch Investigation From URL

URL Format

Create a URL using the following format:

https://visibility.amp.cisco.com/#/investigate?q=<STRING>

Note

Open the URL in a new tab when possible.

Use Cases

  • When an easy method for launching an investigation of an observable is desired
  • When there is no desire to save the list of observables

Launch Investigation From a Newly Created Casebook

Interacting with Casebooks is done via the public-intel URL for the selected region. For North America it is at https://private.intel.amp.cisco.com

Create a new casebook

Use the following to create a new casebook:

POST /ctia/casebook

Example casebook JSON payload:

  {
    "description": "Created via the API",
    "schema_version": "1.0.9",
    "observables": [
      {
        "value": "cisco.com",
        "type": "domain"
      }
    ],
    "type": "casebook",
    "short_description": "API Case",
    "title": "Casebook July 26, 2018 11:14 AM",
    "tlp": "amber",
    "timestamp": "2018-07-26T16:14:40.000Z"
}

New Casebook API Example

https://private.intel.amp.cisco.com/index.html#!/Casebook/post_ctia_casebook

JSON Response:

 {
"description":"This is an example",
"schema_version":"1.0.16",
"observables":[
   {
      "value":"125.65.112.23",
      "type":"ip"
   },
   {
      "value":"4a54655a83b1d539c9d5b65c25d20580",
      "type":"md5"
   }
],
"type":"casebook",
"short_description":"Investigating a bad thing",
"title":"My New Example Casebook",
"id":"https://private.intel.amp.cisco.com:443/ctia/casebook/casebook-8b0794e2-bb9b-4ca7-b17d-93a7caa7370f",
"tlp":"amber",
"groups":[
   "threatgrid:364755"
],
"timestamp":"2020-04-27T20:48:52.698Z",
"owner":"jwick"
 }

Save the .id in the response from the POST.

Example format of .id returned:

https://private.intel.amp.cisco.com:443/ctia/casebook/casebook-25d3dd3e-661b-4b37-8588-f12685e296aa

Generate the URL

Generate the URL to link to the case using the following format:

https://visibility.amp.cisco.com/#/investigate?spid=<CASEBOOK_ID_UUID>

Only the UUID portion 25d3dd3e-661b-4b37-8588-f12685e296aa is required to open a casebook.

Note

Open the URL in a new tab when possible.

Use Cases

  • When there are more than one observables to investigate and it is impossible to generate a URL containing all of them
  • When passing the observables via q= that results in a URL that is more than 2,083 characters
  • When there is a desire to investigate and save observables

Launch Investigation From an Existing Casebook

Interacting with Casebooks is done via the public-intel URL for the selected region. For North America it is at https://private.intel.amp.cisco.com

Search for existing casebooks

Search for all existing casebooks using this:

GET /ctia/casebook/search?query=*

Get Casebook API Example

API Endpoint Definition:

http

GET https://private.intel.amp.cisco.com/ctia/casebook/search HTTP/1.1
Authorization: Bearer ${jwt}
Content-Type: application/json

JSON Response:

[{
   "description":"This is a second example",
   "schema_version":"1.0.16",
   "observables":[
      {
         "value":"125.65.112.23",
         "type":"ip"
      },
      {
         "value":"4a54655a83b1d539c9d5b65c25d20580",
         "type":"md5"
      }
   ],
   "type":"casebook",
   "short_description":"Investigating another bad thing",
   "title":"My New Second Example Casebook",
   "id":"https://private.intel.amp.cisco.com:443/ctia/casebook/casebook-cb5988fa-4eee-46ca-9b6d-1b9be022fe79",
   "tlp":"amber",
   "groups":[
      "threatgrid:364755"
   ],
   "timestamp":"2020-04-27T20:50:14.769Z",
   "owner":"jwick"
},
{
   "description":"This is an example",
   "schema_version":"1.0.16",
   "observables":[
      {
         "value":"125.65.112.23",
         "type":"ip"
      },
      {
         "value":"4a54655a83b1d539c9d5b65c25d20580",
         "type":"md5"
      }
   ],
   "type":"casebook",
   "short_description":"Investigating a bad thing",
   "title":"My New Example Casebook",
   "id":"https://private.intel.amp.cisco.com:443/ctia/casebook/casebook-8b0794e2-bb9b-4ca7-b17d-93a7caa7370f",
   "tlp":"amber",
   "groups":[
      "threatgrid:364755"
   ],
   "timestamp":"2020-04-27T20:48:52.698Z",
   "owner":"jwick"
}]

Search for a specific observable or string in the name or description of the casebook using this:

GET /ctia/casebook/search?query=<STRING>

Get Specific Observable API Definition

JSON Response when <STRING> is “Second”:

GET /ctia/casebook/search?query=Second

Note

The query parameter will return hits for .description, .external_references.description, .observables[].value, .short_description, and .title.

Get Specific Casebook API Example

API Endpoint Definition:

http

GET https://private.intel.amp.cisco.com/ctia/casebook/search?query=second HTTP/1.1
Authorization: Bearer ${jwt}
Content-Type: application/json
{
   "description":"This is a second example",
   "schema_version":"1.0.16",
   "observables":[
      {
         "value":"125.65.112.23",
         "type":"ip"
      },
      {
         "value":"4a54655a83b1d539c9d5b65c25d20580",
         "type":"md5"
      }
   ],
   "type":"casebook",
   "short_description":"Investigating another bad thing",
   "title":"My New Second Example Casebook",
   "id":"https://private.intel.amp.cisco.com:443/ctia/casebook/casebook-cb5988fa-4eee-46ca-9b6d-1b9be022fe79",
   "tlp":"amber",
   "groups":[
      "threatgrid:364755"
   ],
   "timestamp":"2020-04-27T20:50:14.769Z",
   "owner":"jwick"
}

Note

  • Multiple casebooks may be returned as an array. Determine a n number of casebooks to present to the user based on product capabilities.
  • For each casebook presented to the user save .[].title and .[].id for later use.

Example of .id format

Example format of .id returned from the POST:

https://private.intel.amp.cisco.com:443/ctia/casebook/casebook-25d3dd3e-661b-4b37-8588-f12685e296aa

Generating a URL

Generate a URL using the following format:

https://visibility.amp.cisco.com/#/investigate?spid=<CASEBOOK_ID_UUID>

Example fully populated URL:

https://visibility.amp.cisco.com/#/investigate?spid=25d3dd3e-661b-4b37-8588-f12685e296aa

Only the UUID portion 25d3dd3e-661b-4b37-8588-f12685e296aa is required to open a casebook.

Present a n number of .[].title links to the user.

Note

Open the URL in a new tab when possible.

Use Cases

  • When a casebook exists with the observable you would like to investigate
  • Integration built to interact with Casebooks natively (replicating what the Browser plugin or casebooks Widget do)
  • Threat Hunting based on what other analysts in the organization are investigating
  • Looking into casebooks to see what Observables humans may have associated with an Observable of interest but do not have a programmatic connection anywhere, i.e., an analyst has determined an email address and a mutex are part of the same campaign and has stored both in a casebook.

Query Threat Response

Get Verdicts for an Observable

Extract Observables

Note

This step can be skipped if the observable type is known and can be mapped to the supported observables so you can build your own payload.

Extract observables using:

POST /iroh/iroh-inspect/inspect

Extract Observables API Example

API Endpoint Definition:

http

POST https://visibility.amp.cisco.com/iroh/iroh-inspect/inspect HTTP/1.1
Authorization: Bearer ${jwt}
Content-Type: application/json

{
    "content": "cisco.com"
}

JSON Response:

[
  {
    "value": "cisco.com",
    "type": "domain"
  }
]

Deliberate Observables

Pass the returned array to:

POST /iroh/iroh-enrich/deliberate/observables

Deliberate Observables API Example

API Endpoint Definition:

http

POST https://visibility.amp.cisco.com/iroh/iroh-enrich/deliberate/observables HTTP/1.1
Authorization: Bearer ${jwt}
Content-Type: application/json

[
    {
        "value": "cisco.com",
        "type": "domain"
    }
]

JSON Response:

{
  "data": [
    {
      "module": "Talos Intelligence",
      "module-type": "SenderBaseInvestigateModule",
      "data": {
        "verdicts": {
          "count": 1,
          "docs": [
            {
              "type": "verdict",
              "disposition": 1,
              "observable": {
                "value": "cisco.com",
                "type": "domain"
              },
              "disposition_name": "Clean",
              "valid_time": {
                "start_time": "2020-04-28T21:55:32.572Z",
                "end_time": "2020-05-28T21:55:32.572Z"
              }
            }
          ]
        }
      }
    },
    {
      "module": "AMP File Reputation",
      "module-type": "POKEDeliberateModule",
      "data": {
        "verdicts": {
          "count": 0,
          "docs": []
        }
      }
    }
  ]
}

JQ Filters for commonly used values:

  • .data[].module
  • .data[].data.verdicts.docs[].observable.value
  • .data[].data.verdicts.docs[].disposition or .data[].data.verdicts.docs[].disposition_name

Note

Disposition mapping: {1 “Clean”, 2 “Malicious”, 3 “Suspicious”, 4 “Common”, 5 “Unknown”}

JQ Filters for occasionally used values:

  • .data[].data.verdicts.docs[].valid_time.start_time
  • .data[].data.verdicts.docs[].valid_time.end_time

Entities that may be returned:

Use Cases

  • There are a high number of observables
  • Only verdicts are desired
  • To reduce the number of observables
  • The goal is to indicate which items merit looking into further

Contextualize an Observable

Extract Observables

Note

This step can be skipped if the observable type is known and can be mapped to the supported observables so you can build your own payload.

Extract observables using:

POST /iroh/iroh-inspect/inspect

Extract Observables API Example

API Endpoint Definition:

http

POST https://visibility.amp.cisco.com/iroh/iroh-inspect/inspect HTTP/1.1
Authorization: Bearer ${jwt}
Content-Type: application/json

{
    "content": "cisco.com"
}

JSON Response:

[
  {
    "value": "cisco.com",
    "type": "domain"
  }
]

Observe Observables

Pass the returned array to:

POST /iroh/iroh-enrich/observe/observables

Observe Observables API Example

API Endpoint Definition:

http

POST https://visibility.amp.cisco.com/iroh/iroh-enrich/observe/observables HTTP/1.1
Authorization: Bearer ${jwt}
Content-Type: application/json

[
  {
    "value": "cisco.com",
    "type": "domain"
  }
]

JSON Response:

{
  "data": [
    {
      "module": "Talos Intelligence",
      "module-type": "SenderBaseInvestigateModule",
      "data": {
        "verdicts": {
          "count": 1,
          "docs": [
            {
              "type": "verdict",
              "disposition": 1,
              "observable": {
                "value": "cisco.com",
                "type": "domain"
              },
              "judgement_id": "transient:f7e85f0e-2886-479c-baa4-6deb84f9bbf7",
              "disposition_name": "Clean",
              "valid_time": {
                "start_time": "2020-04-28T21:58:56.926Z",
                "end_time": "2020-05-28T21:58:56.926Z"
              }
            }
          ]
        },
        "judgements": {
          "count": 1,
          "docs": [
            {
              "valid_time": {
                "start_time": "2020-04-28T21:58:56.926Z",
                "end_time": "2020-05-28T21:58:56.926Z"
              },
              "schema_version": "1.0.16",
              "observable": {
                "value": "cisco.com",
                "type": "domain"
              },
              "type": "judgement",
              "source": "Talos Intelligence",
              "disposition": 1,
              "reason": "Good Talos Intelligence reputation score",
              "source_uri": "https://www.talosintelligence.com/reputation_center/lookup?search=cisco.com",
              "disposition_name": "Clean",
              "priority": 90,
              "id": "transient:f7e85f0e-2886-479c-baa4-6deb84f9bbf7",
              "severity": "None",
              "tlp": "white",
              "confidence": "High"
            }
          ]
        }
      }
    }
  ]
}

This returns the .data[].module and other pieces of data depending on the use case.

Mapping observables to some objects (attack_patterns) requires looking at the relationships and matching the IDs.

May return any of the CTIM entities:

Most commonly used entities:

  • Verdicts
  • Sightings
  • Indicators
  • Judgements

Note

Targets are found within the Sightings entity

Are there targets in “my” environment?

Return the .data[].data.sightings.docs[]?.targets and compare returned objects and deduplicate to get a true unique value. The same target can be observed for multiple observables .data[].data.sightings.docs[]?.observables.

Use Cases

  • Check for targets from within the returned sightings
  • Contextualize an observable as it relates to the Global and Private Threat Intel
  • Historical Incidents an Observable has been related to with
  • Identify what Campaign(s) an Observable has been used in
  • Find Indicators associated with an Observable
  • Discover Observed Relations for an Observable
    • URLs hosted on a Domain
    • IP Addresses a Domain has resolved to
    • File Names associated with a File Hash
    • File Paths associated with a File Hash
    • Mutexes associated with a File Hash
    • URLs a File Hash was downloaded from

Refer “Pivot” Actions

Extract Observables

Note

This step can be skipped if the observable type is known and can be mapped to the supported observables so you can build your own payload.

Extract observables using:

POST /iroh/iroh-inspect/inspect

API Example

API Endpoint Definition:

http

POST https://visibility.amp.cisco.com/iroh/iroh-inspect/inspect HTTP/1.1
Authorization: Bearer ${jwt}
Content-Type: application/json

{
  "content": "cisco.com"
}

JSON Response:

[
  {
    "value": "cisco.com",
    "type": "domain"
  }
]

Refer Observables

Pass the returned array to:

POST /iroh/iroh-enrich/refer/observables

API Example

API Endpoint Definition:

http

POST https://visibility.amp.cisco.com/iroh/iroh-enrich/refer/observables HTTP/1.1
Authorization: Bearer ${jwt}
Content-Type: application/json

[
  {
    "value": "cisco.com",
    "type": "domain"
  }
]

JSON Response:

{
  "data": [
    {
      "id": "ref-talos-search-domain-cisco.com",
      "module": "Talos Intelligence",
      "module-type": "SenderBaseInvestigateModule",
      "title": "Search for this domain",
      "description": "Lookup this domain on Talos Intelligence",
      "url": "https://www.talosintelligence.com/reputation_center/lookup?search=cisco.com",
      "categories": [
        "Talos Intelligence",
        "Search"
      ]
    }
  ]
}

JQ Filters for commonly used values:

  • .data[].module
  • .data[].url
  • .data[].title

This may return:

  • .data[].description

Render .data[].title link to user in a way that makes sense within the product.

Note

Open the URL in a new tab when possible.

Use Cases

  • Get the links to pivot into products based on modules
  • Streamline user experience when needing to pivot into other products
  • To enable someone to pivot to the UI of a product to search for an Observable
  • To enable someone to pivot to the UI of a product to lookup or browsed the information about an Observable

Response Actions

Extract Observables

Note

This step can be skipped if the observable type is known and can be mapped to the supported observables so you can build your own payload.

Extract observables using:

POST /iroh/iroh-inspect/inspect

API Example

API Endpoint Definition:

http

POST https://visibility.amp.cisco.com/iroh/iroh-inspect/inspect HTTP/1.1
Authorization: Bearer ${jwt}
Content-Type: application/json

{
  "content": "cisco.com"
}

JSON Response:

[
  {
    "value": "cisco.com",
    "type": "domain"
  }
]

Respond Observable

Pass the returned array to:

POST /iroh/iroh-response/respond/observables

API Example

API Endpoint Definition:

http

POST https://visibility.amp.cisco.com/iroh/iroh-response/respond/observables HTTP/1.1
Authorization: Bearer ${jwt}
Content-Type: application/json

[
  {
    "value": "cisco.com",
    "type": "domain"
  }
]

JSON Response:

{
  "data": [
    {
      "module": "Umbrella",
      "module_instance_id": "b56d3882-37d8-4c0c-af22-a5ef0cf53bd3",
      "module_type_id": "188d70f7-29d5-5069-9098-d83a3ec8e797",
      "id": "block",
      "title": "Block this domain",
      "description": "Block this domain using Umbrella Enforcement API",
      "url": "/respond/trigger/b56d3882-37d8-4c0c-af22-a5ef0cf53bd3/block?observable_type=domain&observable_value=cisco.com"
    }
  ]
}

JQ Filters for commonly used values:

  • .data[].module
  • .data[].title
  • .data[].url

Render .data[].title link to user in a way that makes sense within the product. When this is clicked authenticate using a token.

For example:

Example with parameters: <a href="{{host}} + {{$.data[].url}}">{{.data[].title}}</a>

Example with parameter substitution: <a href="https://visibility.amp.cisco.com/respond/trigger/b56d3882-37d8-4c0c-af22-a5ef0cf53bd3/block?observable_type=domain&observable_value=cisco.com">Block this domain</a>

Relay API

Requirements

All docs have to contain a schema_version field. Current version can be found at: https://github.com/threatgrid/ctim

All entities should have an id, in your case it’s a transient as it’s not something stored/accessible at some place using HTTP. A transient is just a string, you need to concatenate transient: with an UUID. For example: transient:616608f4-7658-49f1-8728-d9a3dde849d5.

Sightings need a count field. Example can be found at https://github.com/threatgrid/ctim/blob/master/doc/structures/sighting.md#propertycount-integer

Good Practices When Possible

Sighting.data property, that allows you to add a semi-structured map of key-value pairs. Example can be found at https://github.com/threatgrid/ctim/blob/master/doc/structures/sighting.md#property-data–sightingdatatable-object

Put some of the Indicator explanation in the Sighting description, which is markdown. Example can be found at https://github.com/threatgrid/ctim/blob/master/doc/structures/indicator.md#property-description–markdown-string

Set resolution field to “blocked” if it was blocked. Example can be found at https://github.com/threatgrid/ctim/blob/master/doc/structures/sighting.md#property-resolution–resolution-string

If source for sighting is a distinct appliance (WAF, IDS) Sighting.sensor_object can be set to identify the specific instance that detected.

Getting Started

Recommended steps to create a workflow:

Targets Define where you want to run your workflow.
Account Keys Create all of your accounts keys that you want to use in targets.
Schedules Define schedules if you want to execute a job at a certain time.
Events Create triggers from email that you receive.
Variables Define global variables that you might want to configure for use over multiple workflows.
Atomic Actions Create re-usable snippets for use within your workflows.

Workflows

Workflows are built with Atomic Actions and they act as lego pieces to create workflows.

Workflows

Creating a New Workflow

  1. Select the “New Workflow” button.
_images/newworkflow.png
  1. Click on the empty palette to see all the properties of the workflow on the right side panel.
  2. Provide a display name and a description.
  3. Drag an action from the left side panel from any category desired. For an example, we will be using the “AWS Service” named “Create VPC”.
_images/createvpc.png
  1. Click on the action to see the properties required in the right side panel.
  2. Click the empty palette and add the AWS Endpoint to the target section under execute on a target.
_images/selecttarget.png
  1. Go back to the “Create VPC” action you will see that you can now select the target as use workflow target or you can override it.
_images/choosetarget.png
  1. Provide a name tag and an IP address.
_images/createvpcinfo.png
  1. Add a new action called “Create Subnet in a VPC”.
_images/createsubnet.png
  1. Provide it a name, an IP CIDR Block, and an availability zone.
_images/createsubnetinfo.png
  1. Click the puzzle piece next to VPC ID and go to Activities, Create VPC, and then VPC ID to add the ID.
_images/addidvariable.png
  1. The example workflow is now complete.

Running a Workflow from the UI

  1. Click the “Validate” button.
  2. Click the “Run” button.
_images/runworkflow.png

Running a Workflow from the API

The following API call can be used to start a workflow

/v1/workflows/start

More information can be found here.

Runs

Runs allow you to see what actually occurred within your workflow. It lets you see every single step that happened so you can easily see where something went wrong.

How to See Runs

  1. In the left side panel below “Workflows” you will see a tab for “Runs”.
_images/runs.png
  1. Find runs for a specific workflow by going to the workflow and hitting the “View Runs” button.
_images/specificrun.png
  1. The runs page will show you the status of the run, the time it was started, the time it ended, the user it was started by, and the owner of the workflow.
_images/status.png
  1. Use the filter on the left to see specific results and workflows.
_images/filter.png

How to View a Failed Run

  1. Click on a workflow that failed it will take you to the workflow and put a green box around everything that ran successfully and a red box around what failed.
  2. Click on the red box and see what all the input and output was to find the error.
_images/failedrun.png

Targets

Targets specify where you want your actions or workflows to run. There are both single targets or target groups to choose from.

Creating Single Targets

  1. Create a new single target click the “New Target” button.
_images/newtarget.png
  1. Choose a target type.

Note

HTTP Endpoint is the most common target type.

_images/targettype.png
  1. Create a display name and description.
  2. Choose to apply an account key or create a new one.

Note

Account keys are only required for actions that require authentication.

  1. Provide the HTTP protocol, host/ip address, the port, and the path.
_images/targetinfo.png
  1. Click the “Submit” button.

Adding Targets to a Workflow

  1. Open the workflow.
  2. Select the target you created.
_images/addtarget.png

Creating Target Groups

TODO add info here

Account Keys

Account keys are used to authenticate to a target that is used in workflows. Account keys can be credentials like usernames and passwords or they can be certificates.

Creating a New Account Key
  1. Click on the “New Account Key” button.
_images/accountkeybutton.png
  1. Choose the target account key type.
_images/keytype.png

Note

The most common key type is HTTP Basic Authentication or HTTP Client Certificate Authentication. Most REST interfaces will use HTTP Basic Authentication.

Example of Creating New Account Keys
  1. To create a HTTP Basic Authentication Key you will provide a display name and a description. Then you will add the credentials and click the “Submit” button.
_images/httpkey.png
  1. To create an Email Credentials Key you will provide a display name and a description. Then you will provide a from email address and a password then click the “Submit” button.
_images/emailkey.png
  1. To create a SNMP Credentials Key you will provide a display name and a description. Then you will provide a version number, a username, and a security level then click the “Submit” button.
_images/snmpkey.png
Using an Account Key
  1. Under “Targets” you can choose a target and apply an account key you created to it.
_images/newkeytarget.png

Atomic Actions

Atomic actions are the building blocks of workflows.

Creating an Example Atomic Action

This atomic action will call out a postman echo and echo the response back to us.

Postman Echo
  1. Start by clicking the “New Workflow” button.
_images/newworkflow.png
  1. Scroll down in the left side bar until you reach “Web Service” and add a “HTTP Request” to the workflow.
_images/newecho.png
  1. Provide the HTTP Request the display name “Postman Echo” and provide a description.
  2. Provide the relative URL “/get”.
_images/getURL.png
  1. Go to the target section and select execute on a target.
  2. Create a new target called “Postman Echo” and provide it the URL “postman-echo.com”.
_images/echotarget.png
  1. To test the request please change “/get” to “/get?test&test2” then validate the workflow and run it. In the response JSON you will be able to see “test”, “test2”, and some unnecessary data.

Removing Unnecessary JSON

  1. To remove the extra unnecessary JSON add another action called “JSONPathQuery”. This allows you to pick which data you want to be returned back.
_images/jsonpath.png
  1. In the right hand bar scroll down to JSON Query and click the puzzle piece to add a source JSON to query.
  2. Click activities then “Postman Echo” then choose the body.
_images/jsonvariable.png
  1. Add a JSON Path Query by providing “$.args” and the property name “args”.
  2. To test this action validate the workflow and run it. If you look at the response from the “JSONPathQuery” you will just see “test” and “test2”.

Making the Workflow Reusable

  1. Click an empty spot on the screen and then add a variable.
  2. Choose the data type string, add a display name of “Args”, choose the scope to be input, and make it required.
_images/args.png
  1. Go back to the “Postman Echo” action and change the “/get?test&test2” by leaving the “/get?” and clicking the puzzle piece to select the variable you made.
_images/selectargs.png
  1. Set an output variable by adding a “Set Variables” action to the workflow.
_images/setvariableecho.png
  1. Go back to the main options for the workflow and add a new variable of type string called “OutArgs” and change the scope to output.
_images/outargs.png
  1. Add the variable to the “Set Variables” action by clicking the puzzle piece and choosing “OutArgs” for the variable to update section and for the variable value new section select JSONPath Query then Jsonpath Queries then args.
  2. Validate the workflow and select the “Is Atomic Workflow” button and give it a group name.
_images/atomicworkflow.png
  1. Validate the workflow again and you can no longer click run.
  2. To use the “Postman Echo” workflow you can create a new workflow and now add the “Postman Echo” action.

Logic

Variables

Creating Global Variables

  1. Go to “Variables” on the left hand side to create global variables.
  2. To create a new one click the “New Variable” button.
_images/newvariable.png
  1. Choose a data type. These include boolean, date time, decimal, integer, secure string, string, or you can add a new data type.
_images/variabletypes.png
Example Creation of a String Variable
  1. Select the type String
  2. Provide a display name and a description.
  3. Choose a scope for the variable and provide a value.
_images/stringvariable.png

Creating a New Variable Type

  1. To create a new variable type go under “Variable Types” and click the “New Variable Type” button.
_images/newvariabletype.png
  1. This creates a structure of the type table and asks for a display name and a description.
  2. Add new fields to the variable and click the “Submit” button to create the variable.
  3. This new variable type can now be used to create global variables.
_images/newtypeinfo.png
Creating Local Variables
  1. To create a local variable click inside the workflow area and go to the properties section on the right.
  2. Scroll down until you reach the variables section.
  3. Click new variable.
_images/localvariable.png
  1. Add info for new local variable
_images/localvariableinfo.png

Condition Blocks

Condition blocks allow you to decide which path to take in a workflow.

Example Condition Block

This example sets a variable and then runs a python script based on what the value of the variable is.

  1. Add the action “Set Variables” followed by a condition block with two of the “Execute Python Script” actions inside.
_images/setup.png
  1. Create a local variable for the workflow called “Condition” and make it a boolean and set it to True.
  2. Pass the “Set Variables” action the condition variable.
_images/condition.png
  1. Click on the left condition branch and click the puzzle piece for the left operand and choose the “Condition” variable we created.
  2. Leave the operator as equals and set the right operand to True.
_images/leftside.png
  1. In the left side “Execute Python Script” action add a simple script to print True.
_images/true.png
  1. Click on the right condition branch and click the puzzle piece for the left operand and choose the “Condition” variable we created.
  2. Leave the operator as equals and set the right operand to False.
_images/rightside.png
  1. In the right side “Execute Python Script” action add a simple script to print False.
_images/false.png
  1. Validate and run the action.
  2. The resulting JSON will show the result printed was True as we had the local variable set to True.
_images/conditionresult.png
  1. In the workflow you can see which path was taken as it will have a green square around it.
_images/greenresult.png

For Each Blocks

The For Each block allows you to loop through data.

Example For Each Block

  1. Add a For Each block and add the “JSONPathQuery” action to it.
_images/foreach.png
  1. Create a new variable type called Items and populate the table.
_images/items.png
  1. Click on the For Each block and select the source array to be the items variable by clicking the puzzle piece.
_images/sourcearray.png
  1. Click on the “JSONPathQuery” action and select the source JSON to query to be the first item in the table.
_images/jsonquery.png
  1. Set the Query to “$”, the property name to “ITEM 1”, and the property type to “String”.
_images/jsonvariables.png
  1. Validate the workflow and run it.
  2. After running, you can see that the For Each loop ran 3 times. You can drop down the iterations to see the result of each one.
_images/iterations.png
  1. For the first iteration you can see the item it returned was “desk”.
_images/resultjson.png

While Loop Blocks

A While block will loop until a certain condition is met.

Example While Loop Block

  1. Start by adding the “Set Variable” action and pass it a local variable called count that is set to zero.
_images/count.png
  1. Add a While loop block and add the actions “Execute Python Script” and “Set Variable” to the condition branch.
_images/whilesetup.png
  1. Add a script to the “Execute Python Script” action to add one to count.
  2. Set the script output to be called out.
_images/outcount.png
  1. Set the “Set Variable” action to replace count with the result of the python script.
_images/newcount.png
  1. Set the conditions in the condition branch to use the count variable, not equals, and ten.
_images/whilecondition.png
  1. Run the workflow to see that it runs 10 times.
_images/run10times.png

Parallel Blocks

Parallel blocks allow you to run two actions concurrently and wait until they both complete before doing the next action.

Example Parallel Block

  1. Start by adding “Create VPC” and “Create Subnet in VPC”.
_images/startparallel.png
  1. Add a parallel block and put both actions in it.
  2. Add the “Execute Python Script” after the parallel block.
_images/parallelblock.png
  1. When the workflow is run it will run both “Create VPC” and “Create Subnet in VPC” and wait till they are both done before running “Execute Python Script”.
  2. To add more actions to a parallel block click the plus sign in the top right corner of the block.
_images/newblock.png

Events

Email Events

TODO

Schedules

Calendars

Calendars allow you to choose specific days for a workflow to run.

There are three types of calendars including: date list calendars, group calendars, and a recurring calendars.

You will provide a name and a description for each calendar.

Date List Calendar

  1. Select Date List Calendar from the dropdown.
  2. Provide a name and a description.
  3. Add a list of single dates to have the triggers run on.
_images/datelist.png

Group Calendar

  1. Select Group Calendar from the dropdown.
  2. Provide a name and a description.
  3. Choose a group of dates with a start and end date.
  4. Choose to include or exclude dates from other calendars.
_images/group.png

Recurring Calendar

  1. Select Recurring Calendar from the dropdown.
  2. Provide a name and a description.
  3. Choose a group of dates with a start and end date.
  4. Choose to have it recur daily, weekly, monthly, or yearly.
_images/recurring.png

Schedules

Schedules use the calendars to trigger workflows to run at specified dates and times.

  1. Provide a display name, a description, the calendar name, and the timezone.
  2. Decide a start time, the number of runs per day, and the time interval between runs.
_images/schedule.png

Adding a Schedule to a Workflow

  1. Add a schedule to a workflow by going to the desired workflow and scrolling down to triggers.
  2. Add a new trigger by providing a name, description, type, and the schedule that you created.
_images/trigger.png

Working with Git

Git is able to be used to import/export all workflows and atomic actions.

Exporting to Git

In the workflow workspace you can select a git repository to commit to.

  1. Use the “Commit” button at the top of the page.
_images/specificrun.png
  1. Provide a file name and a commit message.
  2. Use the load new version button to switch to any version of the workflow saved on Git.

Importing from Git

  1. Go to “My Workflows”.
  2. Select the import button and choose a Git repository, filename, and version to import a workflow.
_images/import.png

Adding a Git Repository

  1. Got to “Admin” and then “Git Repositories” to set up all the Git repositories.
  2. To add a new repository click “New Git Repository”.
_images/newgit.png
  1. Provide a name, description, and if you want to provides account keys.
  2. Do Git setup by choosing what protocol to use, the Rest API repository type, the Rest API repository, the branch, and the code path.
  3. Once everything is filled in click the “Submit” button.
_images/newgitinfo.png

API Docs

API Documentation can be found here.