Splunk® Phantom (Legacy)

Python Playbook API Reference for Splunk Phantom

Acrobat logo Download manual as PDF


Acrobat logo Download topic as PDF

Deprecated automation API

Splunk Phantom's Automation API allows security operations teams to develop detailed and precise automation strategies. Playbooks can serve many purposes, ranging from automating minimal investigative tasks that can speed up analysis to large-scale response to a security breach. The following APIs are supported to leverage the capabilities of the platform using Playbooks.

Replacement APIs for deprecated APIs

This table shows the replacements for deprecated APIs. Each of the deprecated items in this table are not available in playbooks or custom functions written in Python 3. Use the supported API instead.

Deprecated API Supported API
artifact_values collect
datastore_get get_list
datastore_present get_list
datastore_add add_list
datastore_set set_list
datastore_delete remove_list
add_attachment vault_add
get_file_info vault_info
get_file_path vault_info
get_vault_item_info vault_info
clear_data clear_object
get_data get_object
save_data save_object

artifact_values

phantom.artifact_values(events, field_name)

This API has been deprecated. Use the collect API instead.

The API is not available to playbooks or custom functions written in Python 3.

actions_done

phantom.actions_done(action_names)

This API has been deprecated. Use the completed API instead.

This API checks to see if all of the actions in the the user given list of action_names have finished executing or not. Succeeded or Failed implies 'Done'. Returns True if and only if all the actions are done or else returns False. The parameter action_names is a list of names given to an action via phantom.act() API in the parameter 'name'.

def join_add_tag_1(action=None, success=None, container=None, results=None,
                   handle=None, filtered_artifacts=None, filtered_results=None):
    # this is a "join" function. It is a callback for 2 separate actions
    # check if all connected incoming actions are done i.e. have succeeded or failed
    # only invoke add_tag_1 when both have completed

    if phantom.actions_done([ 'block_ip_1','block_domain_1' ]):

        # call connected block "add_tag_1"
        add_tag_1(container=container, handle=handle)

    return

add_comment

phantom.add_comment(container, comment)

This API has been deprecated. Use the comment API instead.

This API is used to add a text comment to the container. On completion it returns a tuple of a success flag (boolean) and any response message.

Parameter Required? Description
container Required A container object of which to add a comment.
comment Required A string containing the comment to add to the container.
import phantom.rules as phantom

def on_start(container):

    phantom.add_comment(container, 'Example comment.')

    return

assign

phantom.assign(container, user_id_or_name)

This API has been deprecated. Use the set_owner API instead.

This is an API that allows users to dynamically assign a container to a user.

Parameter Required? Description
container Required The container object for user assignment.
user_id_or_name Required Valid Phantom user name (str) or id (int) to be assigned, or an empty string or None (NoneType) to unassign the container.

Sample playbook:

import phantom.rules as phantom
import json

def on_start(container):
    phantom.assign(container, 'user@company.com')  # assign to user@company.com
    phantom.assign(container, None)  # container unassigned, no user assigned
    return

def on_finish(container, summary):
    return

datastore_add

phantom.datastore_add(list_name, values)

Append a new row of data to the "Custom List" named by "list_name". Values will be converted to a list of strings.

This API has been deprecated. Use the add_list API instead.

The API is not available to playbooks or custom functions written in Python 3.

Here is an example of how to use the API:

import phantom.rules as phantom
import json

def on_start(container):
    #in the product in 'Playbooks / Custom Lists', define a
    # list called 'executives' and then access it here
    phantom.datastore_add('executives', [ 'bob.jones@splunk.com' ] )
    phantom.datastore_add('executives', [ 'susan.smith@splunk.com' ] )
    phantom.debug(execs)
    return

def on_finish(container, summary):
    return

The above will add 2 rows to a 1-column list. First it adds Bob then it adds Susan.

datastore_check

phantom.datastore_check(list_name, value, case_sensitive=False, substring=False)

This API has been deprecated. Use the check_list API instead.

This API allows users to simply test the check whether a value is in the custom list or not in any column. The default behavior is case insensitive and full strings. It returns the number of matching rows in the custom list.

Parameter Required? Description
list_name Required The name of the custom list in which the value has to be checked.
value Required The value that has to be checked.
case_sensitive Optional Default behavior is case insensitive but can be changed with this option.
substring Optional Default behavior is complete string match but can be changed with this option.

