REST API

REST API

The SOAR platform is built on the REST API. It provides comprehensive access to platform capabilities: to read and write incident data, and to perform a wide range of administrative functions. The REST API is supported by documentation, client libraries and example code for Python, .NET and Java.

Typical use cases include incident escalation — creating a new incident based on an external event — and enrichment, automation, and reporting. This API gives you access to all the incident data, including tasks, data tables, notes, milestones, artifacts and file attachments.

REST Services, URLs and Data Types

The REST API follows a very regular pattern. Each resource (incident, task, artifact, etc.) is addressed by a unique URL. The structure of the URL usually indicates that one resource is contained within another. For example, the path to organization ID 201 is https://server/rest/orgs/201, and the URL to incident 2345 in this organization is https://server/rest/orgs/201/incidents/2345.

When you GET a resource, the server returns a JSON representation of the value. (We refer to these JSON documents as DTOs, Data Transfer Objects). To create a new object within the resource, POST a JSON document to the parent URL. For example, to create a new artifact within the incident, you should POST the representation of an artifact to https://server/rest/orgs/201/incidents/2345/artifacts. See below for some working examples in Python.

There are two ways to update a resource. The first is to PUT a new version, which directly replaces the previous version. The second, PATCH, allows a partial update to incidents where only specific fields are replaced; this is recommended over PUT, since it reduces conflicts, and provides some explicit ways to declare how conflicts should be handled if they do occur.

For a general overview of REST API, see the IBM Cloud article, REST APIs.

Using the Interactive Tool

The SOAR platform contains an interactive Rest API browser that allows you to access the REST API and try out any endpoint on the system. When logged into the SOAR platform, click on your account name at the top right and select Help/Contact. Here you can access the complete API Reference guide, including schemas for all of the JSON sent and received by the API, and the interactive Rest API.

Exploring the REST API with gadget

The gadget utility, installed with the SOAR SDK and Resilient Circuits, is a very simple wrapper for the REST API, with commands that

  • List incidents
  • Read and write incident data using GET, POST, PUT, PATCH and DELETE
  • Query and search
  • Access other REST endpoints such as phases and tasks, types, users and groups.

The utility requires an app.config file to communicate with a specific SOAR organization. To see the ID and name of each incident available in the SOAR organization, enter:

gadget --list

To get the JSON representation of incident number 12345, use the command below.

gadget --get /incidents/12345?handle_format=names

To get a JSON array of the incident's artifacts:

gadget --get /incidents/12345/artifacts?handle_format=names

To see the properties of a single artifact with ID 789:

gadget --get /incidents/12345/artifacts/789?handle_format=names

Accessing the REST API with Python

The REST API is accessed by importing the Resilient module, with a SimpleClient class that provides methods to access the platform. Here is simple code that connects to the SOAR platform by reading the connection details from your configuration file:

# Use the Resilient API module
import resilient

# Read connection parameters from your configuration file, supplemented from the command-line
parser = resilient.ArgumentParser(config_file=resilient.get_config_file())

opts = parser.parse_args()


# Connect and authenticate to the SOAR organization, to get a SimpleClient
client = resilient.get_client(opts)

It is possible to construct a SimpleClient directly, instead of using the resilient.get_client() helper method. See the Multi-Org Escalation example for how this can be done. For most use cases, you should use the configuration file approach above.

The SimpleClient object then allows us to work with incident data:

# Get a single incident
inc_id = 12345
uri = "/incidents/{}?handle_format=names".format(inc_id)
inc = client.get(uri)

# What is the incident id?
assert(inc_id == inc["id"])

# Print the incident data structure as nicely-formatted JSON
import json
print(json.dumps(inc, indent=2))

Exploring the schema with finfo

The finfo utility, installed with Resilient Circuits, uses the /types REST API to list the fields and other data types from your SOAR platform. It is a very useful command-line tool for exploring and documenting your SOAR customizations.

The basic usage shows the names of all incident fields. (The output below is for illustration – you will have more fields than this!). Required fields are marked with an asterisk. Required-for-close fields are shown with ‘c’ in the first column. The fields preceded with “properties.” are custom fields, not part of the default system configuration.

$ finfo
Fields:
  city
* discovered_date
  id
  members
* name
  owner_id
  properties.attack_vector
  properties.cyber_kill_chain
  properties.data_breach_type
c resolution_id
c resolution_summary
  severity_code
  start_date
  state
  zip

To list all the field definitions in CSV format, including much more information about each field (its display name, data type, etc.):

finfo --csv

The SOAR data model includes incidents, which contain tasks, notes and other objects; each of these has a type definition. To list all the types:

finfo --types

If you have a customized SOAR platform with a data table named "assets", you can list the fields of that type:

finfo --type assets

Examples

Example 1: Using the SOAR python library

https://pypi.org/project/resilient/

import resilient

base_url = 'example.url.com'
auth = {"host": base_url, 
       "port": 443, 
       "org": "Example Org Name", 
       "api_key_id": "example-api-key-id", 
       "api_key_secret": "example-api-key-secret", 
       "cafile": False} # True or False depending on your connection
requirementsres_client = resilient.get_client(auth)
response = res_client.get(uri="/endpoint")

print(response)

Example 2: Using requests

import requests

api_key_id = 'example-api-key-id'
api_key_secret = 'example-api-key-secret'
base_url = 'https:///rest/orgs/'
headers = {'Content-Type': 'application/json'}
auth = (api_key_id, api_key_secret)

#The options specified will be dependant on your specific connection requirements
response = requests.get(u" {0} /endpoint".format(base_url), auth=auth, proxies=None, headers=headers, verify=False)

print(response.content)