resilient¶
Python client module for the IBM SOAR REST API
API Client¶
- class SimpleClient(org_name=None, base_url=None, proxies=None, verify=None, cache_ttl=240, certauth=None, custom_headers=None, **kwargs)¶
Python helper class for using the IBM SOAR REST API.
''' An example script showing how to connect and get incidents with IBM Security SOAR Example Usage: python sample_connect.py "https://<host>", "<org_name>", "<api_key_id>", "<api_key_secret>", "<path_to_ca_file>|False" ''' import sys import os from resilient import SimpleClient def main(): args = sys.argv assert len(args) == 6 SCRIPT_NAME = args[0] # Get required parameters HOST = args[1] ORG_NAME = args[2] API_KEY_ID = args[3] API_KEY_SECRET = args[4] # Check if using cafile ca_file = args[5] VERIFY = ca_file if os.path.isfile(ca_file) is True else False # Instansiate SimpleClient res_client = SimpleClient( org_name=ORG_NAME, base_url=HOST, verify=VERIFY ) # Set the API Key res_client.set_api_key( api_key_id=API_KEY_ID, api_key_secret=API_KEY_SECRET ) # Setup the request payload payload = { "filters": [ { "conditions": [{"field_name": "plan_status", "method": "equals", "value": "A"}] } ] } # Invoke the request response = res_client.post("/incidents/query_paged?return_level=full", payload=payload) # Print results for incident in response.get("data", []): print("{0}: {1}".format(incident.get("id"), incident.get("name"))) if __name__ == "__main__": main()
Note
The full REST API Documentation for IBM SOAR can be viewed on the Platform itself by searching for the REST API Reference or by going to:
https://<base_url>/docs/rest-api/index.html
- __init__(org_name=None, base_url=None, proxies=None, verify=None, cache_ttl=240, certauth=None, custom_headers=None, **kwargs)¶
- Parameters:
org_name (str) – The name of the organization to use.
base_url (str) – The base URL of the SOAR server, e.g.
https://soar.ibm.com/
proxies (dict) – A dictionary of
HTTP
proxies to use, if any.verify (str|bool) – The path to a
PEM
file containing the trusted CAs, orFalse
to disable all TLS verificationcache_ttl (int) – Time in seconds to live for cached API responses
certauth (str|tuple(str, str)) – The filepath for the client side certificate and the private key either as a single file or as a tuple of both files’ paths
custom_headers (dict) – A dictionary of any headers you want to send in every request
kwargs (dict) –
A dictionary of any other keyword arguments including;
max_connection_retries (int) - Number of attempts to retry when connecting to SOAR. Use
-1
for unlimited retries. Defaults to-1
.request_max_retries (int) - Max number of times to retry a request to SOAR before exiting. Defaults to
5
.request_retry_delay (int) - Number of seconds to wait between retries. Defaults to
2
.request_retry_backoff (int) - Multiplier applied to delay between retry attempts. Defaults to
2
.
- cached_get(uri, co3_context_token=None, timeout=None, skip_retry=[])¶
Same as
get()
, but checks cache first
- connect(email, password, timeout=None)¶
Connect and authenticate to the IBM SOAR REST API service.
- Parameters:
email (str) – The email address to use for authentication.
password (str) – The password.
timeout (int) – optional timeout (seconds)
- Returns:
The IBM SOAR session object.
- Raises:
SimpleHTTPException – if an HTTP exception occurs.
- delete(uri, co3_context_token=None, timeout=None, skip_retry=[])¶
Deletes the specified URI.
Note
This URI is relative to
<base_url>/rest/orgs/<org_id>
. So for example, if you specify a uri of/incidents
, the actual URL would be something like:https://soar.ibm.com/rest/orgs/201/incidents
- Parameters:
uri (str) – Relative URI of the resource to delete.
co3_context_token (str) – The
Co3ContextToken
from an Action Module message, if available.timeout (int) – Optional timeout (seconds).
- Raises:
SimpleHTTPException – if an HTTP exception occurs.
- get(uri, co3_context_token=None, timeout=None, is_uri_absolute=None, get_response_object=None, skip_retry=[])¶
Gets the specified URI.
Note
This URI is relative to
<base_url>/rest/orgs/<org_id>
. So for example, if you specify a uri of/incidents
, the actual URL would be something like:https://soar.ibm.com/rest/orgs/201/incidents
- Parameters:
uri (str) – Relative URI of the resource to fetch.
co3_context_token (str) – The
Co3ContextToken
from an Action Module message, if available.timeout (int) – Optional timeout (seconds).
is_uri_absolute (bool) – if True, does not insert /org/{org_id} into the uri.
get_response_object (bool) – if True, returns entire response object.
- Returns:
A dictionary, list, or response object with the value returned by the server.
- Return type:
dict | list | Response
- Raises:
SimpleHTTPException – if an HTTP exception occurs.
- get_const(co3_context_token=None, timeout=None)¶
Get the
ConstREST
endpoint.Endpoint for retrieving various constant information for this server. This information is useful in translating names that the user sees to IDs that other REST API endpoints accept.
For example, the
incidentDTO
has a field called"crimestatus_id"
. The valid values are stored inconstDTO.crime_statuses
.- Parameters:
co3_context_token (str) – The
Co3ContextToken
from an Action Module message, if available.timeout (int) – Optional timeout (seconds).
- Returns:
ConstDTO
as a dictionary- Return type:
dict
- Raises:
SimpleHTTPException – if an HTTP exception occurs.
- get_content(uri, co3_context_token=None, timeout=None, skip_retry=[])¶
Gets the specified URI.
Note
This URI is relative to
<base_url>/rest/orgs/<org_id>
. So for example, if you specify a uri of/incidents
, the actual URL would be something like:https://soar.ibm.com/rest/orgs/201/incidents
- Parameters:
uri (str) – Relative URI of the resource to fetch.
co3_context_token (str) – The
Co3ContextToken
from an Action Module message, if available.timeout (int) – Optional timeout (seconds).
- Returns:
The raw value returned by the server for this resource.
- Return type:
dict
- Raises:
SimpleHTTPException – if an HTTP exception occurs.
- get_put(uri, apply_func, co3_context_token=None, timeout=None)¶
Safely performs an update operation by a GET, calls your
apply_func
callback, then PUT with the updated value. If the put call returns a409
error, these steps are retried.Note
This URI is relative to
<base_url>/rest/orgs/<org_id>
. So for example, if you specify a uri of/incidents
, the actual URL would be something like:https://soar.ibm.com/rest/orgs/201/incidents
- Parameters:
uri (str) – Relative URI of the resource to get and update.
apply_func (func) – A callback function that you implement to update the resource. The function must be of the following form:
def my_apply_func(object_to_update)
, and update the object. If your callback raisesresilient.NoChange
, the update is skipped.co3_context_token (str) – The
Co3ContextToken
from an Action Module message, if available.timeout (int) – Optional timeout (seconds).
- Returns:
A dictionary or list with the value returned by the PUT operation.
- Return type:
dict | list
- Raises:
SimpleHTTPException – if an HTTP exception occurs.
- patch(uri, patch, co3_context_token=None, timeout=None, overwrite_conflict=False)¶
PATCH request to the specified URI.
Note
This URI is relative to
<base_url>/rest/orgs/<org_id>
. So for example, if you specify a uri of/incidents
, the actual URL would be something like:https://soar.ibm.com/rest/orgs/201/incidents
- Parameters:
uri (str) – Relative URI of the resource to patch.
patch (
Patch
) – ThePatch
object to applyco3_context_token (str) – The
Co3ContextToken
from an Action Module message, if available.timeout (int) – Optional timeout (seconds).
overwrite_conflict (bool) – always overwrite fields in conflict. If
True
, the passed-in patch object will be modified if necessary.
- Returns:
the
response
from the endpoint.- Return type:
- Raises:
SimpleHTTPException – if an HTTP exception or patch conflict occurs.
PatchConflictException – If the patch failed to apply (and overwrite_conflict is False).
- patch_with_callback(uri, patch, callback, co3_context_token=None, timeout=None)¶
PATCH request to the specified URI. If the patch application fails because of field conflicts, the specified callback is invoked, allowing the caller to adjust the patch as necessary.
- Parameters:
uri – Relative URI of the resource to patch.
patch (
Patch
) – ThePatch
object to applycallback (func) – Function/lambda to invoke when a patch conflict is detected. The function/lambda must be of the following form:
def my_callback(response, patch_status, patch)
. If your callback raisesresilient.NoChange
, the update is skipped.co3_context_token (str) – The
Co3ContextToken
from an Action Module message, if available.timeout (int) – Optional timeout (seconds).
- Returns:
the
response
from the endpoint.- Return type:
- post(uri, payload, co3_context_token=None, timeout=None, headers=None, skip_retry=[], **kwargs)¶
Posts to the specified URI.
Note
This URI is relative to
<base_url>/rest/orgs/<org_id>
. So for example, if you specify a uri of/incidents
, the actual URL would be something like:https://soar.ibm.com/rest/orgs/201/incidents
- Parameters:
uri (str) – Relative URI of the resource to post.
payload (dict) – A dictionary value to be posted.
co3_context_token (str) – The
Co3ContextToken
from an Action Module message, if available.timeout (int) – Optional timeout (seconds).
headers (dict) – Optional headers to include.
- Returns:
A dictionary or list with the value returned by the server.
- Return type:
dict | list
- Raises:
SimpleHTTPException – if an HTTP exception occurs.
- post_attachment(uri, filepath, filename=None, mimetype=None, data=None, co3_context_token=None, timeout=None, bytes_handle=None, skip_retry=[])¶
Upload a file to the specified URI e.g.
/incidents/<id>/attachments
(for incident attachments) or/tasks/<id>/attachments
(for task attachments)Warning
Please see our updated
resilient_lib.write_file_attachment
as this method takes a data stream and is more reliable- Parameters:
uri (str) – Relative URI of the resource to post.
filepath (str) – the path of the file to post
filename (str) – optional name of the file when posted
mimetype (str) – optional override for the guessed MIME type
data (dict) – optional dict with additional
MIME
parts (not required for file attachments; used in artifacts)co3_context_token (str) – The
Co3ContextToken
from an Action Module message, if available.timeout (int) – Optional timeout (seconds).
bytes_handle (BytesIO) – BytesIO handle for content or use filepath
- Returns:
the
response
from the endpoint.- Return type:
- put(uri, payload, co3_context_token=None, timeout=None, headers=None, skip_retry=[])¶
Directly performs an update operation by PUT to the specified URI.
Note
This URI is relative to
<base_url>/rest/orgs/<org_id>
. So for example, if you specify a uri of/incidents
, the actual URL would be something like:https://soar.ibm.com/rest/orgs/201/incidents
- Parameters:
uri (str) – Relative URI of the resource to update.
payload (dict) – The object to update.
co3_context_token (str) – The
Co3ContextToken
from an Action Module message, if available.timeout (int) – Optional timeout (seconds).
headers (dict) – Optional headers to include.
- Returns:
A dictionary or list with the value returned by the server.
- Return type:
dict | list
- Raises:
SimpleHTTPException – if an HTTP exception occurs.
- search(payload, co3_context_token=None, timeout=None)¶
Posts to the
SearchExREST
endpoint.Endpoint for performing full text searches through incidents and incident child objects (tasks, incident comments, task comments, milestones, artifacts, incident attachments, task attachments, and data tables).
- Parameters:
payload (dict) – The SearchExInputDTO parameters for performing a search.
co3_context_token (str) – The
Co3ContextToken
from an Action Module message, if available.timeout (int) – Optional timeout (seconds).
- Returns:
List of results, as an array of
SearchExResultDTO
- Return type:
list
- Raises:
SimpleHTTPException – if an HTTP exception occurs.
- exception SimpleHTTPException(response)¶
Exception for HTTP errors.
- exception PatchConflictException(response, patch_status)¶
Exception for patch conflicts.
- exception NoChange¶
Exception that can be raised within a get/put handler or a patch callback to indicate ‘no change’ (which then just bypasses the update operation).
Change Log¶
2024-07: version 51.0.2.2 * Update dependency version of setuptools version to 70.3.x to address CVE-2024-6345
2024-07: version 51.0.2.1
All IBM SOAR Python libraries now only officially support Python 3.9, 3.11, and 3.12. To continue using SOAR libraries on earlier versions of Python, use v52.0.2.0.974
Fix for secret substitution when value starts with “^” but is not intended to be substituted
2024-05: version 51.0.2.0
Added official support for Python 3.12
2024-04: version 51.0.1.1
Updated
jwcrypto
dependency requirement to~= 1.5.6
(for Python 3.9 and 3.11) to address CVE-2024-28102 Note that Python 3.6 and Python 2.7 are no longer receiving security updates and should be moved away from immediately. See previous release below for details on our support for Python 3.11
2024-02: version 51.0.1.0
All SOAR Python libraries now officially support Python 3.11
All SOAR Python libraries are now published in a docker container format on Quay.io. This is to better support our apps build process to include the latest SOAR libraries in the base image. This also allows us to better control the OS and Python dependencies that appear in the eventual app container. To take advantage of this new image in your app see the SDK Change Log. The new base image is hosted on quay.io. The default Python version is 3.11 and the image can be pulled manually with:
$ docker pull quay.io/ibmresilient/soarapps-base-docker-image:latest # latest libraries with Python 3.11 $ docker pull quay.io/ibmresilient/soarapps-base-docker-image:python-39 # latest libraries with Python 3.9
Updated
jwcrypto
dependency requirement to~= 1.5.2
(for Python 3.9 and 3.11) to address CVE-2023-6681Pinned
jwcrypto
to== 1.5.1
for Python 3.6 since1.5.2
is no longer 3.6 compatible
2023-11: version 51.0.0.0
Changed the version of
resilient
(and all other SOAR Python libraries) to match the new v.r.m.f scheme that SOAR v51.0.0.0 introduced
2023-10: version 50.1
Improved options for skipping retry with certain exit codes received by REST methods in
SimpleClient
resilient.RetryHTTPException
now inherits fromresilient.BasicHTTPException
for improved error handlingBug fix for
resilient.app_config.AppConfigManager
when using Jinja2 to render values from app.config. This fix is only applicable to Python 3 and cannot be fixed in Python 2Improved obfuscation of potential secrets in logs
2023-08: version 50.0
Adding a deprecation warning for use of Email and Password for authentication. This is still supported but will become unsupported in the future. Any integration servers using email and password to authenticate should consider moving to API Keys as soon as possible
2023-07: version 49.1
Bug fix for protected secrets which ended in
$}
2023-05: version 49.0
Added logic to skip retry logic for failed API calls in
resilient.SimpleClient.post()
,resilient.SimpleClient.put()
andresilient.SimpleClient.get_put()
Added
resilient-app-config-plugins
as a new package to manage third party credentials within SOAR apps
2023-05: version 48.2
Update version of requests-toolbelt to v1.0 to support urllib3 v2.0
2023-04: version 48.1
REST client updated to use
include_permissions=false
by default when authenticating to/rest/session
endpoint. This will give improved performance for SOAR instances with large organizations.
2023-02: version 48.0
Updated project to use
pyproject.toml
andsetup.cfg
metadata files. Build backend continues to usesetuptools
. Instead of directly invoking setup.py to get a sdist or wheel, usebuild
as a build frontend:pip install build python -m build
2022-12: version 47.1
Support for custom headers when using
resilient.SimpleClient.post()
andresilient.SimpleClient.put()
2022-11: version 47.0
Added more general retry logic to our
get
,post
anddelete
request methods. All of which can be configured by specifying any of the following parameters in theSimpleClient
classmax_connection_retries - Number of attempts to retry when connecting to SOAR. Use
-1
for unlimited retries. Defaults to-1
.request_max_retries - Max number of times to retry a request to SOAR before exiting. Defaults to
5
.request_retry_delay - Number of seconds to wait between retries. Defaults to
2
.request_retry_backoff - Multiplier applied to delay between retry attempts. Defaults to
2
.
Now support Protected Secrets. If running on the Edge Gateway (formally App Host) and there are encrypted secrets in JSON Web Key format, in the
/etc/secrets
directory, we will use thejwe
andjwk
libraries in jwcrypto to decrypt the secret and make it available in your app
2022-08: version 46.0
Added some retry logic to
resilient.SimpleClient.post_attachment()
. If a response code of409
is received we retry adding the attachment
2022-07: version 45.1
No major changes. Just bumping build number to coincide with other builds
2022-05: version 45.0
The
org
config can now specify any of the organization’scloud_account
,uuid
orname
Removed the
User-Agent
header for all requestsAdded a custom header for all requests that will include the current version of the library:
Resilient-Module-Version: 45.0.0
The optional
client_auth_cert
andclient_auth_key
app.config parameters have been added to specify the respective paths to client side certificates and client side certificate private keys
2022-04: version 44.1
Better logging of an
Unauthorized
request with API Keys and exits with a code of21
Added optional
get_response_object
argument toresilient.SimpleClient.get()
that ifTrue
, returns entire response object
2022-02: version 44.0
Ensure
tests/
is not included in packaged codeAdded
is_uri_absolute
argument toresilient.SimpleClient.get()
that ifTrue
, does not insert/org/{org_id}
into the uriOfficially support
Python 3.9
2022-01: version 43.1
Ability to globally check if
unrecognized arguments
are allowed
2021-11: version 43.0
Formatted Sphinx documentation and hosted it at https://ibm.biz/soar-python-docs
2021-11: version 42.3
No major changes. Just bumping build number to coincide with other builds
2021-10: version 42.2
Bug fix for
pip >= 21.3
2021-08: version 42.1
Bug fix removing pinned
urllib3
dependency
2021-08: version 42.0
Added support for
HTTP_PROXY
,HTTPS_PROXY
andNO_PROXY
environmental variables. See the App Host Deployment Guide for details.Add new
User-Agent: soar-app-1.0
header for API calls to SOAR platform.Bug fixes.
2021-06: version 41.1
No major changes. Just bumping build number to coincide with other builds
2021-05: version 41.0
No major changes. Just bumping build number to coincide with other builds
2021-03: version 40.2
Bug fix for to use
setuptools_scm < 6.0.0
for Python 2.7 environments
2021-03: version 40.1
No major changes. Just bumping build number to coincide with other builds
2021-02: version 40.0
Bump minimum
requests
version to 2.25.0
2020-07-15: version 37.2
Bug fix for proxy in python 3.
2020-01-16: version 35.0.195
Moved ImportDefinition from
resilient-circuits
Added –resilient-mock parameter
2019-08-02: version 33.0.189
Minor bug fixes.
2019-07-03: version 32.0.186
Fix for deprecated log warnings
Other minor bug fixes
2019-04-12: version 32.0.140
No major changes. Just bumping build number to coincide with other builds
2019-03-06: version 32.0.126
No major changes. Just bumping build number to coincide with other builds
2019-01-15: version 32.0
No major changes. Just bumping build number to coincide with other builds
2018-12-05: version 31.0
Bug Fixes
2018-04-15: version 30.0
Fix an issue with keyring values outside the
[resilient]
config section
2018-02-22: version 29.1.0
Fix an issue with performance receiving STOMP messages
2017-12-12: version 29.0.1
Fix an issue with backward compatibility between
co3
andresilient
package names
2017-12-01: version 29.0.0
Refactoring base class to support minimal environments
2017-09-01: version 28.2.1
- rename
co3
package toresilient
Note
note The module
co3
is retained for backward compatibility, and most applications will still work usingimport co3
after this change. Applications that import from submodules (import co3.co3.xxx
) must be changed to import fromresilient
instead.
- rename
2017-08-24: version 28.1.
add
patch
method toSimpleClient
for efficient field-level updates
2017-06-22: version 28.0.33
disable the ConfigParser
%
interpolation feature
2017-06-14: version 28.0.30
Add get_const() to get the ConstREST endpoint
- Add search() to post to the SearchExREST endpoint (only for v28+ servers)
(Note: there is no method to call the deprecated
searchREST
endpoint from earlier versions)
Fix proxy support, adding config options: proxy_host, proxy_port, proxy_user, proxy_password
Remove
stomp.py
dependency,resilient_circuits
now uses stompest libraryNew
res-keyring
command-line utility to store secrets in the keyring- Move the keyring and env argument parser from
resilient_circuits
into co3, so all config files can make use of
^xxx
(keyring) and$xxx
(environment) values
- Move the keyring and env argument parser from
Add a dependency on
keyring
package
2017-04-27: version 27.1.22
Remove
dist
, instead releases are available on https://github.com/Co3Systems/co3-api/releasesMinor modifications to automated build numbering
2017-04-21: version 27.1.13
Remember the available orgs that the user can log in to
Add
post_artifact_file
method to support posting file (binary) artifactsAdd
cached_get
method and--cache-ttl
commandline optionAdd
get_client
helper function to properly construct a SimpleClient from optionsFor Debian OS, specify exact version of the
keyring
dependencyUse configuration file ($APP_CONFIG_FILE or ./app.config or ~/.resilient/app.config) for utility scripts
Move the utility scripts
gadget
andfinfo
into the co3 module, installed as executablesAdd support for tests
2017-02-17: version 27.0.0
Support UTF8 strings in co3 module
Support UTF8 characters in configuration files
Add optional
timeout
parameter to REST callsAdd
NoChange
to optimize get/putFix
post_attachment()
to guess MIME-type based on the filename