datastore_delete

phantom.datastore_delete(list_name)

This API has been deprecated. Use the remove_list API instead.

Completely delete a list. The list will no longer exist and not be available from the UI.

Here is an example of how to use the API:

import phantom.rules as phantom
import json

def on_start(container):
    succeeded, message = phantom.datastore_delete('example')
    phantom.debug(message)
    return

def on_finish(container, summary):
    return

datastore_get

phantom.datastore_get(list_name)

This API has been deprecated. Use the get_list API instead.

The API is not available to playbooks or custom functions written in Python 3.

'Custom Lists' are lists of dictionaries to allow users to manage data that can be referenced in Phantom Playbooks. These lists are available and accessible to the user to maintain in UI Playbooks / Custom Lists.

This API allows programmatic access to these 'Custom Lists' that the users may have defined and setup. For example the users may want to define a set of user names as 'executives' or set of IP addresses as 'test machines' and in the context of a container (container) and artifacts(events) if the user is a member of the 'executives' list, then the course of action may be different or the severity may have to be altered using the 'set_severity' API explained below. Similarly if the IP address on which an event has been detected is a 'test machine' there may not be any reason to act. The result of this call is the full list as defined by the user.

Here is an example of how to use the API:

import phantom.rules as phantom
import json

def on_start(container):
    #in the product in 'Playbooks / Custom Lists', define a
    # list called 'executives' and then access it here
    execs = phantom.datastore_get('executives')
    phantom.debug(execs)
    return

def on_finish(container, summary):
    return

datastore_present

phantom.datastore_present(list_name, values, column_index=-1)

This API has been deprecated. Use the get_list API instead.

The API is not available to playbooks or custom functions written in Python 3.

This API allows users to simply test the presence of a value or values in a list without having to get the entire list which can have thousands of entries.

The last parameter allows users to check the 'values' in the specified column. If the column_index is not specified the values are checked in each row and column of the list.

Here is an example of how to use the API:

import phantom.rules as phantom
import json

def on_start(container):
    #in 'Custom Lists', define a list called 'executives' and then access it here
    data = phantom.datastore_get('executives')
    phantom.debug(str(data))
    result = phantom.datastore_present('executives',['ceo@enterprise.com'])
    phantom.debug(result)
    return


def on_finish(container, summary):
    return
The return value is a JSON object that that has the following structure:

{
  "matches": [
    {
      "index": 0,
      "value": [
        "ceo@enterprise.com",
        "CEO"
      ]
    }
  ]
}

This API has been deprecated. Please use the get_list API instead.

datastore_set

phantom.datastore_set(list_name, values_list_of_lists)

This API has been deprecated. Use the set_list API instead.

The API is not available to playbooks or custom functions written in Python 3.

This API provides the ability to replace the entire contents of a list.

Here is an example of how to use the API:

import phantom.rules as phantom
import json

def on_start(container):
    #in the product in 'Playbooks / Custom Lists', define a
    # list called 'example' with two rows. Creates the list if it does not exist.
    succeeded, message = phantom.datastore_set('example', [ ['a', 'list', 'of', 'values'],
        ['second', 'row'] ])
    phantom.debug(message)
    return

def on_finish(container, summary):
    return

get_action_info

phantom.get_action_info(action,action_run_id,app_run_id,get_results)

This API has been deprecated.

get_vault_item_info

phantom.get_vault_item_info(vault_id=None, get_hashes=False)

This API has been deprecated. Use the vault_info API instead.

save_artifact

phantom.save_artifact(container, raw, cef,label, name, severity, identifier, artifact_type, field_mapping)

This API has been deprecated. Use the add_artifact API instead.

Add a new Artifact to the specified container. On successful artifact creation, this call returns the artifact id.

