device-security-get-raci

Calculates the responsible and informed parties for a Device Security incident by matching incident and device details against the Device Security configuration list.

python · Device Security by Palo Alto Networks

Details

IDdevice-security-get-raci
Languagepython
From Version6.10.0
Docker Imagedemisto/python3:3.12.13.10404775
Tagsdevice security

README

Calculates the responsible and informed parties for a Device Security incident by matching incident and device details against the Device Security configuration list.

Script Data


Name Description
Script Type python3
Tags device security
Cortex XSOAR Version 6.10.0

Used In


This script is used in the following playbooks and scripts.

  • PANW Device Security Incident Handling with ServiceNow

Inputs


Argument Name Description
incident_name The name of the Device Security incident.
raw_type The raw type of the incident.
category The device category.
profile The device profile.
vendor The device vendor.
model The device model.
device_security_config_list_name The name of the list containing the Device Security configuration.

Outputs


Path Description Type
PaloAltoNetworksDeviceSecurity.RACI.Model The RACI model of the Device Security incident. object
PaloAltoNetworksDeviceSecurity.RACI.Model.r The responsible party in the RACI model. string
PaloAltoNetworksDeviceSecurity.RACI.Model.r_email The email address of the responsible party in the RACI model. string
PaloAltoNetworksDeviceSecurity.RACI.Model.i The informed parties in the RACI model. string
PaloAltoNetworksDeviceSecurity.RACI.Model.i_email The comma-separated email addresses of the informed parties in the RACI model. string
PaloAltoNetworksDeviceSecurity.RACI.Model.owner The Device Security owner of the device. string
PaloAltoNetworksDeviceSecurity.RACI.Model.r_snow The ServiceNow information for the responsible party. object
PaloAltoNetworksDeviceSecurity.RACI.Model.r_snow.fields The fields of the ServiceNow ticket. string
PaloAltoNetworksDeviceSecurity.RACI.Model.r_snow.custom_fields The custom fields of the ServiceNow ticket. string
PaloAltoNetworksDeviceSecurity.RACI.Model.r_snow.table The table of the ServiceNow ticket. string
import json
import re

import demistomock as demisto  # noqa: F401
from CommonServerPython import *  # noqa: F401

from CommonServerUserPython import *  # noqa: E402 lgtm [py/polluting-import]


def get_device_security_config(device_security_config_list_name="DEVICE_SECURITY_CONFIG"):
    device_security_config = demisto.executeCommand("getList", {"listName": device_security_config_list_name})
    if is_error(device_security_config):
        return None
    device_security_config_content = device_security_config[0]["Contents"]
    try:
        return json.loads(device_security_config_content)
    except Exception as e:
        raise ValueError(f"Failed to parse the DEVICE_SECURITY_CONFIG. Error: {e!s}")


def get_raci(args):
    incident_name = args.get("incident_name", "")
    alert_type = args.get("raw_type")

    category = args.get("category", "")
    profile = args.get("profile", "")
    vendor = args.get("vendor", "")
    model = args.get("model", "")
    device_id = f"{category}|{profile}|{vendor}|{model}"

    device_security_config_list_name = args.get("device_security_config_list_name", "DEVICE_SECURITY_CONFIG")
    config = get_device_security_config(device_security_config_list_name)
    if config is None:
        return None

    result = {}

    # determine owner
    owner = None
    for d in config.get("devices", []):
        if "device_id" in d and "owner" in d and re.match(d["device_id"], device_id):
            owner = d["owner"]
    result["owner"] = owner

    # determine raci
    raci = None
    for a in config.get("alerts", []):
        if "device_security_raw_type" in a and "raci" in a and alert_type == a["device_security_raw_type"]:
            match_name = "name_regex" not in a
            if not match_name:
                for n in a["name_regex"]:
                    if re.match(n, incident_name):
                        match_name = True
                        break
            if match_name:
                raci = a["raci"]

    if raci:
        r = raci.get("r")
        if r == "DEVICE_SECURITY_OWNER":
            result["r"] = owner

            if owner is None:
                result["r_email"] = None
                result["r_snow"] = None
            else:
                e = config.get("groups", {}).get(owner, {}).get("email", None)
                if e is None:
                    default_email = config.get("groups", {}).get("DEFAULT", {}).get("email", None)
                    if default_email is not None:
                        result["r_email"] = default_email
                    else:
                        result["r_email"] = None
                else:
                    result["r_email"] = e

            result["r_snow"] = config.get("groups", {}).get(owner, {}).get("snow", None)
        elif r is not None:
            result["r"] = r

            e = config.get("groups", {}).get(r, {}).get("email", None)
            if e is None:
                default_email = config.get("groups", {}).get("DEFAULT", {}).get("email", None)
                if default_email is not None:
                    result["r_email"] = default_email
                else:
                    result["r_email"] = None
            else:
                result["r_email"] = e

            result["r_snow"] = config.get("groups", {}).get(r, {}).get("snow", None)
        else:
            result["r_email"] = None
            result["r_snow"] = None

        r_snow = result.get("r_snow", {})
        if r_snow:
            fields = r_snow.get("fields", {})
            if fields:
                r_snow["fields"] = ";".join([f"{k}={v}" for k, v in fields.items()])
            cfields = r_snow.get("custom_fields", {})
            if cfields:
                r_snow["custom_fields"] = ";".join([f"{k}={v}" for k, v in cfields.items()])

        i = []
        for inform in raci.get("i", []):
            if inform == "DEVICE_SECURITY_OWNER":
                if owner is not None:
                    i.append(owner)
            else:
                i.append(inform)
        result["i"] = ", ".join(i) if i else None

        if i:
            i_email = []
            for entry in i:
                e = config.get("groups", {}).get(entry, {}).get("email", None)
                if e is None:
                    default_email = config.get("groups", {}).get("DEFAULT", {}).get("email", None)
                    if default_email is not None:
                        i_email.append(default_email)
                else:
                    i_email.append(e)
            if len(i_email) > 0:
                result["i_email"] = ", ".join(i_email)
            else:
                result["i_email"] = None
    else:
        result["r"] = None
        result["r_email"] = None
        result["r_snow"] = None
        result["i"] = None
        result["i_email"] = None

    return CommandResults(outputs_prefix="PaloAltoNetworksDeviceSecurity.RACI.Model", outputs_key_field="", outputs=result)


def main():
    try:
        return_results(get_raci(demisto.args()))
    except Exception as ex:
        return_error(f"Failed to execute device-security-get-raci. Error: {ex!s}")


if __name__ in ("__main__", "__builtin__", "builtins"):
    main()