Universal Cloud REST API connector workflow for IBM Security Randori Recon

You can customize your workflow and workflow parameters based on the default workflow.

A workflow is an XML document that describes the alert retrieval process. The workflow defines one or more parameters, which can be explicitly assigned values in the workflow XML or can derive values from the workflow parameter values XML document. The workflow consists of multiple actions that run sequentially.

IBM Security Randori Recon default workflow

Use the following XML to populate the Workflow field in the Universal Cloud REST API connector parameters section.

Click the Copy to clipboard icon at the upper right of the code block, and then paste the content into the Workflow field.

<?xml version="1.0" encoding="UTF-8" ?>
<Workflow name="IBMSecurityRandoriRecon" version="1.0" xmlns="http://qradar.ibm.com/UniversalCloudRESTAPI/Workflow/V2">
    <Parameters>
        <Parameter name="tenant"     label="The Base URL For the IBM Security Randori Recon instance." required="true" />
        <Parameter name="apiKey"     label="API Key"                     secret="true"                 required="true" />
        <Parameter name="apiVersion" label="API Version"                 default="v1"                  required="true" />
    </Parameters>
    <Actions>
        <ClearStatus />

        <Initialize path="/randoriDetections/starttimeMilli" value="${time() - (60000 * 60 * 24 * 7)}"/> <!-- 7 days previous to initialize -->
        <Set        path="/randoriDetections/endtimeMilli"   value="${time()}"/>

        <Set path="/randoriDetections/dateTimeFormat" value="yyyy-MM-dd'T'HH:mm:ss.SSSX" />

        <FormatDate pattern="${/randoriDetections/dateTimeFormat}" timeZone="UTC" savePath="/randoriDetections/starttime" time="${/randoriDetections/starttimeMilli}"/>
        <FormatDate pattern="${/randoriDetections/dateTimeFormat}" timeZone="UTC" savePath="/randoriDetections/endtime"   time="${/randoriDetections/endtimeMilli}"/>

        <Set path="/randoriDetections/query"           value='{"condition":"AND","rules":[{"field":"table.confidence","operator":"greater_or_equal","value":60},{"field":"table.affiliation_state","operator":"equal","value":"None"},{"condition":"OR","rules":[{"condition":"AND","rules":[{"ui_id":"target_first_seen","id":"table.target_first_seen","field":"table.target_first_seen","type":"datetime","input":"text","randoriOnly":false,"label":"after","operator":"greater_or_equal","value":"${/randoriDetections/starttime}"},{"ui_id":"target_first_seen","id":"table.target_first_seen","field":"table.target_first_seen","type":"datetime","input":"text","randoriOnly":false,"label":"before","operator":"less","value":"${/randoriDetections/endtime}"}]},{"condition":"AND","rules":[{"field":"table.temptation_last_modified","id":"table.temptation_last_modified","input":"text","type":"datetime","ui_id":"temptation_last_modified","randoriOnly":false,"label":"after","operator":"greater_or_equal","value":"${/randoriDetections/starttime}"},{"field":"table.temptation_last_modified","id":"table.temptation_last_modified","input":"text","type":"datetime","ui_id":"temptation_last_modified","randoriOnly":false,"label":"before","operator":"less","value":"${/randoriDetections/endtime}"}]}]}]}'/>
        <Set path="/randoriDetections/detectionOffset" value="0"/>
        <Set path="/randoriDetections/limit"           value="100"/>
        <Set path="/randoriDetections/fullUrl"         value="https://${/tenant}/recon/api/${/apiVersion}/all-detections-for-target" />
        <Log type="INFO" message="Full Request: GET - ${/randoriDetections/fullUrl}" />
        <Log type="INFO" message="Using limit=${/randoriDetections/limit}" />
        <DoWhile condition="${/randoriDetections/detections/body/count} = ${/randoriDetections/limit}"> <!-- If we have hit our limit of 100, then we want to query it again.-->
            <CallEndpoint url="${/randoriDetections/fullUrl}" method="GET" savePath="/randoriDetections/detections">
                <BearerAuthentication token="${/apiKey}" />
                <QueryParameter name="limit"        value="${/randoriDetections/limit}" />
                <QueryParameter name="offset"       value="${/randoriDetections/detectionOffset}" />
                <QueryParameter name="sort"         value="id" />
                <QueryParameter name="q"            value="${base64_encode(/randoriDetections/query)}" />
                <RequestHeader  name="Accept"       value="application/json" />
                <RequestHeader  name="Content-Type" value="application/json" />
            </CallEndpoint>

            <!-- _________________________ Catch any status code other than 200 (success). Note 502's for this protocol are throttle issues. _________________________ -->
            <If condition="${/randoriDetections/detections/status_code} != 200">
                <If condition="${/randoriDetections/detections/status_code} = 502">
                    <Log type="ERROR" message="A 502 exception indicates the API throttle limit was hit." />
                </If>
                <Log type="ERROR" message="${/randoriDetections/detections/status_code}: ${/randoriDetections/detections/status_message}" />
                <Abort reason="${/randoriDetections/detections/status_code}: ${/randoriDetections/detections/status_message}" />
            </If>
            <Else>
                <SetStatus type="INFO" message="Successfully Queried for events."/>
            </Else>

            <PostEvents path="/randoriDetections/detections/body/data" source="${/tenant}" />

            <Log type="DEBUG" message="Queried endpoint and received ${count(/randoriDetections/detections/body/data)} detections." />
            <Set path="/randoriDetections/detectionOffset" value="${/randoriDetections/detectionOffset + count(/randoriDetections/detections/body/data)}"/>
            <Log type="DEBUG" message="New offset to use: ${/randoriDetections/detectionOffset}" />
        </DoWhile>

        <SetStatus type="INFO" message="Completed receiving all of the detections for the current time period, from ${/randoriDetections/starttime} to ${/randoriDetections/endtime}" />
        <Log       type="INFO" message="Completed receiving all of the detections for the current time period, from ${/randoriDetections/starttime} to ${/randoriDetections/endtime}" />

        <ParseDate pattern="${/randoriDetections/dateTimeFormat}" timeZone="UTC" date="${/randoriDetections/endtime}" savePath="/randoriDetections/starttimeMilli" />
        <Delete path="/randoriDetections/detections" />
        <Delete path="/randoriDetections/fullUrl" />
        <Delete path="/randoriDetections/query" />
    </Actions>

    <Tests>
        <DNSResolutionTest              host="${/tenant}"/>
        <TCPConnectionTest              host="${/tenant}"/>
        <SSLHandshakeTest               host="${/tenant}"/>
        <HTTPConnectionThroughProxyTest  url="${/tenant}"/>
    </Tests>
</Workflow>

IBM Security Randori Recon default workflow parameters

If you are using the OAuth client credentials to configure the data source, use the following XML to populate the Workflow Parameter Values field in the Universal Cloud REST API connector parameters section.

  1. Click the Copy to clipboard icon at the upper right of the code block, and then paste the content to a text file.
  2. Replace the values for <tenant>, <apiKey>, and <apiVersion> with your own values.
  3. Copy the updated content into the Workflow Parameter Values field.
<?xml version="1.0" encoding="UTF-8" ?>
<WorkflowParameterValues xmlns="http://qradar.ibm.com/UniversalCloudRESTAPI/WorkflowParameterValues/V2">
    <Value name="tenant" 	value="The Base URL for your IBM Security Randori Recon instance"/>
    <Value name="apiKey" 	value="your-api-key"/>
    <Value name="apiVersion" value="v1"/>
</WorkflowParameterValues>