Parameter Required? Description
container Required The container to which this artifact belongs and need to be associated with.
raw Required The raw artifact data that will be stored as-is and accessible from the artifacts. An empty dictionary can be used, see the following example.
cef Required The CEF representation of the data in original. CEF fields allow users to access the data more easily via the phantom.collect API in playbooks. An empty dictionary can be used, see the following example.
label Required The label expressing the class of artifact. For example event, netflow, AV Alert, etc.
name Required The name of the artifact.
severity Required One of the values 'high', 'medium', 'low', or a custom severity defined by an administrator.
identifier Required The source data identifier for the artifact. Generally this is a unique ID from a data source. A value of None will generate a GUID for the source data identifier.
artifact_type Required The type of the artifact like 'host' or 'network'.
field_mapping Optional If CEF field names are not specific enough, the user can use this parameter to specify the contains type for this field. For example, the playbook could add an artifact whose CEF could have a field named 'user_hash'. Now this parameter can help convey to the platform that 'user_hash' is a hash type of field that can then be used to show contextual actions via mission control. It takes a dictionary with a key of the field name, and a value of a list of contains strings, like this: {'user_hash':['md5']} . This sets user_hash to a contains type of 'md5' and hence any action that supports MD5 as an input parameter will show up in contextual actions.

Here is a sample playbook:

import phantom.rules as phantom
import json
import uuid

def on_start(container):

    artifacts = phantom.collect(container, 'artifacts:*', scope='all')
    phantom.debug(artifacts)

    raw = {}
    cef = {}
    cef['sourceAddress'] = '1.1.1.1'

    artifact_id = phantom.save_artifact(container, raw, cef, label='netflow',
                                        name='test_event', severity='high',
                                        identifier=None,
                                        artifact_type='network')

    phantom.debug('artifact added as id:'+str(artifact_id))

    artifacts = phantom.collect(container, 'artifacts:*', scope='all')
    phantom.debug(artifacts)

    # optionally user can specify a type for custom CEF fields.
    cef['foo'] = 'c8e5728b05c3ac46212c33535b65f183'
    field_mapping = {}
    field_mapping['foo'] = ['md5']

    artifact_id = phantom.save_artifact(container, raw, cef, label='netflow',
                                        name='test_event', severity='high',
                                        identifier=None,
                                        artifact_type='network',
                                        field_mapping=field_mapping)

    phantom.debug('artifact added as id:'+str(artifact_id))

    return


def on_finish(container, summary):

    return

The output of the above playbook in debugger shows the following results:

