Creating a Custom Action
Overview
In the Building a Custom Integration, we created a Ping Action for the Armis integration. In this tutorial we will create an Action for the Armis integration that enriches entities. Knowledge of Python and object oriented programming is necessary for this tutorial. The SDK documentation and the Building a Custom Integration tutorial will be referenced frequently. Additionally, exploring the SDK modules themselves is highly recommended.
Creating a Custom Action
Navigate to the IDE and click the
icon in the upper left hand corner to Add New IDE Item. Select the Action
radio button, name the Action and select the integration then click the Create
button.
The IDE will create a new template that has some very useful code comments and explanations. Make sure to give this template a look over when possible.
The Siemplify Action Object
There are two things that must happen in a Siemplify Action. An object must be
instantiated from the
SiemplifyAction
class and the object must utilize the class’s
end
method to return an output message and a result value.
The Result Value
Every Action
will have an Output Name that will represent the result value of what the
Siemplify Action returns in its end method. The Default Output Name is
is_success but it can be changed to anything from the IDE.
Additionally a Default Return Value can be set if the Action were to fail. For example, if the Action in the screenshot above were to time out after 5 minutes (or fail for any other reason), the ScriptResult would be set to the string ‘Timeout’.
Default Return Value is important for Playbook logic. In this case you could utilize the Playbook Flow Control of Previous Action Conditions to build out playbook branches if the Action fails.
JSON Result Value
Arguably more important than the actual result value, is the JSON result that
can be added via the Action. The JSON result is NOT mandatory, but it is
extremely useful for pivoting on data within playbooks, or even for eyes on
“manual” investigative analysis. The JSON result can be added via
the SiemplifyAction result property’s
add_result_json
method or via the
add_entity_json
method to attach a JSON result to the entity (not as useful but still covered
here).
Imports and Constants
The SiemplifyAction class from the SiemplifyAction module will always be
imported. The specific methods imported from SiemplifyUtils are not mandatory
but output_handler is very useful for debugging and
add_prefix_to_dict_keys
and
convert_dict_to_json_result_dict
will be utilized for data transformation. The EntityTypes class helps
determine what type of entity the Action will run on. The ArmisManager was
created in the Building a Custom Integration How To and it will be reused for
the Armis API logic. The json library is also imported and a couple of
constants are set.
The Action Logic
This particular Action only has a main function that will be executed. In line
14 the
siemplify
object is instantiated from the SiemplifyAction class. The API Root and the
API Token are imported from the Marketplace Configuration for this
integration; this should look familiar from the Building a Custom Integration
tutorial. In lines 26-27, an empty dictionary and an empty list are created
for use later. A default result value is also set to the string
‘true’ in line 28.
In line 31, an object is instantiated from the
ArmisManager
class. In lines 32-33, we iterate through the entities that exist in the Alert
that this Action is running on.
Remember that Actions run on Alerts! The SiemplifyAction class allows you to retrieve all sorts of useful Case, Alert and Event data via the SDK or the API. Explore the SDK modules and the SDK documentation for more handy methods and properties.
Notice that in line 33, every Entity has an entity_type property and it can be
compared to the properties from the EntityTypes class. In this case, the
entity will only be passed to the Manager’s
get_device_by_ip
method if it’s an IP Address (which is what the ADDRESS property
represents). This prevents the Action from using useless cycles on Entities
that will return errors from the Armis API endpoint. In line 34 notice that we
are passing the entity identifier property. The identifier property is simply
a string representation of the Entity, so an Entity object for the IP Address
of 192.168.1.2 would have an identifier of ‘192.168.1.2’.
In line 36, we utilize the empty dict that we created earlier by setting the
key to the entity identifier and the value to the result returned by the Armis
API endpoint. In line 37, the identifier is appended to the empty list created
earlier. In line 38, the
add_entity_json
method is used to create a JSON result for the entity. This method takes a
mandatory two parameters: the identifier and the result in JSON format. In
line 40, a new empty dict is instantiated for the properties to be used for
enrichment. In lines 41-52, the result from Armis is parsed and added to this
dict. In line 53, the dict is transformed by adding a string prefix of
‘armis’ to the keys. This is done to provide clarity in the
application for what integration provided what enrichment properties within
the entity.
Remember that the Entity itself is an object within the application that retains state and can be enriched by multiple integrations.
In lines 54-56, the entity is updated with the new enrichment properties. Notice in line 55 that the entity object is enriched, not the entity identifier. Also notice that it’s in a list because this method expects a list of objects as input.
In lines 66-69, the output message is set based on whether there are any enriched entities in the list that was created earlier.
Line 72 may be the most important line of code in the Action. Here the
add_result_json
method is used to add an additional result to the Action. The
convert_dict_to_json_result_dict
method that was imported earlier is used to transform the json_results
dictionary where the identifier is set as the key and the value is the
results.
Line 73 ends the action with the output message and the result value. Lines 75 and 76 are mandatory for the Action to run.
Putting it All Together in the Application
Running this Action on an Alert with an Entity Identifier of 192.168.1.41
enriches the Entity with several new properties. Notice the
‘armis’ prefix on the properties that were added via this
Enrichment Action. The values that correspond to the properties are censored
in this screenshot.
We can also look at the Action on the Case Wall. The Output Message and Entity JSON results are on the Results tab:
The Technical Details tab has the Script Result (the result value) and
the JSON results. Again they are censored here.