Thu May 05 2016 14:03:42 GMT-0700 (PDT): Starting playbook '2498' testing on 'incident' id: '79'...
Thu May 05 2016 14:03:42 GMT-0700 (PDT): calling on_start(): on incident 'test_incident', id: 79.
Thu May 05 2016 14:03:42 GMT-0700 (PDT): phantom.collect() called with datapath: artifacts:*, limit = 100 and none_if_first=False
Thu May 05 2016 14:03:42 GMT-0700 (PDT): phantom.collect(): will be limited to return 100 rows by default. To override, please provide limit parameter. 0 implies no limit
Thu May 05 2016 14:03:42 GMT-0700 (PDT): phantom.collect():  called with datapath 'artifacts:*', scope='all' and limit=100. Found 0 TOTAL artifacts
Thu May 05 2016 14:03:42 GMT-0700 (PDT):
[]
Thu May 05 2016 14:03:42 GMT-0700 (PDT): phantom.save_artifact() called
Thu May 05 2016 14:03:42 GMT-0700 (PDT): artifact added as id:122
Thu May 05 2016 14:03:42 GMT-0700 (PDT): phantom.collect() called with datapath: artifacts:*, limit = 100 and none_if_first=False
Thu May 05 2016 14:03:42 GMT-0700 (PDT): phantom.collect(): will be limited to return 100 rows by default. To override, please provide limit parameter. 0 implies no limit
Thu May 05 2016 14:03:42 GMT-0700 (PDT): phantom.collect():  called with datapath 'artifacts:*', scope='all' and limit=100. Found 1 TOTAL artifacts
Thu May 05 2016 14:03:43 GMT-0700 (PDT):
[
    {
        "create_time": 1462482222615,
        "id": 122,
        "severity": "high",
        "label": "netflow",
        "version": 1,
        "type": "network",
        "owner_id": 0,
        "cef": {
            "sourceAddress": "1.1.1.1"
        },
        "update_time": 1462482222615,
        "hash": "4cb608956567e4a95784382de5f81c1b",
        "description": "",
        "tags": [],
        "cef_types": {},
        "start_time": 1462482222615,
        "container_id": 79,
        "kill_chain": "",
        "playbook_run_id": 25,
        "data": {},
        "name": "test_event",
        "ingest_app_id": 0,
        "source_data_identifier": "0617e876-7ca1-407d-bab4-b5c3acf644f3",
        "end_time": 0
    }
]
Thu May 05 2016 14:03:43 GMT-0700 (PDT): phantom.save_artifact() called
Thu May 05 2016 14:03:43 GMT-0700 (PDT): artifact added as id:123
Thu May 05 2016 14:03:43 GMT-0700 (PDT): phantom.collect() called with datapath: artifacts:*, limit = 100 and none_if_first=False
Thu May 05 2016 14:03:43 GMT-0700 (PDT): phantom.collect(): will be limited to return 100 rows by default. To override, please provide limit parameter. 0 implies no limit
Thu May 05 2016 14:03:43 GMT-0700 (PDT): phantom.collect():  called with datapath 'artifacts:*', scope='all' and limit=100. Found 2 TOTAL artifacts
Thu May 05 2016 14:03:43 GMT-0700 (PDT):
[
    {
        "create_time": 1462482222615,
        "id": 122,
        "severity": "high",
        "label": "netflow",
        "version": 1,
        "type": "network",
        "owner_id": 0,
        "cef": {
            "sourceAddress": "1.1.1.1"
        },
        "update_time": 1462482222615,
        "hash": "4cb608956567e4a95784382de5f81c1b",
        "description": "",
        "tags": [],
        "cef_types": {},
        "start_time": 1462482222615,
        "container_id": 79,
        "kill_chain": "",
        "playbook_run_id": 25,
        "data": {},
        "name": "test_event",
        "ingest_app_id": 0,
        "source_data_identifier": "0617e876-7ca1-407d-bab4-b5c3acf644f3",
        "end_time": 0
    },
    {
        "create_time": 1462482223566,
        "id": 123,
        "severity": "high",
        "label": "netflow",
        "version": 1,
        "type": "network",
        "owner_id": 0,
        "cef": {
            "foo": "c8e5728b05c3ac46212c33535b65f183",
            "sourceAddress": "1.1.1.1"
        },
        "update_time": 1462482223566,
        "hash": "03134c15c2df2f7417f3ce360ce75d87",
        "description": "",
        "tags": [],
        "cef_types": {
            "foo": [
                "md5"
            ]
        },
        "start_time": 1462482223566,
        "container_id": 79,
        "kill_chain": "",
        "playbook_run_id": 25,
        "data": {},
        "name": "test_event",
        "ingest_app_id": 0,
        "source_data_identifier": "8dc4e4f8-0d81-4c64-8685-4742bd1d7bce",
        "end_time": 0
    }
]
Thu May 05 2016 14:03:43 GMT-0700 (PDT): No actions were executed
Thu May 05 2016 14:03:43 GMT-0700 (PDT): calling on_finish()
Thu May 05 2016 14:03:43 GMT-0700 (PDT):
Playbook '2498 (id: 58)' executed (playbook_run_id: 25) on incident 'test_incident'(id: 79).
Playbook execution status is:'success'
	No actions were executed for this playbook and 'incident'
Thu May 05 2016 14:03:43 GMT-0700 (PDT): {"message":"No actions were executed","playbook_run_id":25,"result":[],"status":"success"}

When the playbook calls this API, the newly added artifact is not accessible to this instance of playbook run via phantom.collect() API id scope='new'. Hence the sample playbook shown above uses scope='all' in the phantom.collect() call to get all the artifacts including the one that was just added to the container.

add_attachment

phantom.Vault.add_attachment(file_location, container_id, file_name, metadata)

This API has been deprecated. Use the vault_add API instead.

The API is not available to playbooks or custom functions written in Python 3.

Attach a file to a container by adding it to the vault.

Parameter Required? Description
file_location Required The location of the file on the Phantom file system. The file should be written to /opt/phantom/vault/tmp/ directory before calling this API.
container_id Required The container to add the attachment to.
file_name Optional A custom file name. This will show up as the file name in the container's vault files list.
metadata Optional A dictionary adding metadata about the file. Currently the only user-supplied attribute that will be used is "contains" which specifies what kind of information is available. (e.g. metadata={"contains":["pe file"]} tells the system the file is a Windows PE file which will enable actions such as "detonate file".)

The following is an example of what the API returns.

{
    "container": 1,
    "message": "success",
    "vault_id": "41c4e1e9abe08b218f5ea60d8ae41a5f523e7534",
    "succeeded": true,
    "hash": "41c4e1e9abe08b218f5ea60d8ae41a5f523e7534"
}

The following is an example code snippet that can be used to add a file to the vault from the playbook

import phantom.rules as phantom
import json

def on_start(container):

    return

def on_finish(container, summary):

    phantom.Vault.add_attachment("/opt/phantom/vault/tmp/myfile", container['id'],
                        file_name="notepad.exe",
                        metadata={"contains": ["PE File"]})
    return

get_file_path

phantom.Vault.get_file_path(vault_id)

This API has been deprecated. Use the vault_info API instead.

The API is not available to playbooks or custom functions written in Python 3.

Returns the full path of the vault file on the filesystem, given the vault_id.

Parameter Required? Description
vault_id Required The ID of the vault file.

get_file_info

phantom.Vault.get_file_info(vault_id=None, file_name=None, container_id=None)

This API has been deprecated. Use the vault_info API instead.

The API is not available to playbooks or custom functions written in Python 3.

Returns information for all vault items that match either of the input parameters. If neither of the parameters are specified, an empty list is returned.

Parameter Required? Description
vault_id Optional The ID of the vault file.
file_name Optional The name of the vault file.
container_id Optional Container ID to query vault items for. To get the current container_id value from an App which is executing an action, use the return value of BaseConnector::get_container_id().

The following is an example of what the API returns

[
    {
        "container": "Incident # 1",
        "name": "ping.exe",
        "aka": [
            "ping.exe"
        ],
        "metadata": {
            "contains": [
                "pe file"
            ],
            "sha256": "14262982a64551fde126339b22b993b6e4aed520e53dd882e67d887b6b66f942",
            "md5": "5fb30fe90736c7fc77de637021b1ce7c",
            "sha1": "41c4e1e9abe08b218f5ea60d8ae41a5f523e7534"
        },
        "id": 3,
        "container_id": 1,
        "create_time": "37 minutes ago",
        "vault_id": "41c4e1e9abe08b218f5ea60d8ae41a5f523e7534",
        "user": "",
        "vault_document": 3,
        "hash": "41c4e1e9abe08b218f5ea60d8ae41a5f523e7534",
        "path": "/opt/phantom/vault/41/c4/41c4e1e9abe08b218f5ea60d8ae41a5f523e7534",
        "size": 16896
    },
....
....
]

clear_data

Use the clear_data API to clear data stored from the phantom.save_data method and delete it from the persistent store.

This API has been deprecated. Use the clear_object API instead.

The clear_data API is not supported from within a custom function.

phantom.clear_data(key)
Parameter Required? Type Description
key Required String The key provided to or by the save_data API. For more information, see save_data.

get_data

Use the get_data API to return data stored from the phantom.save_data method and delete data from the persistent store if the clear_data parameter is set to the default of True.

This API has been deprecated. Use the get_object API instead.

The get_data API is not supported from within a custom function.

phantom.get_data(key, clear_data=True)
Parameter Required? Type Description
key Required String The key provided to or by the save_data API. For more information, see save_data.

Only JSON-compliant objects, dictionaries, lists, strings, and numbers are supported as objects that can be saved and retrieved.

save_data

Use the save_data API to save the data provided in the value parameter and to return a generated key that can be used to retrieve data. This data can be saved and retrieved within or across playbooks when you provide a matching key. To save and get data across playbook runs, select a fixed name for the key. Only JSON compliant objects, dictionaries, lists, strings, and numbers are supported as objects that can be saved and retrieved.

This API has been deprecated. Use the save_object API instead.

The save_data API is not supported from within a custom function.

phantom.save_data(value, key=None)

This API may return incorrect results if playbook vertical scaling is enabled. Where possible, using unique value:key pairs across playbook runs to mitigate the problem.

Last modified on 02 March, 2021
PREVIOUS
Network automation API
 

This documentation applies to the following versions of Splunk® Phantom (Legacy): 4.10.1, 4.10.2, 4.10.3, 4.10.4, 4.10.6, 4.10.7


Was this documentation topic helpful?


You must be logged into splunk.com in order to post comments. Log in now.

Please try to keep this discussion focused on the content covered in this documentation topic. If you have a more general question about Splunk functionality or are experiencing a difficulty with Splunk, consider posting a question to Splunkbase Answers.

0 out of 1000 Characters