{
    "definition": {
        "metadata": {
            "notes": {}
        },
        "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
        "contentVersion": "1.0.0.0",
        "triggers": {
            "Microsoft_Sentinel_incident": {
                "type": "ApiConnectionWebhook",
                "inputs": {
                    "host": {
                        "connection": {
                            "name": "@parameters('$connections')['azuresentinel-4']['connectionId']"
                        }
                    },
                    "body": {
                        "callback_url": "@listCallbackUrl()"
                    },
                    "path": "/incident-creation"
                }
            }
        },
        "actions": {
            "Get_incident": {
                "runAfter": {},
                "type": "ApiConnection",
                "inputs": {
                    "host": {
                        "connection": {
                            "name": "@parameters('$connections')['azuresentinel-4']['connectionId']"
                        }
                    },
                    "method": "post",
                    "body": {
                        "incidentArmId": "@triggerBody()?['object']?['id']"
                    },
                    "path": "/Incidents"
                }
            },
            "Get_Analytic_Rule": {
                "runAfter": {
                    "Get_incident": [
                        "Succeeded"
                    ]
                },
                "type": "Http",
                "inputs": {
                    "uri": "https://management.azure.com@{first(triggerBody()?['object']?['properties']?['relatedAnalyticRuleIds'])}?api-version=2023-02-01",
                    "method": "GET",
                    "authentication": {
                        "type": "ManagedServiceIdentity"
                    }
                }
            },
            "Entities_-_Get_URLs": {
                "runAfter": {
                    "Get_incident": [
                        "Succeeded"
                    ]
                },
                "type": "ApiConnection",
                "inputs": {
                    "host": {
                        "connection": {
                            "name": "@parameters('$connections')['azuresentinel-4']['connectionId']"
                        }
                    },
                    "method": "post",
                    "body": "@triggerBody()?['object']?['properties']?['relatedEntities']",
                    "path": "/entities/url"
                }
            },
            "Entities_-_Get_IPs": {
                "runAfter": {
                    "Get_incident": [
                        "Succeeded"
                    ]
                },
                "type": "ApiConnection",
                "inputs": {
                    "host": {
                        "connection": {
                            "name": "@parameters('$connections')['azuresentinel-4']['connectionId']"
                        }
                    },
                    "method": "post",
                    "body": "@triggerBody()?['object']?['properties']?['relatedEntities']",
                    "path": "/entities/ip"
                }
            },
            "Entities_-_Get_Accounts": {
                "runAfter": {
                    "Get_incident": [
                        "Succeeded"
                    ]
                },
                "type": "ApiConnection",
                "inputs": {
                    "host": {
                        "connection": {
                            "name": "@parameters('$connections')['azuresentinel-4']['connectionId']"
                        }
                    },
                    "method": "post",
                    "body": "@triggerBody()?['object']?['properties']?['relatedEntities']",
                    "path": "/entities/account"
                }
            },
            "Entities_-_Get_Hosts": {
                "runAfter": {
                    "Get_incident": [
                        "Succeeded"
                    ]
                },
                "type": "ApiConnection",
                "inputs": {
                    "host": {
                        "connection": {
                            "name": "@parameters('$connections')['azuresentinel-4']['connectionId']"
                        }
                    },
                    "method": "post",
                    "body": "@triggerBody()?['object']?['properties']?['relatedEntities']",
                    "path": "/entities/host"
                }
            },
            "Entities_-_Get_FileHashes": {
                "runAfter": {
                    "Get_incident": [
                        "Succeeded"
                    ]
                },
                "type": "ApiConnection",
                "inputs": {
                    "host": {
                        "connection": {
                            "name": "@parameters('$connections')['azuresentinel-4']['connectionId']"
                        }
                    },
                    "method": "post",
                    "body": "@triggerBody()?['object']?['properties']?['relatedEntities']",
                    "path": "/entities/filehash"
                }
            },
            "Parse_Alerts_Array": {
                "runAfter": {
                    "Get_incident": [
                        "Succeeded"
                    ]
                },
                "type": "ParseJson",
                "inputs": {
                    "content": "@triggerBody()?['object']?['properties']?['alerts']",
                    "schema": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "properties": {
                                    "type": "object",
                                    "properties": {
                                        "alertDisplayName": {
                                            "type": "string"
                                        },
                                        "timeGenerated": {
                                            "type": "string"
                                        },
                                        "additionalData": {
                                            "type": "object",
                                            "properties": {
                                                "Query": {
                                                    "type": "string"
                                                },
                                                "Query Start Time UTC": {
                                                    "type": "string"
                                                },
                                                "Query End Time UTC": {
                                                    "type": "string"
                                                },
                                                "Analytic Rule Ids": {
                                                    "type": "string"
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            },
            "Compose_Incident_Time": {
                "runAfter": {
                    "Get_incident": [
                        "Succeeded"
                    ]
                },
                "type": "Compose",
                "inputs": "@coalesce(triggerBody()?['object']?['properties']?['createdTimeUtc'], utcNow())"
            },
            "Compose_Worker_Payload": {
                "runAfter": {
                    "Entities_-_Get_URLs": [
                        "Succeeded",
                        "Failed",
                        "Skipped",
                        "TimedOut"
                    ],
                    "Entities_-_Get_IPs": [
                        "Succeeded",
                        "Failed",
                        "Skipped",
                        "TimedOut"
                    ],
                    "Entities_-_Get_Accounts": [
                        "Succeeded",
                        "Failed",
                        "Skipped",
                        "TimedOut"
                    ],
                    "Entities_-_Get_Hosts": [
                        "Succeeded",
                        "Failed",
                        "Skipped",
                        "TimedOut"
                    ],
                    "Entities_-_Get_FileHashes": [
                        "Succeeded",
                        "Failed",
                        "Skipped",
                        "TimedOut"
                    ],
                    "Get_Analytic_Rule": [
                        "Succeeded",
                        "Failed",
                        "Skipped",
                        "TimedOut"
                    ],
                    "Parse_Alerts_Array": [
                        "Succeeded",
                        "Failed",
                        "Skipped",
                        "TimedOut"
                    ],
                    "Compose_Incident_Time": [
                        "Succeeded"
                    ]
                },
                "type": "Compose",
                "inputs": {
                    "incidentId": "@body('Get_incident')?['name']",
                    "incidentArmId": "@triggerBody()?['object']?['id']",
                    "incidentTitle": "@body('Get_incident')?['properties']?['title']",
                    "incidentSeverity": "@body('Get_incident')?['properties']?['severity']",
                    "incidentStatus": "@body('Get_incident')?['properties']?['status']",
                    "incidentDescription": "@body('Get_incident')?['properties']?['description']",
                    "incidentTime": "@outputs('Compose_Incident_Time')",
                    "analyticRuleQuery": "@body('Get_Analytic_Rule')?['properties']?['query']",
                    "alerts": "@body('Parse_Alerts_Array')",
                    "urls": "@coalesce(body('Entities_-_Get_URLs')?['URLs'], json('[]'))",
                    "ips": "@coalesce(body('Entities_-_Get_IPs')?['IPs'], json('[]'))",
                    "accounts": "@coalesce(body('Entities_-_Get_Accounts')?['Accounts'], json('[]'))",
                    "hosts": "@coalesce(body('Entities_-_Get_Hosts')?['Hosts'], json('[]'))",
                    "fileHashes": "@coalesce(body('Entities_-_Get_FileHashes')?['Filehashes'], json('[]'))"
                }
            },
            "Select_Account_Names": {
                "runAfter": {
                    "Compose_Worker_Payload": [
                        "Succeeded"
                    ]
                },
                "type": "Select",
                "inputs": {
                    "from": "@coalesce(body('Entities_-_Get_Accounts')?['Accounts'], json('[]'))",
                    "select": "@toLower(concat(item()?['accountName'], if(not(empty(coalesce(item()?['upnSuffix'], ''))), concat('@', item()?['upnSuffix']), '')))"
                }
            },
            "Select_Host_Names": {
                "runAfter": {
                    "Compose_Worker_Payload": [
                        "Succeeded"
                    ]
                },
                "type": "Select",
                "inputs": {
                    "from": "@coalesce(body('Entities_-_Get_Hosts')?['Hosts'], json('[]'))",
                    "select": "@toLower(item()?['hostName'])"
                }
            },
            "Select_IP_Addresses": {
                "runAfter": {
                    "Compose_Worker_Payload": [
                        "Succeeded"
                    ]
                },
                "type": "Select",
                "inputs": {
                    "from": "@coalesce(body('Entities_-_Get_IPs')?['IPs'], json('[]'))",
                    "select": "@item()?['address']"
                }
            },
            "Select_URLs_Flat": {
                "runAfter": {
                    "Compose_Worker_Payload": [
                        "Succeeded"
                    ]
                },
                "type": "Select",
                "inputs": {
                    "from": "@coalesce(body('Entities_-_Get_URLs')?['URLs'], json('[]'))",
                    "select": "@item()?['url']"
                }
            },
            "Compose_Hard_Fingerprint": {
                "runAfter": {
                    "Select_Account_Names": [
                        "Succeeded",
                        "Failed",
                        "Skipped",
                        "TimedOut"
                    ],
                    "Select_Host_Names": [
                        "Succeeded",
                        "Failed",
                        "Skipped",
                        "TimedOut"
                    ],
                    "Select_IP_Addresses": [
                        "Succeeded",
                        "Failed",
                        "Skipped",
                        "TimedOut"
                    ],
                    "Select_URLs_Flat": [
                        "Succeeded",
                        "Failed",
                        "Skipped",
                        "TimedOut"
                    ]
                },
                "type": "Compose",
                "inputs": "@concat(substring(coalesce(body('Get_Analytic_Rule')?['properties']?['displayName'], 'Unknown Rule'), 0, min(80, length(coalesce(body('Get_Analytic_Rule')?['properties']?['displayName'], 'Unknown Rule')))), ' | ', if(and(equals(length(coalesce(body('Select_Account_Names'), json('[]'))), 0), equals(length(coalesce(body('Select_Host_Names'), json('[]'))), 0), equals(length(coalesce(body('Select_IP_Addresses'), json('[]'))), 0), equals(length(coalesce(body('Select_URLs_Flat'), json('[]'))), 0)), 'no-entities', trim(concat(if(greater(length(coalesce(body('Select_Account_Names'), json('[]'))), 0), join(take(coalesce(body('Select_Account_Names'), json('[]')), min(3, length(coalesce(body('Select_Account_Names'), json('[]'))))), ', '), ''), if(and(greater(length(coalesce(body('Select_Account_Names'), json('[]'))), 0), greater(length(coalesce(body('Select_Host_Names'), json('[]'))), 0)), ', ', ''), if(greater(length(coalesce(body('Select_Host_Names'), json('[]'))), 0), join(take(coalesce(body('Select_Host_Names'), json('[]')), min(2, length(coalesce(body('Select_Host_Names'), json('[]'))))), ', '), ''), if(and(or(greater(length(coalesce(body('Select_Account_Names'), json('[]'))), 0), greater(length(coalesce(body('Select_Host_Names'), json('[]'))), 0)), greater(length(coalesce(body('Select_IP_Addresses'), json('[]'))), 0)), ', ', ''), if(greater(length(coalesce(body('Select_IP_Addresses'), json('[]'))), 0), join(take(coalesce(body('Select_IP_Addresses'), json('[]')), min(2, length(coalesce(body('Select_IP_Addresses'), json('[]'))))), ', '), ''), if(and(or(greater(length(coalesce(body('Select_Account_Names'), json('[]'))), 0), greater(length(coalesce(body('Select_Host_Names'), json('[]'))), 0), greater(length(coalesce(body('Select_IP_Addresses'), json('[]'))), 0)), greater(length(coalesce(body('Select_URLs_Flat'), json('[]'))), 0)), ', ', ''), if(greater(length(coalesce(body('Select_URLs_Flat'), json('[]'))), 0), join(take(coalesce(body('Select_URLs_Flat'), json('[]')), min(2, length(coalesce(body('Select_URLs_Flat'), json('[]'))))), ', '), '')))))"
            },
            "Compose_Hard_Fingerprint_Sanitized": {
                "runAfter": {
                    "Compose_Hard_Fingerprint": [
                        "Succeeded"
                    ]
                },
                "type": "Compose",
                "inputs": "@trim(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(string(outputs('Compose_Hard_Fingerprint')), decodeUriComponent('%0A'), ''), decodeUriComponent('%0D'), ''), decodeUriComponent('%09'), ''), decodeUriComponent('%C2%A0'), ' '), decodeUriComponent('%E2%80%8B'), ''), decodeUriComponent('%E2%80%8C'), ''), decodeUriComponent('%E2%80%8D'), ''), decodeUriComponent('%E2%80%98'), ''), decodeUriComponent('%E2%80%99'), ''), decodeUriComponent('%E2%80%94'), '-'), decodeUriComponent('%E2%80%93'), '-'), decodeUriComponent('%EF%BB%BF'), ''))"
            },
            "Compose_Hard_Fingerprint_Capped": {
                "runAfter": {
                    "Compose_Hard_Fingerprint_Sanitized": [
                        "Succeeded"
                    ]
                },
                "type": "Compose",
                "inputs": "@substring(string(outputs('Compose_Hard_Fingerprint_Sanitized')), 0, min(160, length(string(outputs('Compose_Hard_Fingerprint_Sanitized')))))"
            },
            "Compose_Anchored_Rule_KQL": {
                "runAfter": {
                    "Compose_Worker_Payload": [
                        "Succeeded"
                    ]
                },
                "type": "Compose",
                "inputs": "@concat(\n  '<strong>Analytic Rule - Alert-Anchored Query</strong><br>',\n  '<em>Locked to the exact alert execution window. The let _alertStart / let _alertEnd variables replace any relative ago() or time-picker window in the original rule.</em><br>',\n  '<strong>Alert Window:</strong>&nbsp;',\n  coalesce(first(body('Parse_Alerts_Array'))?['properties']?['additionalData']?['Query Start Time UTC'], outputs('Compose_Incident_Time')),\n  '&nbsp;&#8594;&nbsp;',\n  coalesce(first(body('Parse_Alerts_Array'))?['properties']?['additionalData']?['Query End Time UTC'], utcNow()),\n  '<br><br>',\n  '<blockquote>',\n  '// Alert-Anchored Query - reproduces the exact rows that triggered this incident<br>&nbsp;',\n  '// Rule: ', coalesce(body('Get_Analytic_Rule')?['properties']?['displayName'], 'Unknown Rule'), '<br>&nbsp;',\n  '// Original lookback: ', coalesce(string(body('Get_Analytic_Rule')?['properties']?['queryPeriod']), 'unknown'), ' | Frequency: ', coalesce(string(body('Get_Analytic_Rule')?['properties']?['queryFrequency']), 'unknown'), '<br>&nbsp;<br>&nbsp;',\n  'let _alertStart = datetime(', coalesce(first(body('Parse_Alerts_Array'))?['properties']?['additionalData']?['Query Start Time UTC'], outputs('Compose_Incident_Time')), ');<br>&nbsp;',\n  'let _alertEnd = datetime(', coalesce(first(body('Parse_Alerts_Array'))?['properties']?['additionalData']?['Query End Time UTC'], utcNow()), ');<br>&nbsp;<br>&nbsp;',\n  replace(replace(replace(replace(\n    coalesce(outputs('Compose_Worker_Payload')?['analyticRuleQuery'], '// No analytic rule query available'),\n    '<', '&lt;'),\n    '>', '&gt;'),\n    decodeUriComponent('%0A'), '<br>&nbsp;'),\n    decodeUriComponent('%0D'), ''),\n  '<br>&nbsp;| where TimeGenerated between (_alertStart .. _alertEnd)',\n  '</blockquote><br>',\n  '<em>Note: Set Log Analytics time picker to Last 30 days when running to ensure the anchored window is not filtered out.</em><br><br>'\n)"
            },
            "Call_Worker_VT": {
                "runAfter": {
                    "Compose_Worker_Payload": [
                        "Succeeded"
                    ]
                },
                "type": "Http",
                "inputs": {
                    "uri": "@parameters('WorkerURL_VT')",
                    "method": "POST",
                    "headers": {
                        "Content-Type": "application/json",
                        "x-worker-key": "@parameters('WorkerSharedKey')"
                    },
                    "body": "@outputs('Compose_Worker_Payload')"
                },
                "operationOptions": "DisableAsyncPattern",
                "runtimeConfiguration": {
                    "contentTransfer": {
                        "transferMode": "Chunked"
                    }
                }
            },
            "Call_Worker_URLScan": {
                "runAfter": {
                    "Compose_Worker_Payload": [
                        "Succeeded"
                    ]
                },
                "type": "Http",
                "inputs": {
                    "uri": "@parameters('WorkerURL_URLScan')",
                    "method": "POST",
                    "headers": {
                        "Content-Type": "application/json",
                        "x-worker-key": "@parameters('WorkerSharedKey')"
                    },
                    "body": "@outputs('Compose_Worker_Payload')"
                },
                "operationOptions": "DisableAsyncPattern",
                "runtimeConfiguration": {
                    "contentTransfer": {
                        "transferMode": "Chunked"
                    }
                }
            },
            "Call_Worker_Netskope": {
                "runAfter": {
                    "Compose_Worker_Payload": [
                        "Succeeded"
                    ]
                },
                "type": "Http",
                "inputs": {
                    "uri": "@parameters('WorkerURL_Netskope')",
                    "method": "POST",
                    "headers": {
                        "Content-Type": "application/json",
                        "x-worker-key": "@parameters('WorkerSharedKey')"
                    },
                    "body": "@outputs('Compose_Worker_Payload')"
                },
                "operationOptions": "DisableAsyncPattern",
                "runtimeConfiguration": {
                    "contentTransfer": {
                        "transferMode": "Chunked"
                    }
                }
            },
            "Call_Worker_AbuseIPDB": {
                "runAfter": {
                    "Compose_Worker_Payload": [
                        "Succeeded"
                    ]
                },
                "type": "Http",
                "inputs": {
                    "uri": "@parameters('WorkerURL_AbuseIPDB')",
                    "method": "POST",
                    "headers": {
                        "Content-Type": "application/json",
                        "x-worker-key": "@parameters('WorkerSharedKey')"
                    },
                    "body": "@outputs('Compose_Worker_Payload')"
                },
                "operationOptions": "DisableAsyncPattern",
                "runtimeConfiguration": {
                    "contentTransfer": {
                        "transferMode": "Chunked"
                    }
                }
            },
            "Call_Worker_Accounts": {
                "runAfter": {
                    "Compose_Worker_Payload": [
                        "Succeeded"
                    ]
                },
                "type": "Http",
                "inputs": {
                    "uri": "@parameters('WorkerURL_Accounts')",
                    "method": "POST",
                    "headers": {
                        "Content-Type": "application/json",
                        "x-worker-key": "@parameters('WorkerSharedKey')"
                    },
                    "body": "@outputs('Compose_Worker_Payload')"
                },
                "operationOptions": "DisableAsyncPattern",
                "runtimeConfiguration": {
                    "contentTransfer": {
                        "transferMode": "Chunked"
                    }
                }
            },
            "Call_Worker_Hosts": {
                "runAfter": {
                    "Compose_Worker_Payload": [
                        "Succeeded"
                    ]
                },
                "type": "Http",
                "inputs": {
                    "uri": "@parameters('WorkerURL_Hosts')",
                    "method": "POST",
                    "headers": {
                        "Content-Type": "application/json",
                        "x-worker-key": "@parameters('WorkerSharedKey')"
                    },
                    "body": "@outputs('Compose_Worker_Payload')"
                },
                "operationOptions": "DisableAsyncPattern",
                "runtimeConfiguration": {
                    "contentTransfer": {
                        "transferMode": "Chunked"
                    }
                }
            },
            "Call_Worker_Email_TI": {
                "runAfter": {
                    "Compose_Worker_Payload": [
                        "Succeeded"
                    ]
                },
                "type": "Http",
                "inputs": {
                    "uri": "@parameters('WorkerURL_EmailTI')",
                    "method": "POST",
                    "headers": {
                        "Content-Type": "application/json",
                        "x-worker-key": "@parameters('WorkerSharedKey')"
                    },
                    "body": "@outputs('Compose_Worker_Payload')"
                },
                "operationOptions": "DisableAsyncPattern",
                "runtimeConfiguration": {
                    "contentTransfer": {
                        "transferMode": "Chunked"
                    }
                }
            },
            "Call_Worker_MDE": {
                "runAfter": {
                    "Compose_Worker_Payload": [
                        "Succeeded"
                    ]
                },
                "type": "Http",
                "inputs": {
                    "uri": "@parameters('WorkerURL_MDE')",
                    "method": "POST",
                    "headers": {
                        "Content-Type": "application/json",
                        "x-worker-key": "@parameters('WorkerSharedKey')"
                    },
                    "body": "@outputs('Compose_Worker_Payload')"
                },
                "operationOptions": "DisableAsyncPattern",
                "runtimeConfiguration": {
                    "contentTransfer": {
                        "transferMode": "Chunked"
                    }
                }
            },
            "Compose_VT_Response": {
                "runAfter": {
                    "Call_Worker_VT": [
                        "Succeeded",
                        "Failed",
                        "TimedOut",
                        "Skipped"
                    ]
                },
                "type": "Compose",
                "inputs": "@coalesce(body('Call_Worker_VT'), json('{\"htmlTable\":\"\",\"vtURLTableHTML\":\"\",\"vtIPTableHTML\":\"\",\"vtHashTableHTML\":\"\",\"results\":[]}'))"
            },
            "Compose_URLScan_Response": {
                "runAfter": {
                    "Call_Worker_URLScan": [
                        "Succeeded",
                        "Failed",
                        "TimedOut",
                        "Skipped"
                    ]
                },
                "type": "Compose",
                "inputs": "@coalesce(body('Call_Worker_URLScan'), json('{\"urlscanTableHTML\":\"\",\"urlscanDomainTableHTML\":\"\",\"urlscanIPTableHTML\":\"\",\"urlscanHashTableHTML\":\"\",\"urlscanASNTableHTML\":\"\",\"results\":[]}'))"
            },
            "Compose_Netskope_Response": {
                "runAfter": {
                    "Call_Worker_Netskope": [
                        "Succeeded",
                        "Failed",
                        "TimedOut",
                        "Skipped"
                    ]
                },
                "type": "Compose",
                "inputs": "@coalesce(body('Call_Worker_Netskope'), json('{\"nsURLTableHTML\":\"\",\"nsClickTableHTML\":\"\",\"kqlSectionHTML\":\"\",\"results\":[]}'))"
            },
            "Compose_AbuseIPDB_Response": {
                "runAfter": {
                    "Call_Worker_AbuseIPDB": [
                        "Succeeded",
                        "Failed",
                        "TimedOut",
                        "Skipped"
                    ]
                },
                "type": "Compose",
                "inputs": "@coalesce(body('Call_Worker_AbuseIPDB'), json('{\"abuseIPTableHTML\":\"\",\"results\":[]}'))"
            },
            "Compose_Accounts_Response": {
                "runAfter": {
                    "Call_Worker_Accounts": [
                        "Succeeded",
                        "Failed",
                        "TimedOut",
                        "Skipped"
                    ]
                },
                "type": "Compose",
                "inputs": "@coalesce(body('Call_Worker_Accounts'), json('{\"accountTableHTML\":\"\",\"kqlSectionHTML\":\"\",\"results\":[]}'))"
            },
            "Compose_Hosts_Response": {
                "runAfter": {
                    "Call_Worker_Hosts": [
                        "Succeeded",
                        "Failed",
                        "TimedOut",
                        "Skipped"
                    ]
                },
                "type": "Compose",
                "inputs": "@coalesce(body('Call_Worker_Hosts'), json('{\"hostTableHTML\":\"\",\"kqlSectionHTML\":\"\",\"results\":[]}'))"
            },
            "Compose_EmailTI_Response": {
                "runAfter": {
                    "Call_Worker_Email_TI": [
                        "Succeeded",
                        "Failed",
                        "TimedOut",
                        "Skipped"
                    ]
                },
                "type": "Compose",
                "inputs": "@coalesce(body('Call_Worker_Email_TI'), json('{\"emailTableHTML\":\"\",\"tiTableHTML\":\"\",\"kqlSectionHTML\":\"\",\"results\":[]}'))"
            },
            "Compose_MDE_Response": {
                "runAfter": {
                    "Call_Worker_MDE": [
                        "Succeeded",
                        "Failed",
                        "TimedOut",
                        "Skipped"
                    ]
                },
                "type": "Compose",
                "inputs": "@coalesce(body('Call_Worker_MDE'), json('{\"mdeDeviceTableHTML\":\"\",\"mdeAlertTableHTML\":\"\",\"mdeProcessTableHTML\":\"\",\"mdeNetworkTableHTML\":\"\",\"mdeFileTableHTML\":\"\",\"mdeLogonTableHTML\":\"\",\"kqlSectionHTML\":\"\",\"results\":[]}'))"
            },
            "Compose_Full_KQL_Query": {
                "runAfter": {
                    "Compose_VT_Response": [
                        "Succeeded"
                    ],
                    "Compose_URLScan_Response": [
                        "Succeeded"
                    ],
                    "Compose_Netskope_Response": [
                        "Succeeded"
                    ],
                    "Compose_AbuseIPDB_Response": [
                        "Succeeded"
                    ],
                    "Compose_Accounts_Response": [
                        "Succeeded"
                    ],
                    "Compose_Hosts_Response": [
                        "Succeeded"
                    ],
                    "Compose_EmailTI_Response": [
                        "Succeeded"
                    ],
                    "Compose_MDE_Response": [
                        "Succeeded"
                    ]
                },
                "type": "Compose",
                "inputs": "@concat(outputs('Compose_Worker_Payload')?['analyticRuleQuery'], '| take 10')"
            },
            "Run_Alert_KQL": {
                "runAfter": {
                    "Compose_Full_KQL_Query": [
                        "Succeeded"
                    ]
                },
                "type": "ApiConnection",
                "inputs": {
                    "host": {
                        "connection": {
                            "name": "@parameters('$connections')['azuremonitorlogs']['connectionId']"
                        }
                    },
                    "method": "post",
                    "body": "@{outputs('Compose_Full_KQL_Query')}",
                    "path": "/queryData",
                    "queries": {
                        "subscriptions": "<AZURE-SUBSCRIPTION-ID>",
                        "resourcegroups": "<RESOURCE-GROUP>",
                        "resourcetype": "Log Analytics Workspace",
                        "resourcename": "<LOG-ANALYTICS-WORKSPACE>",
                        "timerange": "7d"
                    }
                }
            },
            "Compose_AI_Context": {
                "runAfter": {
                    "Run_Alert_KQL": [
                        "Succeeded",
                        "Failed",
                        "TimedOut"
                    ]
                },
                "type": "Compose",
                "inputs": {
                    "incidentId": "@outputs('Compose_Worker_Payload')?['incidentId']",
                    "incidentTitle": "@outputs('Compose_Worker_Payload')?['incidentTitle']",
                    "incidentSeverity": "@outputs('Compose_Worker_Payload')?['incidentSeverity']",
                    "incidentStatus": "@outputs('Compose_Worker_Payload')?['incidentStatus']",
                    "incidentDescription": "@outputs('Compose_Worker_Payload')?['incidentDescription']",
                    "alerts": "@outputs('Compose_Worker_Payload')?['alerts']",
                    "analyticRuleQuery": "@outputs('Compose_Worker_Payload')?['analyticRuleQuery']",
                    "kqlResults": "@coalesce(body('Run_Alert_KQL')?['value'], json('[]'))",
                    "accountEnrichment": "@coalesce(outputs('Compose_Accounts_Response')?['results'], json('[]'))",
                    "hostEnrichment": "@coalesce(outputs('Compose_Hosts_Response')?['results'], json('[]'))",
                    "vtURLResults": "@coalesce(outputs('Compose_VT_Response')?['vtURLResults'], json('[]'))",
                    "vtIPResults": "@coalesce(outputs('Compose_VT_Response')?['vtIPResults'], json('[]'))",
                    "vtHashResults": "@coalesce(outputs('Compose_VT_Response')?['vtHashResults'], json('[]'))",
                    "urlscanResults": "@coalesce(outputs('Compose_URLScan_Response')?['urlscanResults'], json('[]'))",
                    "netskopeURLResults": "@coalesce(outputs('Compose_Netskope_Response')?['nsURLResults'], json('[]'))",
                    "netskopeClickResults": "@coalesce(outputs('Compose_Netskope_Response')?['nsClickResults'], json('[]'))",
                    "abuseIPResults": "@coalesce(outputs('Compose_AbuseIPDB_Response')?['results'], json('[]'))",
                    "emailResults": "@coalesce(outputs('Compose_EmailTI_Response')?['emailResults'], json('[]'))",
                    "tiResults": "@coalesce(outputs('Compose_EmailTI_Response')?['tiResults'], json('[]'))",
                    "mdeResults": "@coalesce(outputs('Compose_MDE_Response')?['results'], json('[]'))"
                }
            },
            "Compose_AI_Context_CharLength": {
                "runAfter": {
                    "Compose_AI_Context": [
                        "Succeeded"
                    ]
                },
                "type": "Compose",
                "inputs": "@length(string(outputs('Compose_AI_Context')))"
            },
            "Compose_AI_System_Prompt": {
                "runAfter": {
                    "Compose_AI_Context_CharLength": [
                        "Succeeded"
                    ]
                },
                "type": "Compose",
                "inputs": "You are a senior cybersecurity analyst at a retail organization. You will receive Microsoft Sentinel incident data and raw KQL query results from triggered alert rules. Your job is to review the log data and provide a structured security analysis. Think methodically - examine the data for patterns, anomalies, timestamps, user accounts, IP addresses, device names, and sequences of events that indicate malicious or suspicious activity. Always ground your analysis in the actual data provided, not assumptions.\n\nFORMATTING RULES - CRITICAL:\n- Format your entire response as HTML only.\n- Use <br> for all line breaks. Never use \\n.\n- Use <strong> for bold text. Never use ** or __ markdown.\n- Use <em> for italic text. Never use * or _ markdown.\n- For bullet points, use the literal bullet character • followed by a space, then your text, then <br>. Do NOT use dashes (-), asterisks (*), or tilde (~) as list markers.\n- For numbered lists, write: 1. text<br> 2. text<br> etc.\n- Do NOT use any markdown syntax whatsoever. No #, no **, no __, no ~~, no -, no backticks.\n- Do NOT include any HTML document structure tags like <html>, <head>, <body>. Return only inline HTML content.\n- Wrap each section heading in <strong> tags, e.g. <strong>1. SUMMARY</strong><br>\n\nSECURITY ENVIRONMENT:\n- Microsoft-first stack: Entra ID, Intune, Defender XDR, Sentinel\n- MFA enforced; privileged roles JIT via PIM\n- Windows endpoints Intune-managed and Defender-onboarded\n- iOS MAM-managed only\n- Sentinel ingests Entra ID, M365, Defender XDR logs (no firewall/proxy)\n- MDE (Defender for Endpoint) telemetry available: device risk/exposure, active alerts, process events, network connections, file events, and logged-on users per host entity\n- After-hours admin activity is suspicious unless tied to incident response\n- Rubrik Cloud Integration: <ORG> is the backup system; VM/backup admin actions are expected\n- Treat unmanaged device admin actions as high risk\n\nSECTION 18 SCORING GUIDANCE — INCIDENT RATINGS:\nYou must always produce Section 18 with exactly two numeric ratings on a 1-10 scale.\n\nRATING 1 — SECURITY RISK SCORE (1-10):\nRate the true security threat posed by this incident after factoring in false positive likelihood.\nA high score means: credible threat activity, low false positive likelihood, attacker indicators present.\nA low score means: benign explanation is highly probable, no threat actor indicators, easily explained by legitimate activity.\nScale guidance:\n1-2 = Almost certainly a false positive or noise (misconfigured script, expected admin task, password change)\n3-4 = Low risk, likely benign but warrants a quick look\n5-6 = Moderate risk, ambiguous signals, could be threat or could be legitimate\n7-8 = High risk, credible threat indicators, investigation required\n9-10 = Critical, strong evidence of active attack, immediate response needed\n\nRATING 2 — OPERATIONAL REVIEW NEED (1-10):\nRate how much this incident warrants review by an internal <ORG> operational or IT team — INDEPENDENT of whether it is a security threat.\nThis captures incidents where the 3rd-party SOC may close the ticket as non-threatening, but the underlying cause still requires internal follow-up to resolve a technical issue, misconfiguration, or degraded user experience.\nA high score means: even if not a threat, something broke, degraded, or is misconfigured that an internal team should fix.\nA low score means: entirely expected behavior, no follow-up needed by internal teams.\nScale guidance:\n1-2 = No operational follow-up needed, expected behavior\n3-4 = Minor, low-priority follow-up may be beneficial\n5-6 = Moderate operational issue, internal team should investigate root cause when time permits\n7-8 = Significant operational issue, internal team should investigate promptly (e.g. misconfigured script causing mass alerts, account lockouts, Defender blocking large volumes of files)\n9-10 = Urgent operational issue regardless of threat status — a team must act to restore normal function or resolve root cause (e.g. 300% spike in failed logins traced to password change not synced, mass file block impacting productivity)\n\nEXAMPLES to calibrate your ratings:\n• Defender blocked 200 files on a single endpoint due to a new deployment script → Security Risk: 2, Operational Review: 9\n• User had 300% increase in failed logins traced to a recent password change not propagated to a service → Security Risk: 2, Operational Review: 8\n• Unknown process lateral movement with confirmed C2 beaconing → Security Risk: 10, Operational Review: 4\n• Single failed login from an expected travel location → Security Risk: 2, Operational Review: 1\n• Mass MFA failures across 10 accounts at 2am with no matching travel → Security Risk: 8, Operational Review: 6"
            },
            "Compose_AI_User_Prompt": {
                "runAfter": {
                    "Initialize_FinalAIText": [
                        "Succeeded"
                    ],
                    "Initialize_FinalAITokens": [
                        "Succeeded"
                    ],
                    "Initialize_FinalAIModel": [
                        "Succeeded"
                    ]
                },
                "type": "Compose",
                "inputs": "@concat('Analyze this Sentinel incident and all enrichment data provided. Provide sections: 1.SUMMARY 2.SEVERITY ASSESSMENT 3.ATTACK TECHNIQUE (MITRE) 4.KEY INDICATORS 5.RECOMMENDED ACTIONS 6.FALSE POSITIVE LIKELIHOOD 7.ACCOUNT ANALYSIS 8.HOST TIMELINE ANALYSIS 9.VIRUSTOTAL URL ANALYSIS 10.VIRUSTOTAL IP ANALYSIS 11.VIRUSTOTAL FILE HASH ANALYSIS 12.NETSKOPE URL ANALYSIS 13.ABUSEIPDB IP ANALYSIS 14.NETSKOPE URL CLICK AND CONNECTION ANALYSIS 15.URLSCAN.IO URL SCAN ANALYSIS 16.EMAIL DELIVERY ANALYSIS 17.SENTINEL THREAT INTELLIGENCE ANALYSIS 18.INCIDENT RATINGS 19.MDE DEVICE TELEMETRY ANALYSIS — for section 18 provide exactly two scored ratings as described in your instructions: (a) SECURITY RISK SCORE 1-10 — for section 19 analyze MDE device profile (risk score, exposure, onboarding), active MDE alerts on the device, process executions (look for LOLBins, encoded PowerShell, suspicious parent-child chains), network connections (C2 indicators, unusual destinations), file events (dropped executables/scripts), and logged-on users at time of incident with a one-sentence justification, (b) OPERATIONAL REVIEW NEED 1-10 with a one-sentence justification explaining what internal team action (if any) is warranted even if the SOC closes this as a non-threat.\\n\\nIncident data: ', string(outputs('Compose_AI_Context')))"
            },
            "Compose_AI_Context_Part1": {
                "runAfter": {
                    "Compose_AI_User_Prompt": [
                        "Succeeded"
                    ]
                },
                "type": "Compose",
                "inputs": {
                    "incidentId": "@outputs('Compose_AI_Context')?['incidentId']",
                    "incidentTitle": "@outputs('Compose_AI_Context')?['incidentTitle']",
                    "incidentSeverity": "@outputs('Compose_AI_Context')?['incidentSeverity']",
                    "incidentStatus": "@outputs('Compose_AI_Context')?['incidentStatus']",
                    "incidentDescription": "@outputs('Compose_AI_Context')?['incidentDescription']",
                    "alerts": "@outputs('Compose_AI_Context')?['alerts']",
                    "analyticRuleQuery": "@outputs('Compose_AI_Context')?['analyticRuleQuery']",
                    "kqlResults": "@outputs('Compose_AI_Context')?['kqlResults']",
                    "accountEnrichment": "@outputs('Compose_AI_Context')?['accountEnrichment']",
                    "hostEnrichment": "@outputs('Compose_AI_Context')?['hostEnrichment']",
                    "mdeResults": "@outputs('Compose_AI_Context')?['mdeResults']"
                }
            },
            "Compose_AI_Context_Part2": {
                "runAfter": {
                    "Compose_AI_User_Prompt": [
                        "Succeeded"
                    ]
                },
                "type": "Compose",
                "inputs": {
                    "incidentId": "@outputs('Compose_AI_Context')?['incidentId']",
                    "incidentTitle": "@outputs('Compose_AI_Context')?['incidentTitle']",
                    "incidentSeverity": "@outputs('Compose_AI_Context')?['incidentSeverity']",
                    "incidentStatus": "@outputs('Compose_AI_Context')?['incidentStatus']",
                    "incidentDescription": "@outputs('Compose_AI_Context')?['incidentDescription']",
                    "alerts": "@outputs('Compose_AI_Context')?['alerts']",
                    "vtURLResults": "@outputs('Compose_AI_Context')?['vtURLResults']",
                    "vtIPResults": "@outputs('Compose_AI_Context')?['vtIPResults']",
                    "vtHashResults": "@outputs('Compose_AI_Context')?['vtHashResults']",
                    "urlscanResults": "@outputs('Compose_AI_Context')?['urlscanResults']",
                    "netskopeURLResults": "@outputs('Compose_AI_Context')?['netskopeURLResults']",
                    "netskopeClickResults": "@outputs('Compose_AI_Context')?['netskopeClickResults']",
                    "abuseIPResults": "@outputs('Compose_AI_Context')?['abuseIPResults']",
                    "emailResults": "@outputs('Compose_AI_Context')?['emailResults']",
                    "tiResults": "@outputs('Compose_AI_Context')?['tiResults']"
                }
            },
            "Compose_AI_User_Prompt_Part1": {
                "runAfter": {
                    "Compose_AI_Context_Part1": [
                        "Succeeded"
                    ]
                },
                "type": "Compose",
                "inputs": "@concat('Analyze this Sentinel incident. Provide ONLY sections 1-8 AND section 18: 1.SUMMARY 2.SEVERITY ASSESSMENT 3.ATTACK TECHNIQUE (MITRE) 4.KEY INDICATORS 5.RECOMMENDED ACTIONS 6.FALSE POSITIVE LIKELIHOOD 7.ACCOUNT ANALYSIS 8.HOST TIMELINE ANALYSIS 18.INCIDENT RATINGS 19.MDE DEVICE TELEMETRY ANALYSIS — for section 18 provide exactly two scored ratings: (a) SECURITY RISK SCORE 1-10 with a one-sentence justification, (b) OPERATIONAL REVIEW NEED 1-10 with a one-sentence justification explaining what internal team action (if any) is warranted even if the SOC closes this as a non-threat. Section 19 should analyze MDE device profile (risk/exposure/onboarding), active MDE alerts, process events (LOLBins, encoded PS, suspicious chains), network connections (C2, beaconing), file events (dropped executables/scripts), and logged-on users. Note: Threat intelligence sections 9-17 will follow in a separate analysis part.\\n\\nIncident data: ', string(outputs('Compose_AI_Context_Part1')))"
            },
            "Compose_AI_User_Prompt_Part2": {
                "runAfter": {
                    "Compose_AI_Context_Part2": [
                        "Succeeded"
                    ]
                },
                "type": "Compose",
                "inputs": "@concat('Analyze the threat intelligence data for this Sentinel incident. Provide ONLY sections 9-17: 9.VIRUSTOTAL URL ANALYSIS 10.VIRUSTOTAL IP ANALYSIS 11.VIRUSTOTAL FILE HASH ANALYSIS 12.NETSKOPE URL ANALYSIS 13.ABUSEIPDB IP ANALYSIS 14.NETSKOPE URL CLICK AND CONNECTION ANALYSIS 15.URLSCAN.IO URL SCAN ANALYSIS 16.EMAIL DELIVERY ANALYSIS 17.SENTINEL THREAT INTELLIGENCE ANALYSIS. The primary incident analysis (sections 1-8) is being generated separately.\\n\\nIncident data: ', string(outputs('Compose_AI_Context_Part2')))"
            },
            "Condition_Needs_AI_Split": {
                "actions": {
                    "Send_Split_Notification_Email": {
                        "type": "ApiConnection",
                        "inputs": {
                            "host": {
                                "connection": {
                                    "name": "@parameters('$connections')['office365-1']['connectionId']"
                                }
                            },
                            "method": "post",
                            "body": {
                                "To": "<ANALYST-EMAIL>",
                                "Subject": "⚠️ AI Split Triggered - @{body('Get_incident')?['properties']?['title']} (#@{body('Get_incident')?['name']})",
                                "Body": "@concat('<html><body style=\"font-family:Segoe UI,Arial,sans-serif;font-size:13px;color:#222\"><div style=\"background:#e67e22;color:#fff;padding:14px 20px;border-radius:6px 6px 0 0\"><h2 style=\"margin:0\">⚠️ AI Dual-Call Split Triggered</h2></div><div style=\"border:1px solid #ddd;border-top:none;padding:20px;border-radius:0 0 6px 6px\"><p>The AI context payload exceeded the 200K token threshold (~600,000 characters) and was automatically split into two separate AI calls.</p><table style=\"width:100%;border-collapse:collapse;margin-bottom:20px\"><tr><td style=\"padding:6px 12px;font-weight:bold;width:180px;background:#f5f5f5;border:1px solid #ddd\">Incident Number</td><td style=\"padding:6px 12px;border:1px solid #ddd;font-family:monospace\">',body('Get_incident')?['name'],'</td></tr><tr><td style=\"padding:6px 12px;font-weight:bold;background:#f5f5f5;border:1px solid #ddd\">Incident Title</td><td style=\"padding:6px 12px;border:1px solid #ddd\">',body('Get_incident')?['properties']?['title'],'</td></tr><tr><td style=\"padding:6px 12px;font-weight:bold;background:#f5f5f5;border:1px solid #ddd\">Analytic Rule</td><td style=\"padding:6px 12px;border:1px solid #ddd\">',body('Get_Analytic_Rule')?['properties']?['displayName'],'</td></tr><tr><td style=\"padding:6px 12px;font-weight:bold;background:#f5f5f5;border:1px solid #ddd\">Severity</td><td style=\"padding:6px 12px;border:1px solid #ddd;font-weight:bold\">',body('Get_incident')?['properties']?['severity'],'</td></tr><tr><td style=\"padding:6px 12px;font-weight:bold;background:#f5f5f5;border:1px solid #ddd\">Estimated Char Length</td><td style=\"padding:6px 12px;border:1px solid #ddd;font-family:monospace\">',string(outputs('Compose_AI_Context_CharLength')),' chars (~',string(div(outputs('Compose_AI_Context_CharLength'),3)),' tokens)</td></tr></table><p style=\"color:#666;font-size:12px\">Review the incident in Sentinel to verify both AI analysis parts posted correctly. If context trimming is needed, consider reducing KQL take limits for high-volume rules.</p></div></body></html>')",
                                "Importance": "Normal",
                                "IsHtml": true
                            },
                            "path": "/v2/Mail"
                        }
                    },
                    "Http_AI_Call_Part1": {
                        "runAfter": {
                            "Send_Split_Notification_Email": [
                                "Succeeded",
                                "Failed"
                            ]
                        },
                        "type": "Http",
                        "inputs": {
                            "uri": "https://<AZURE-OPENAI-RESOURCE>.openai.azure.com/openai/v1/responses",
                            "method": "POST",
                            "headers": {
                                "Content-Type": "application/json",
                                "api-key": "<AZURE-OPENAI-API-KEY>"
                            },
                            "body": {
                                "model": "gpt-5.3-chat",
                                "instructions": "@{outputs('Compose_AI_System_Prompt')}",
                                "input": "@{outputs('Compose_AI_User_Prompt_Part1')}",
                                "max_output_tokens": 3500
                            }
                        }
                    },
                    "Http_AI_Call_Part2": {
                        "runAfter": {
                            "Send_Split_Notification_Email": [
                                "Succeeded",
                                "Failed"
                            ]
                        },
                        "type": "Http",
                        "inputs": {
                            "uri": "https://<AZURE-OPENAI-RESOURCE>.openai.azure.com/openai/v1/responses",
                            "method": "POST",
                            "headers": {
                                "Content-Type": "application/json",
                                "api-key": "<AZURE-OPENAI-API-KEY>"
                            },
                            "body": {
                                "model": "gpt-5.3-chat",
                                "instructions": "@{outputs('Compose_AI_System_Prompt')}",
                                "input": "@{outputs('Compose_AI_User_Prompt_Part2')}",
                                "max_output_tokens": 3500
                            }
                        }
                    },
                    "Parse_AI_Response_Part1": {
                        "runAfter": {
                            "Http_AI_Call_Part1": [
                                "Succeeded"
                            ]
                        },
                        "type": "ParseJson",
                        "inputs": {
                            "content": "@body('Http_AI_Call_Part1')",
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "output": {
                                        "type": "array",
                                        "items": {
                                            "type": "object",
                                            "properties": {
                                                "content": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "text": {
                                                                "type": "string"
                                                            },
                                                            "type": {
                                                                "type": "string"
                                                            }
                                                        }
                                                    }
                                                },
                                                "type": {
                                                    "type": "string"
                                                }
                                            }
                                        }
                                    },
                                    "usage": {
                                        "type": "object",
                                        "properties": {
                                            "input_tokens": {
                                                "type": "integer"
                                            },
                                            "output_tokens": {
                                                "type": "integer"
                                            },
                                            "total_tokens": {
                                                "type": "integer"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "Parse_AI_Response_Part2": {
                        "runAfter": {
                            "Http_AI_Call_Part2": [
                                "Succeeded"
                            ]
                        },
                        "type": "ParseJson",
                        "inputs": {
                            "content": "@body('Http_AI_Call_Part2')",
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "output": {
                                        "type": "array",
                                        "items": {
                                            "type": "object",
                                            "properties": {
                                                "content": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "text": {
                                                                "type": "string"
                                                            },
                                                            "type": {
                                                                "type": "string"
                                                            }
                                                        }
                                                    }
                                                },
                                                "type": {
                                                    "type": "string"
                                                }
                                            }
                                        }
                                    },
                                    "usage": {
                                        "type": "object",
                                        "properties": {
                                            "input_tokens": {
                                                "type": "integer"
                                            },
                                            "output_tokens": {
                                                "type": "integer"
                                            },
                                            "total_tokens": {
                                                "type": "integer"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "Compose_AI_Text_Part1": {
                        "runAfter": {
                            "Parse_AI_Response_Part1": [
                                "Succeeded"
                            ]
                        },
                        "type": "Compose",
                        "inputs": "@{coalesce(body('Parse_AI_Response_Part1')?['output']?[1]?['content']?[0]?['text'], body('Parse_AI_Response_Part1')?['output']?[0]?['content']?[0]?['text'], 'AI Part 1 response not found')}"
                    },
                    "Compose_AI_Text_Part2": {
                        "runAfter": {
                            "Parse_AI_Response_Part2": [
                                "Succeeded"
                            ]
                        },
                        "type": "Compose",
                        "inputs": "@{coalesce(body('Parse_AI_Response_Part2')?['output']?[1]?['content']?[0]?['text'], body('Parse_AI_Response_Part2')?['output']?[0]?['content']?[0]?['text'], 'AI Part 2 response not found')}"
                    },
                    "Compose_AI_Text_Split_Combined": {
                        "runAfter": {
                            "Compose_AI_Text_Part1": [
                                "Succeeded",
                                "Failed"
                            ],
                            "Compose_AI_Text_Part2": [
                                "Succeeded",
                                "Failed"
                            ]
                        },
                        "type": "Compose",
                        "inputs": "@concat(outputs('Compose_AI_Text_Part1'), '<br><br><strong>--- Threat Intelligence Analysis (Part 2) ---</strong><br><br>', outputs('Compose_AI_Text_Part2'))"
                    },
                    "Compose_Split_Total_Tokens": {
                        "runAfter": {
                            "Parse_AI_Response_Part1": [
                                "Succeeded",
                                "Failed"
                            ],
                            "Parse_AI_Response_Part2": [
                                "Succeeded",
                                "Failed"
                            ]
                        },
                        "type": "Compose",
                        "inputs": "@add(coalesce(body('Parse_AI_Response_Part1')?['usage']?['total_tokens'], 0), coalesce(body('Parse_AI_Response_Part2')?['usage']?['total_tokens'], 0))"
                    },
                    "Compose_Split_Model": {
                        "runAfter": {
                            "Http_AI_Call_Part1": [
                                "Succeeded",
                                "Failed"
                            ]
                        },
                        "type": "Compose",
                        "inputs": "@coalesce(body('Http_AI_Call_Part1')?['model'], 'gpt-5.3-chat')"
                    },
                    "Set_AI_Text_From_Split": {
                        "runAfter": {
                            "Compose_AI_Text_Split_Combined": [
                                "Succeeded"
                            ],
                            "Compose_Split_Total_Tokens": [
                                "Succeeded"
                            ],
                            "Compose_Split_Model": [
                                "Succeeded"
                            ]
                        },
                        "type": "SetVariable",
                        "inputs": {
                            "name": "FinalAIText",
                            "value": "@outputs('Compose_AI_Text_Split_Combined')"
                        }
                    },
                    "Set_AI_Tokens_From_Split": {
                        "runAfter": {
                            "Set_AI_Text_From_Split": [
                                "Succeeded"
                            ]
                        },
                        "type": "SetVariable",
                        "inputs": {
                            "name": "FinalAITokens",
                            "value": "@outputs('Compose_Split_Total_Tokens')"
                        }
                    },
                    "Set_AI_Model_From_Split": {
                        "runAfter": {
                            "Set_AI_Tokens_From_Split": [
                                "Succeeded"
                            ]
                        },
                        "type": "SetVariable",
                        "inputs": {
                            "name": "FinalAIModel",
                            "value": "@coalesce(body('Http_AI_Call_Part1')?['model'], 'gpt-5.3-chat')"
                        }
                    }
                },
                "runAfter": {
                    "Compose_AI_User_Prompt_Part1": [
                        "Succeeded"
                    ],
                    "Compose_AI_User_Prompt_Part2": [
                        "Succeeded"
                    ]
                },
                "else": {
                    "actions": {
                        "Http_AI_Call_Single": {
                            "type": "Http",
                            "inputs": {
                                "uri": "https://<AZURE-OPENAI-RESOURCE>.openai.azure.com/openai/v1/responses",
                                "method": "POST",
                                "headers": {
                                    "Content-Type": "application/json",
                                    "api-key": "<AZURE-OPENAI-API-KEY>"
                                },
                                "body": {
                                    "model": "gpt-5.3-chat",
                                    "instructions": "@{outputs('Compose_AI_System_Prompt')}",
                                    "input": "@{outputs('Compose_AI_User_Prompt')}",
                                    "max_output_tokens": 3500
                                }
                            }
                        },
                        "Parse_AI_Response_Single": {
                            "runAfter": {
                                "Http_AI_Call_Single": [
                                    "Succeeded"
                                ]
                            },
                            "type": "ParseJson",
                            "inputs": {
                                "content": "@body('Http_AI_Call_Single')",
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "output": {
                                            "type": "array",
                                            "items": {
                                                "type": "object",
                                                "properties": {
                                                    "content": {
                                                        "type": "array",
                                                        "items": {
                                                            "type": "object",
                                                            "properties": {
                                                                "text": {
                                                                    "type": "string"
                                                                },
                                                                "type": {
                                                                    "type": "string"
                                                                }
                                                            }
                                                        }
                                                    },
                                                    "type": {
                                                        "type": "string"
                                                    }
                                                }
                                            }
                                        },
                                        "usage": {
                                            "type": "object",
                                            "properties": {
                                                "input_tokens": {
                                                    "type": "integer"
                                                },
                                                "output_tokens": {
                                                    "type": "integer"
                                                },
                                                "total_tokens": {
                                                    "type": "integer"
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        },
                        "Compose_AI_Text_Single": {
                            "runAfter": {
                                "Parse_AI_Response_Single": [
                                    "Succeeded"
                                ]
                            },
                            "type": "Compose",
                            "inputs": "@{coalesce(body('Parse_AI_Response_Single')?['output']?[1]?['content']?[0]?['text'], body('Parse_AI_Response_Single')?['output']?[0]?['content']?[0]?['text'], 'AI response not found')}"
                        },
                        "Set_AI_Text_From_Single": {
                            "runAfter": {
                                "Compose_AI_Text_Single": [
                                    "Succeeded"
                                ]
                            },
                            "type": "SetVariable",
                            "inputs": {
                                "name": "FinalAIText",
                                "value": "@outputs('Compose_AI_Text_Single')"
                            }
                        },
                        "Set_AI_Tokens_From_Single": {
                            "runAfter": {
                                "Set_AI_Text_From_Single": [
                                    "Succeeded"
                                ]
                            },
                            "type": "SetVariable",
                            "inputs": {
                                "name": "FinalAITokens",
                                "value": "@coalesce(body('Parse_AI_Response_Single')?['usage']?['total_tokens'], 0)"
                            }
                        },
                        "Set_AI_Model_From_Single": {
                            "runAfter": {
                                "Set_AI_Tokens_From_Single": [
                                    "Succeeded"
                                ]
                            },
                            "type": "SetVariable",
                            "inputs": {
                                "name": "FinalAIModel",
                                "value": "@coalesce(body('Http_AI_Call_Single')?['model'], 'gpt-5.3-chat')"
                            }
                        }
                    }
                },
                "expression": {
                    "and": [
                        {
                            "greater": [
                                "@outputs('Compose_AI_Context_CharLength')",
                                400000
                            ]
                        }
                    ]
                },
                "type": "If"
            },
            "Http_AI_Fingerprint_Call": {
                "runAfter": {
                    "Condition_Needs_AI_Split": [
                        "Succeeded",
                        "Failed"
                    ]
                },
                "type": "Http",
                "inputs": {
                    "uri": "https://<AZURE-OPENAI-RESOURCE>.openai.azure.com/openai/v1/responses",
                    "method": "POST",
                    "headers": {
                        "Content-Type": "application/json",
                        "api-key": "<AZURE-OPENAI-API-KEY>"
                    },
                    "body": {
                        "model": "gpt-5.3-chat",
                        "instructions": "You are a security incident normalization engine. Your only job is to extract structured deduplication fields from a Microsoft Sentinel incident. You must return ONLY valid JSON — no preamble, no markdown, no backtick fences, no commentary of any kind. Raw JSON only.\n\nFIELD RULES:\n\nincident_type: MUST be exactly one value from this list — no variations allowed:\nAuthentication Failure Spike | Impossible Travel | Malware Detection | Lateral Movement | Suspicious Admin Activity | Data Exfiltration | Recon / Enumeration | Credential Stuffing | Phishing / Malicious Email | Ransomware Indicators | Insider Threat Indicators | Policy Violation | Other\n\ndetection_rule: The analytic rule name exactly as provided. Do not paraphrase or shorten.\n\nprimary_entities: Return ONLY the top 5 most significant entities using this priority order: 1. Servers / hosts, 2. Privileged or service accounts, 3. Standard user accounts. Rules: lowercase only, alphabetically sorted, no duplicates, no IP addresses, no timestamps, no counts, no email domains alone.\n\nenvironment_scope: Exactly one of: Single User | Multiple Users | Server-Based | Hybrid\n\nlikely_cause_category: Exactly one of: Cached Credentials | Password Change Fallout | Service Account Misuse | Misconfiguration | Malicious Activity | Phishing | Software Deployment | Brute Force | Unknown\n\nsource_system: Exactly one of: MXDR365 | Microsoft Sentinel | Defender for Identity | Defender for Endpoint | Netskope | Unknown\n\nReturn ONLY this exact JSON structure with no other text:\n{\"incident_type\":\"\",\"detection_rule\":\"\",\"primary_entities\":[],\"environment_scope\":\"\",\"likely_cause_category\":\"\",\"source_system\":\"\"}",
                        "input": "@concat('Normalize this Sentinel incident for ServiceNow deduplication.\\n\\nIncident Title: ', outputs('Compose_Worker_Payload')?['incidentTitle'], '\\nIncident Description: ', coalesce(outputs('Compose_Worker_Payload')?['incidentDescription'], 'No description'), '\\nAnalytic Rule Name: ', coalesce(body('Get_Analytic_Rule')?['properties']?['displayName'], 'Unknown'), '\\nSeverity: ', outputs('Compose_Worker_Payload')?['incidentSeverity'], '\\nAccount Entities: ', string(outputs('Compose_Worker_Payload')?['accounts']), '\\nHost Entities: ', string(outputs('Compose_Worker_Payload')?['hosts']), '\\nAlert Names: ', string(outputs('Compose_Worker_Payload')?['alerts']))",
                        "max_output_tokens": 400
                    }
                }
            },
            "Parse_AI_Fingerprint_Response": {
                "runAfter": {
                    "Http_AI_Fingerprint_Call": [
                        "Succeeded"
                    ]
                },
                "type": "ParseJson",
                "inputs": {
                    "content": "@body('Http_AI_Fingerprint_Call')",
                    "schema": {
                        "type": "object",
                        "properties": {
                            "output": {
                                "type": "array",
                                "items": {
                                    "type": "object",
                                    "properties": {
                                        "content": {
                                            "type": "array",
                                            "items": {
                                                "type": "object",
                                                "properties": {
                                                    "text": {
                                                        "type": "string"
                                                    },
                                                    "type": {
                                                        "type": "string"
                                                    }
                                                }
                                            }
                                        },
                                        "type": {
                                            "type": "string"
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            },
            "Compose_Fingerprint_Raw_Text": {
                "runAfter": {
                    "Parse_AI_Fingerprint_Response": [
                        "Succeeded"
                    ]
                },
                "type": "Compose",
                "inputs": "@coalesce(body('Parse_AI_Fingerprint_Response')?['output']?[1]?['content']?[0]?['text'], body('Parse_AI_Fingerprint_Response')?['output']?[0]?['content']?[0]?['text'], '{\"incident_type\":\"Other\",\"detection_rule\":\"Unknown\",\"primary_entities\":[],\"environment_scope\":\"Single User\",\"likely_cause_category\":\"Unknown\",\"source_system\":\"Microsoft Sentinel\"}')"
            },
            "Parse_Fingerprint_JSON": {
                "runAfter": {
                    "Compose_Fingerprint_Raw_Text": [
                        "Succeeded"
                    ]
                },
                "type": "ParseJson",
                "inputs": {
                    "content": "@outputs('Compose_Fingerprint_Raw_Text')",
                    "schema": {
                        "type": "object",
                        "properties": {
                            "incident_type": {
                                "type": "string"
                            },
                            "detection_rule": {
                                "type": "string"
                            },
                            "primary_entities": {
                                "type": "array",
                                "items": {
                                    "type": "string"
                                }
                            },
                            "environment_scope": {
                                "type": "string"
                            },
                            "likely_cause_category": {
                                "type": "string"
                            },
                            "source_system": {
                                "type": "string"
                            }
                        }
                    }
                }
            },
            "Compose_Fingerprint_DeduplicationKey": {
                "runAfter": {
                    "Parse_Fingerprint_JSON": [
                        "Succeeded",
                        "Failed"
                    ]
                },
                "type": "Compose",
                "inputs": "@toLower(concat(coalesce(body('Parse_Fingerprint_JSON')?['incident_type'], 'other'), '|', substring(coalesce(body('Parse_Fingerprint_JSON')?['detection_rule'], 'unknown'), 0, min(50, length(coalesce(body('Parse_Fingerprint_JSON')?['detection_rule'], 'unknown')))), '|', join(take(coalesce(body('Parse_Fingerprint_JSON')?['primary_entities'], json('[]')), min(5, length(coalesce(body('Parse_Fingerprint_JSON')?['primary_entities'], json('[]'))))), ',')))"
            },
            "Compose_Fingerprint_Key_Sanitized": {
                "runAfter": {
                    "Compose_Fingerprint_DeduplicationKey": [
                        "Succeeded",
                        "Failed"
                    ]
                },
                "type": "Compose",
                "inputs": "@trim(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(outputs('Compose_Fingerprint_DeduplicationKey'), decodeUriComponent('%0A'), ''), decodeUriComponent('%0D'), ''), decodeUriComponent('%09'), ''), decodeUriComponent('%C2%A0'), ' '), decodeUriComponent('%E2%80%8B'), ''), decodeUriComponent('%E2%80%8C'), ''), decodeUriComponent('%E2%80%8D'), ''), decodeUriComponent('%E2%80%98'), ''), decodeUriComponent('%E2%80%99'), ''), decodeUriComponent('%E2%80%94'), '-'), decodeUriComponent('%E2%80%93'), '-'), decodeUriComponent('%EF%BB%BF'), ''))"
            },
            "Compose_Incident_Fingerprint": {
                "runAfter": {
                    "Compose_Fingerprint_Key_Sanitized": [
                        "Succeeded",
                        "Failed"
                    ]
                },
                "type": "Compose",
                "inputs": {
                    "sentinel_incident_id": "@outputs('Compose_Worker_Payload')?['incidentId']",
                    "sentinel_incident_title": "@outputs('Compose_Worker_Payload')?['incidentTitle']",
                    "sentinel_severity": "@outputs('Compose_Worker_Payload')?['incidentSeverity']",
                    "sentinel_arm_id": "@outputs('Compose_Worker_Payload')?['incidentArmId']",
                    "incident_type": "@coalesce(body('Parse_Fingerprint_JSON')?['incident_type'], 'Other')",
                    "detection_rule": "@coalesce(body('Parse_Fingerprint_JSON')?['detection_rule'], 'Unknown')",
                    "primary_entities": "@coalesce(body('Parse_Fingerprint_JSON')?['primary_entities'], json('[]'))",
                    "environment_scope": "@coalesce(body('Parse_Fingerprint_JSON')?['environment_scope'], 'Single User')",
                    "likely_cause_category": "@coalesce(body('Parse_Fingerprint_JSON')?['likely_cause_category'], 'Unknown')",
                    "source_system": "@coalesce(body('Parse_Fingerprint_JSON')?['source_system'], 'Microsoft Sentinel')",
                    "deduplication_key": "@outputs('Compose_Fingerprint_Key_Sanitized')",
                    "generated_utc": "@utcNow()"
                }
            },
            "Compose_AI_Full_Comment": {
                "runAfter": {
                    "Initialize_AI_Chunk_Index": [
                        "Succeeded"
                    ]
                },
                "type": "Compose",
                "inputs": "@concat('<p class=\"editor-paragraph\"><b><strong class=\"editor-text-bold\">🤖 AI Security Analysis (Beta ', variables('FinalAIModel'), ')</strong></b><br><br>', variables('FinalAIText'), '<br><br><i><em class=\"editor-text-italic\">Tokens used: ', string(variables('FinalAITokens')), '</em></i></p>')"
            },
            "Compose_AI_Comment_Length": {
                "runAfter": {
                    "Compose_AI_Full_Comment": [
                        "Succeeded"
                    ]
                },
                "type": "Compose",
                "inputs": "@length(string(outputs('Compose_AI_Full_Comment')))"
            },
            "Compose_AI_Chunk_Count": {
                "runAfter": {
                    "Compose_AI_Comment_Length": [
                        "Succeeded"
                    ]
                },
                "type": "Compose",
                "inputs": "@add(div(outputs('Compose_AI_Comment_Length'), 28000), if(greater(mod(outputs('Compose_AI_Comment_Length'), 28000), 0), 1, 0))"
            },
            "Until_AI_Chunks_Built": {
                "actions": {
                    "Compose_AI_Chunk_Start": {
                        "type": "Compose",
                        "inputs": "@mul(variables('AIChunkIndex'), 28000)"
                    },
                    "Compose_AI_Chunk_Text": {
                        "runAfter": {
                            "Compose_AI_Chunk_Start": [
                                "Succeeded"
                            ]
                        },
                        "type": "Compose",
                        "inputs": "@substring(string(outputs('Compose_AI_Full_Comment')), outputs('Compose_AI_Chunk_Start'), min(28000, sub(outputs('Compose_AI_Comment_Length'), outputs('Compose_AI_Chunk_Start'))))"
                    },
                    "Compose_AI_Chunk_Label": {
                        "runAfter": {
                            "Compose_AI_Chunk_Text": [
                                "Succeeded"
                            ]
                        },
                        "type": "Compose",
                        "inputs": "@if(greater(outputs('Compose_AI_Chunk_Count'), 1), concat('[Part ', add(variables('AIChunkIndex'), 1), ' of ', outputs('Compose_AI_Chunk_Count'), '] '), '')"
                    },
                    "Append_AI_Chunk": {
                        "runAfter": {
                            "Compose_AI_Chunk_Label": [
                                "Succeeded"
                            ]
                        },
                        "type": "AppendToArrayVariable",
                        "inputs": {
                            "name": "AICommentChunks",
                            "value": "@concat(outputs('Compose_AI_Chunk_Label'), outputs('Compose_AI_Chunk_Text'))"
                        }
                    },
                    "Increment_AI_Chunk_Index": {
                        "runAfter": {
                            "Append_AI_Chunk": [
                                "Succeeded"
                            ]
                        },
                        "type": "IncrementVariable",
                        "inputs": {
                            "name": "AIChunkIndex",
                            "value": 1
                        }
                    }
                },
                "runAfter": {
                    "Compose_AI_Chunk_Count": [
                        "Succeeded"
                    ]
                },
                "expression": "@greaterOrEquals(variables('AIChunkIndex'), outputs('Compose_AI_Chunk_Count'))",
                "limit": {
                    "count": 10,
                    "timeout": "PT5M"
                },
                "type": "Until"
            },
            "Until_AI_Posted_All_Chunks": {
                "actions": {
                    "Post_AI_Comment_Chunk": {
                        "type": "Http",
                        "inputs": {
                            "uri": "https://management.azure.com@{triggerBody()?['object']?['id']}/comments/@{guid()}?api-version=2023-02-01",
                            "method": "PUT",
                            "headers": {
                                "Content-Type": "application/json"
                            },
                            "body": {
                                "properties": {
                                    "message": "@{variables('AICommentChunks')[variables('AIPostIndex')]}"
                                }
                            },
                            "authentication": {
                                "type": "ManagedServiceIdentity"
                            }
                        }
                    },
                    "Decrement_AI_Post_Index": {
                        "runAfter": {
                            "Post_AI_Comment_Chunk": [
                                "Succeeded",
                                "Failed"
                            ]
                        },
                        "type": "DecrementVariable",
                        "inputs": {
                            "name": "AIPostIndex",
                            "value": 1
                        }
                    }
                },
                "runAfter": {
                    "Initialize_AI_Post_Index": [
                        "Succeeded"
                    ]
                },
                "expression": "@less(variables('AIPostIndex'), 0)",
                "limit": {
                    "count": 10,
                    "timeout": "PT10M"
                },
                "type": "Until"
            },
            "Compose_Enrichment_Part1": {
                "runAfter": {
                    "Until_AI_Posted_All_Chunks": [
                        "Succeeded",
                        "Failed"
                    ]
                },
                "type": "Compose",
                "inputs": "@concat('<p class=\"editor-paragraph\"><strong>🦠 Threat Intelligence Enrichment Data</strong><br><br>',\n  if(not(equals(coalesce(outputs('Compose_Hosts_Response')?['hostTableHTML'], ''), '')),\n     concat('<strong>💻 Host Defender Timeline</strong><br><table style=\"border-collapse:collapse;width:100%;font-size:13px\"><tr style=\"background:#1a1a2e;color:#fff\"><th style=\"padding:6px 10px;border:1px solid #444\">Host</th><th>OS</th><th>Timeline</th><th>⚙ Process</th><th>🌐 Network</th><th>📄 File</th><th>🔐 Logon</th><th>🚨 Alerts</th><th>🛡 Events</th></tr>', outputs('Compose_Hosts_Response')?['hostTableHTML'], '</table><br>'),\n     '<strong>💻 Host Defender Timeline</strong><br>No host entities in this incident.<br>'),\n  if(not(equals(coalesce(outputs('Compose_Accounts_Response')?['accountTableHTML'], ''), '')),\n     concat('<strong>👤 Account Enrichment</strong><br><table style=\"border-collapse:collapse;width:100%;font-size:13px\"><tr style=\"background:#1a1a2e;color:#fff\"><th>Display Name</th><th>UPN</th><th>AD Account</th><th>Title</th><th>Dept</th><th>Status</th><th>Pwd Change</th><th>Sign-Ins</th><th>SVC</th><th>Risk</th><th>Cloud</th><th>On-Prem</th><th>Match</th></tr>', outputs('Compose_Accounts_Response')?['accountTableHTML'], '</table><br>'),\n     '<strong>👤 Account Enrichment</strong><br>No account entities in this incident.<br>'),\n  if(not(equals(coalesce(outputs('Compose_VT_Response')?['vtURLTableHTML'], ''), '')),\n     concat('<br><strong>🔗 VirusTotal URL Reports</strong><br><table style=\"border-collapse:collapse;width:100%;font-size:13px\"><tr style=\"background:#1a1a2e;color:#fff\"><th>URL</th><th>Status</th><th>🔴 Malicious</th><th>🟡 Suspicious</th><th>🟢 Harmless</th><th>⚪ Undetected</th><th>Report</th></tr>', outputs('Compose_VT_Response')?['vtURLTableHTML'], '</table>'),\n     '<br><strong>🔗 VirusTotal URL Reports</strong><br>No URL entities in this incident.<br>'),\n  if(not(equals(coalesce(outputs('Compose_VT_Response')?['vtIPTableHTML'], ''), '')),\n     concat('<br><strong>🌐 VirusTotal IP Reports</strong><br><table style=\"border-collapse:collapse;width:100%;font-size:13px\"><tr style=\"background:#1a1a2e;color:#fff\"><th>IP</th><th>ASN</th><th>Owner</th><th>Country</th><th>Reputation</th><th>🔴 Malicious</th><th>🟡 Suspicious</th><th>Report</th></tr>', outputs('Compose_VT_Response')?['vtIPTableHTML'], '</table>'),\n     '<br><strong>🌐 VirusTotal IP Reports</strong><br>No IP entities in this incident.<br>'),\n  if(not(equals(coalesce(outputs('Compose_VT_Response')?['vtHashTableHTML'], ''), '')),\n     concat('<br><strong>🧬 VirusTotal File Hash Reports</strong><br><table style=\"border-collapse:collapse;width:100%;font-size:13px\"><tr style=\"background:#1a1a2e;color:#fff\"><th>Hash</th><th>Algo</th><th>File Name</th><th>Type</th><th>Reputation</th><th>🔴 Malicious</th><th>🟡 Suspicious</th><th>⚪ Undetected</th><th>Report</th></tr>', outputs('Compose_VT_Response')?['vtHashTableHTML'], '</table>'),\n     '<br><strong>🧬 VirusTotal File Hash Reports</strong><br>No file hash entities in this incident.<br>')\n)"
            },
            "Compose_Enrichment_Part2": {
                "runAfter": {
                    "Compose_Enrichment_Part1": [
                        "Succeeded"
                    ]
                },
                "type": "Compose",
                "inputs": "@concat(\n  if(not(equals(coalesce(outputs('Compose_Netskope_Response')?['nsURLTableHTML'], ''), '')),\n     concat('<br><strong>🛡️ Netskope URL Category Reports</strong><br><table style=\"border-collapse:collapse;width:100%;font-size:13px\"><tr style=\"background:#1a1a2e;color:#fff\"><th>URL</th><th>Site</th><th>Primary Category</th><th>All Categories</th><th>URL Lists</th><th>Classification</th></tr>', outputs('Compose_Netskope_Response')?['nsURLTableHTML'], '</table>'),\n     '<br><strong>🛡️ Netskope URL Category Reports</strong><br>No URL entities in this incident.<br>'),\n  if(not(equals(coalesce(outputs('Compose_Netskope_Response')?['nsClickTableHTML'], ''), '')),\n     concat('<br><strong>🖱️ URL Click &amp; Connection Events (30d)</strong><br><table style=\"border-collapse:collapse;width:100%;font-size:13px\"><tr style=\"background:#1a1a2e;color:#fff\"><th>URL</th><th>📧 Clicks</th><th>Click Details</th><th>💻 Connections</th><th>Connection Details</th></tr>', outputs('Compose_Netskope_Response')?['nsClickTableHTML'], '</table>'),\n     '<br><strong>🖱️ URL Click &amp; Connection Events</strong><br>No URL click data in this incident.<br>'),\n  if(not(equals(coalesce(outputs('Compose_AbuseIPDB_Response')?['abuseIPTableHTML'], ''), '')),\n     concat('<br><strong>🚨 AbuseIPDB Reports</strong><br><table style=\"border-collapse:collapse;width:100%;font-size:13px\"><tr style=\"background:#1a1a2e;color:#fff\"><th>IP</th><th>Score</th><th>Reports</th><th>Reporters</th><th>Country</th><th>ISP</th><th>Usage Type</th><th>Whitelisted</th><th>Last Reported</th><th>Link</th></tr>', outputs('Compose_AbuseIPDB_Response')?['abuseIPTableHTML'], '</table>'),\n     '<br><strong>🚨 AbuseIPDB Reports</strong><br>No IP entities in this incident.<br>'),\n  if(not(equals(coalesce(outputs('Compose_URLScan_Response')?['urlscanTableHTML'], ''), '')),\n     concat('<br><strong>🔍 urlscan.io Scan Results</strong><br><table style=\"border-collapse:collapse;width:100%;font-size:13px\"><tr style=\"background:#1a1a2e;color:#fff\"><th>URL</th><th>Source</th><th>Verdict</th><th>Score</th><th>Domain</th><th>IP</th><th>Country</th><th>ASN</th><th>Server</th><th>🔴 Malicious Resources</th><th>HTTPS%</th><th>Links</th></tr>', outputs('Compose_URLScan_Response')?['urlscanTableHTML'], '</table>'),\n     '<br><strong>🔍 urlscan.io Scan Results</strong><br>No URL entities in this incident.<br>'),\n  if(not(equals(coalesce(outputs('Compose_EmailTI_Response')?['emailTableHTML'], ''), '')),\n     concat('<br><strong>📧 Email Delivery Analysis (30d)</strong><br><table style=\"border-collapse:collapse;width:100%;font-size:13px\"><tr style=\"background:#1a1a2e;color:#fff\"><th>URL / Hash</th><th>Deliveries</th><th>Recipient</th><th>Action</th><th>Threat Types</th><th>Attachments</th></tr>', outputs('Compose_EmailTI_Response')?['emailTableHTML'], '</table>'),\n     '<br><strong>📧 Email Delivery Analysis</strong><br>No email delivery data in this incident.<br>'),\n  if(not(equals(coalesce(outputs('Compose_EmailTI_Response')?['tiTableHTML'], ''), '')),\n     concat('<br><strong>🎯 Sentinel TI Matches</strong><br><table style=\"border-collapse:collapse;width:100%;font-size:13px\"><tr style=\"background:#1a1a2e;color:#fff\"><th>Type</th><th>Value</th><th>Matches</th><th>Threat Type</th><th>Severity</th><th>Confidence</th><th>Description</th></tr>', outputs('Compose_EmailTI_Response')?['tiTableHTML'], '</table>'),\n     '<br><strong>🎯 Sentinel TI Matches</strong><br>No TI indicator matches in this incident.<br>'),\n  if(not(equals(coalesce(outputs('Compose_MDE_Response')?['mdeDeviceTableHTML'], ''), '')),\n     concat('<br><strong>🖥️ MDE Device Profile</strong><br><table style=\"border-collapse:collapse;width:100%;font-size:13px\"><tr style=\"background:#1a1a2e;color:#fff\"><th style=\"padding:6px 10px;border:1px solid #444\">Device</th><th>OS</th><th>Last Seen</th><th>Onboarding</th><th>Risk</th><th>Exposure</th><th>Health</th><th>Managed By</th><th>AAD Joined</th><th>RBAC Group</th><th>Active Alerts</th><th>Logon Users</th></tr>', outputs('Compose_MDE_Response')?['mdeDeviceTableHTML'], '</table><br>'),\n     '<br><strong>🖥️ MDE Device Profile</strong><br>No host entities in this incident.<br>'),\n  if(not(equals(coalesce(outputs('Compose_MDE_Response')?['mdeAlertTableHTML'], ''), '')),\n     concat('<br><strong>🚨 MDE Active Alerts on Device (7d)</strong><br><table style=\"border-collapse:collapse;width:100%;font-size:13px\"><tr style=\"background:#1a1a2e;color:#fff\"><th style=\"padding:6px 10px;border:1px solid #444\">Device</th><th>Title</th><th>Severity</th><th>Category</th><th>Status</th><th>First Event</th><th>Last Update</th><th>MITRE</th><th>Link</th></tr>', outputs('Compose_MDE_Response')?['mdeAlertTableHTML'], '</table><br>'),\n     ''),\n  if(not(equals(coalesce(outputs('Compose_MDE_Response')?['mdeProcessTableHTML'], ''), '')),\n     concat('<br><strong>⚙️ MDE Process Events (±2h)</strong><br><table style=\"border-collapse:collapse;width:100%;font-size:12px\"><tr style=\"background:#1a1a2e;color:#fff\"><th style=\"padding:5px 8px;border:1px solid #444\">Time</th><th>Device</th><th>Account</th><th>Parent Process</th><th>Process</th><th>Command Line</th><th>SHA256</th></tr>', outputs('Compose_MDE_Response')?['mdeProcessTableHTML'], '</table><br>'),\n     ''),\n  if(not(equals(coalesce(outputs('Compose_MDE_Response')?['mdeNetworkTableHTML'], ''), '')),\n     concat('<br><strong>🌐 MDE Network Events (±2h)</strong><br><table style=\"border-collapse:collapse;width:100%;font-size:12px\"><tr style=\"background:#1a1a2e;color:#fff\"><th style=\"padding:5px 8px;border:1px solid #444\">Time</th><th>Device</th><th>Action</th><th>Remote IP</th><th>Remote URL</th><th>Port</th><th>Protocol</th><th>Process</th><th>Account</th></tr>', outputs('Compose_MDE_Response')?['mdeNetworkTableHTML'], '</table><br>'),\n     ''),\n  if(not(equals(coalesce(outputs('Compose_MDE_Response')?['mdeFileTableHTML'], ''), '')),\n     concat('<br><strong>📄 MDE File Events (±2h)</strong><br><table style=\"border-collapse:collapse;width:100%;font-size:12px\"><tr style=\"background:#1a1a2e;color:#fff\"><th style=\"padding:5px 8px;border:1px solid #444\">Time</th><th>Device</th><th>Action</th><th>File</th><th>Path</th><th>SHA256</th><th>Parent Process</th><th>Account</th></tr>', outputs('Compose_MDE_Response')?['mdeFileTableHTML'], '</table><br>'),\n     ''),\n  if(not(equals(coalesce(outputs('Compose_MDE_Response')?['mdeLogonTableHTML'], ''), '')),\n     concat('<br><strong>👤 MDE Logged-On Users</strong><br><table style=\"border-collapse:collapse;width:100%;font-size:13px\"><tr style=\"background:#1a1a2e;color:#fff\"><th style=\"padding:6px 10px;border:1px solid #444\">Device</th><th>Account</th><th>Domain</th><th>Type</th><th>First Seen</th><th>Last Seen</th><th>Logon Types</th><th>Count</th></tr>', outputs('Compose_MDE_Response')?['mdeLogonTableHTML'], '</table><br>'),\n     ''),\n'</p>'\n)"
            },
            "Compose_Enrichment_Full_Comment": {
                "runAfter": {
                    "Compose_Enrichment_Part2": [
                        "Succeeded"
                    ]
                },
                "type": "Compose",
                "inputs": "@concat(outputs('Compose_Enrichment_Part1'), outputs('Compose_Enrichment_Part2'))"
            },
            "Compose_Enrichment_Comment_Length": {
                "runAfter": {
                    "Initialize_Enrichment_Chunk_Index": [
                        "Succeeded"
                    ]
                },
                "type": "Compose",
                "inputs": "@length(string(outputs('Compose_Enrichment_Full_Comment')))"
            },
            "Compose_Enrichment_Chunk_Count": {
                "runAfter": {
                    "Compose_Enrichment_Comment_Length": [
                        "Succeeded"
                    ]
                },
                "type": "Compose",
                "inputs": "@add(div(outputs('Compose_Enrichment_Comment_Length'), 28000), if(greater(mod(outputs('Compose_Enrichment_Comment_Length'), 28000), 0), 1, 0))"
            },
            "Until_Enrichment_Chunks_Built": {
                "actions": {
                    "Compose_Enrichment_Chunk_Start": {
                        "type": "Compose",
                        "inputs": "@mul(variables('EnrichmentChunkIndex'), 28000)"
                    },
                    "Compose_Enrichment_Chunk_Text": {
                        "runAfter": {
                            "Compose_Enrichment_Chunk_Start": [
                                "Succeeded"
                            ]
                        },
                        "type": "Compose",
                        "inputs": "@substring(string(outputs('Compose_Enrichment_Full_Comment')), outputs('Compose_Enrichment_Chunk_Start'), min(28000, sub(outputs('Compose_Enrichment_Comment_Length'), outputs('Compose_Enrichment_Chunk_Start'))))"
                    },
                    "Compose_Enrichment_Chunk_Label": {
                        "runAfter": {
                            "Compose_Enrichment_Chunk_Text": [
                                "Succeeded"
                            ]
                        },
                        "type": "Compose",
                        "inputs": "@if(greater(outputs('Compose_Enrichment_Chunk_Count'), 1), concat('[Part ', add(variables('EnrichmentChunkIndex'), 1), ' of ', outputs('Compose_Enrichment_Chunk_Count'), '] '), '')"
                    },
                    "Append_Enrichment_Chunk": {
                        "runAfter": {
                            "Compose_Enrichment_Chunk_Label": [
                                "Succeeded"
                            ]
                        },
                        "type": "AppendToArrayVariable",
                        "inputs": {
                            "name": "EnrichmentCommentChunks",
                            "value": "@concat(outputs('Compose_Enrichment_Chunk_Label'), outputs('Compose_Enrichment_Chunk_Text'))"
                        }
                    },
                    "Increment_Enrichment_Chunk_Index": {
                        "runAfter": {
                            "Append_Enrichment_Chunk": [
                                "Succeeded"
                            ]
                        },
                        "type": "IncrementVariable",
                        "inputs": {
                            "name": "EnrichmentChunkIndex",
                            "value": 1
                        }
                    }
                },
                "runAfter": {
                    "Compose_Enrichment_Chunk_Count": [
                        "Succeeded"
                    ]
                },
                "expression": "@greaterOrEquals(variables('EnrichmentChunkIndex'), outputs('Compose_Enrichment_Chunk_Count'))",
                "limit": {
                    "count": 10,
                    "timeout": "PT5M"
                },
                "type": "Until"
            },
            "Until_Enrichment_Posted_All_Chunks": {
                "actions": {
                    "Post_Enrichment_Comment_Chunk": {
                        "type": "Http",
                        "inputs": {
                            "uri": "https://management.azure.com@{triggerBody()?['object']?['id']}/comments/@{guid()}?api-version=2023-02-01",
                            "method": "PUT",
                            "headers": {
                                "Content-Type": "application/json"
                            },
                            "body": {
                                "properties": {
                                    "message": "@{variables('EnrichmentCommentChunks')[variables('EnrichmentPostIndex')]}"
                                }
                            },
                            "authentication": {
                                "type": "ManagedServiceIdentity"
                            }
                        }
                    },
                    "Decrement_Enrichment_Post_Index": {
                        "runAfter": {
                            "Post_Enrichment_Comment_Chunk": [
                                "Succeeded",
                                "Failed"
                            ]
                        },
                        "type": "DecrementVariable",
                        "inputs": {
                            "name": "EnrichmentPostIndex",
                            "value": 1
                        }
                    }
                },
                "runAfter": {
                    "Initialize_Enrichment_Post_Index": [
                        "Succeeded"
                    ]
                },
                "expression": "@less(variables('EnrichmentPostIndex'), 0)",
                "limit": {
                    "count": 10,
                    "timeout": "PT10M"
                },
                "type": "Until"
            },
            "Compose_KQL_Full_Comment": {
                "runAfter": {
                    "Until_Enrichment_Posted_All_Chunks": [
                        "Succeeded",
                        "Failed"
                    ],
                    "Compose_Anchored_Rule_KQL": [
                        "Succeeded",
                        "Failed"
                    ]
                },
                "type": "Compose",
                "inputs": "@concat(\n  '<strong>KQL Query Reference - Incident #', outputs('Compose_Worker_Payload')?['incidentId'], '</strong><br>',\n  '<em>All queries below are pre-populated with the exact time windows and entity values used during this incident analysis. Copy any query directly into Log Analytics to reproduce the original data set.</em><br><br>',\n  outputs('Compose_Anchored_Rule_KQL'),\n  if(not(equals(coalesce(outputs('Compose_Hosts_Response')?['kqlSectionHTML'], ''), '')),\n     concat('<strong>Hosts Worker - Defender Timeline Queries</strong><br><br>',\n       replace(replace(replace(replace(replace(replace(replace(replace(replace(\n          replace(replace(replace(\n            outputs('Compose_Hosts_Response')?['kqlSectionHTML'],\n          '<div style=\\\"border-left:4px solid #2980b9;padding:10px 14px;margin-bottom:20px;background:#f8fafd\\\">', '<blockquote>'),\n          '</div>', '</blockquote>'),\n          '<strong style=\"color:#1a5276;font-size:13px\">', '<strong>'),\n          '<strong style=\"font-size:12px;color:#2471a3\">', '<strong>'),\n          '<span style=\\\"font-family:Consolas,Courier New,monospace;font-size:11px;color:#1c2833;white-space:pre\\\">', '<blockquote>'),\n          '</span>', '</blockquote>'),\n          '<span style=\\\"color:#7f8c8d;font-size:11px;margin-left:10px\\\">', '<br>'),\n          '<em style=\"color:#888\">', '<em>'),\n          '<p class=\"editor-paragraph\">', ''),\n          '</p>', '<br>'),\n          '<strong style=\"font-size:13px\">', '<strong>'),\n          '<strong style=\"font-size:12px\">', '<strong>')\n     ),\n     '<em>No host KQL queries executed - no host entities in this incident.</em><br><br>'),\n  if(not(equals(coalesce(outputs('Compose_Accounts_Response')?['kqlSectionHTML'], ''), '')),\n     concat('<strong>Accounts Worker - Identity and Sign-In Queries</strong><br><br>',\n       replace(replace(replace(replace(replace(replace(replace(replace(replace(\n          replace(replace(replace(\n            outputs('Compose_Accounts_Response')?['kqlSectionHTML'],\n          '<div style=\\\"border-left:4px solid #2980b9;padding:10px 14px;margin-bottom:20px;background:#f8fafd\\\">', '<blockquote>'),\n          '</div>', '</blockquote>'),\n          '<strong style=\"color:#1a5276;font-size:13px\">', '<strong>'),\n          '<strong style=\"font-size:12px;color:#2471a3\">', '<strong>'),\n          '<span style=\\\"font-family:Consolas,Courier New,monospace;font-size:11px;color:#1c2833;white-space:pre\\\">', '<blockquote>'),\n          '</span>', '</blockquote>'),\n          '<span style=\\\"color:#7f8c8d;font-size:11px;margin-left:10px\\\">', '<br>'),\n          '<em style=\"color:#888\">', '<em>'),\n          '<p class=\"editor-paragraph\">', ''),\n          '</p>', '<br>'),\n          '<strong style=\"font-size:13px\">', '<strong>'),\n          '<strong style=\"font-size:12px\">', '<strong>')\n     ),\n     '<em>No account KQL queries executed - no account entities or none resolved in this incident.</em><br><br>'),\n  if(not(equals(coalesce(outputs('Compose_Netskope_Response')?['kqlSectionHTML'], ''), '')),\n     concat('<strong>Netskope Worker - URL Click and Network Queries</strong><br><br>',\n       replace(replace(replace(replace(replace(replace(replace(replace(replace(\n          replace(replace(replace(\n            outputs('Compose_Netskope_Response')?['kqlSectionHTML'],\n          '<div style=\\\"border-left:4px solid #8e44ad;padding:10px 14px;margin-bottom:20px;background:#fdf8ff\\\">', '<blockquote>'),\n          '</div>', '</blockquote>'),\n          '<strong style=\"color:#6c3483;font-size:13px\">', '<strong>'),\n          '<strong style=\"font-size:12px;color:#7d3c98\">', '<strong>'),\n          '<span style=\\\"font-family:Consolas,Courier New,monospace;font-size:11px;color:#1c2833;white-space:pre\\\">', '<blockquote>'),\n          '</span>', '</blockquote>'),\n          '<span style=\\\"color:#7f8c8d;font-size:11px;margin-left:10px\\\">', '<br>'),\n          '<em style=\"color:#888\">', '<em>'),\n          '<p class=\"editor-paragraph\">', ''),\n          '</p>', '<br>'),\n          '<strong style=\"font-size:13px\">', '<strong>'),\n          '<strong style=\"font-size:12px\">', '<strong>')\n     ),\n     '<em>No Netskope URL KQL queries executed - no URL entities or all excluded in this incident.</em><br><br>'),\n  if(not(equals(coalesce(outputs('Compose_MDE_Response')?['kqlSectionHTML'], ''), '')),\n     concat('<strong>&#128421; MDE Worker — Device Telemetry Queries</strong><br><br>',\n       replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(\n         outputs('Compose_MDE_Response')?['kqlSectionHTML'],\n         '<div style=\"border-left:4px solid #2980b9;padding:10px 14px;margin-bottom:20px;background:#f8fafd\">', '<blockquote>'),\n         '</div>', '</blockquote>'),\n         '<strong style=\"color:#1a5276;font-size:13px\">', '<strong>'),\n         '<strong style=\"font-size:12px;color:#2471a3\">', '<strong>'),\n         '<strong style=\"font-size:13px\">', '<strong>'),\n         '<strong style=\"font-size:12px\">', '<strong>'),\n         '<span style=\"font-family:Consolas,Courier New,monospace;font-size:11px;color:#1c2833;white-space:pre\">', '<blockquote>'),\n         '</span>', '</blockquote>'),\n         '<span style=\"color:#7f8c8d;font-size:11px;margin-left:10px\">', '<br>'),\n         '<em style=\"color:#888\">', '<em>'),\n         '<p class=\"editor-paragraph\">', ''),\n         '</p>', '<br>'),\n         '<div style=\"margin-bottom:20px\">', ''),\n         '<div style=\"border-left:4px solid #27ae60;padding:10px 14px;margin-bottom:20px;background:#f2fdf5\">', '<blockquote>')\n     ),\n     '<em>No MDE queries executed — no host entities in this incident.</em><br><br>'),\n  if(not(equals(coalesce(outputs('Compose_EmailTI_Response')?['kqlSectionHTML'], ''), '')),\n     concat('<strong>Email TI Worker - Email Delivery and Threat Intelligence Queries</strong><br><br>',\n       replace(replace(replace(replace(replace(replace(replace(replace(replace(\n          replace(replace(replace(\n            outputs('Compose_EmailTI_Response')?['kqlSectionHTML'],\n          '<div style=\\\"border-left:4px solid #e74c3c;padding:10px 14px;margin-bottom:20px;background:#fdf5f5\\\">', '<blockquote>'),\n          '</div>', '</blockquote>'),\n          '<strong style=\"color:#922b21;font-size:13px\">', '<strong>'),\n          '<strong style=\"font-size:12px;color:#c0392b\">', '<strong>'),\n          '<span style=\\\"font-family:Consolas,Courier New,monospace;font-size:11px;color:#1c2833;white-space:pre\\\">', '<blockquote>'),\n          '</span>', '</blockquote>'),\n          '<span style=\\\"color:#7f8c8d;font-size:11px;margin-left:10px\\\">', '<br>'),\n          '<em style=\"color:#888\">', '<em>'),\n          '<p class=\"editor-paragraph\">', ''),\n          '</p>', '<br>'),\n          '<strong style=\"font-size:13px\">', '<strong>'),\n          '<strong style=\"font-size:12px\">', '<strong>')\n     ),\n     '<em>No Email/TI KQL queries executed - no URL, hash, or IP entities in this incident.</em><br><br>')\n)"
            },
            "Compose_KQL_Comment_Length": {
                "runAfter": {
                    "Initialize_KQL_Chunk_Index": [
                        "Succeeded"
                    ]
                },
                "type": "Compose",
                "inputs": "@length(string(outputs('Compose_KQL_Full_Comment')))"
            },
            "Compose_KQL_Chunk_Count": {
                "runAfter": {
                    "Compose_KQL_Comment_Length": [
                        "Succeeded"
                    ]
                },
                "type": "Compose",
                "inputs": "@add(div(outputs('Compose_KQL_Comment_Length'), 28000), if(greater(mod(outputs('Compose_KQL_Comment_Length'), 28000), 0), 1, 0))"
            },
            "Until_KQL_Chunks_Built": {
                "actions": {
                    "Compose_KQL_Chunk_Start": {
                        "type": "Compose",
                        "inputs": "@mul(variables('KQLChunkIndex'), 28000)"
                    },
                    "Compose_KQL_Chunk_Text": {
                        "runAfter": {
                            "Compose_KQL_Chunk_Start": [
                                "Succeeded"
                            ]
                        },
                        "type": "Compose",
                        "inputs": "@substring(string(outputs('Compose_KQL_Full_Comment')), outputs('Compose_KQL_Chunk_Start'), min(28000, sub(outputs('Compose_KQL_Comment_Length'), outputs('Compose_KQL_Chunk_Start'))))"
                    },
                    "Compose_KQL_Chunk_Label": {
                        "runAfter": {
                            "Compose_KQL_Chunk_Text": [
                                "Succeeded"
                            ]
                        },
                        "type": "Compose",
                        "inputs": "@if(greater(outputs('Compose_KQL_Chunk_Count'), 1), concat('[Part ', add(variables('KQLChunkIndex'), 1), ' of ', outputs('Compose_KQL_Chunk_Count'), '] '), '')"
                    },
                    "Append_KQL_Chunk": {
                        "runAfter": {
                            "Compose_KQL_Chunk_Label": [
                                "Succeeded"
                            ]
                        },
                        "type": "AppendToArrayVariable",
                        "inputs": {
                            "name": "KQLCommentChunks",
                            "value": "@concat(outputs('Compose_KQL_Chunk_Label'), outputs('Compose_KQL_Chunk_Text'))"
                        }
                    },
                    "Increment_KQL_Chunk_Index": {
                        "runAfter": {
                            "Append_KQL_Chunk": [
                                "Succeeded"
                            ]
                        },
                        "type": "IncrementVariable",
                        "inputs": {
                            "name": "KQLChunkIndex",
                            "value": 1
                        }
                    }
                },
                "runAfter": {
                    "Compose_KQL_Chunk_Count": [
                        "Succeeded"
                    ]
                },
                "expression": "@greaterOrEquals(variables('KQLChunkIndex'), outputs('Compose_KQL_Chunk_Count'))",
                "limit": {
                    "count": 10,
                    "timeout": "PT5M"
                },
                "type": "Until"
            },
            "Until_KQL_Posted_All_Chunks": {
                "actions": {
                    "Post_KQL_Comment_Chunk": {
                        "type": "Http",
                        "inputs": {
                            "uri": "https://management.azure.com@{triggerBody()?['object']?['id']}/comments/@{guid()}?api-version=2023-02-01",
                            "method": "PUT",
                            "headers": {
                                "Content-Type": "application/json"
                            },
                            "body": {
                                "properties": {
                                    "message": "@{variables('KQLCommentChunks')[variables('KQLPostIndex')]}"
                                }
                            },
                            "authentication": {
                                "type": "ManagedServiceIdentity"
                            }
                        }
                    },
                    "Decrement_KQL_Post_Index": {
                        "runAfter": {
                            "Post_KQL_Comment_Chunk": [
                                "Succeeded",
                                "Failed"
                            ]
                        },
                        "type": "DecrementVariable",
                        "inputs": {
                            "name": "KQLPostIndex",
                            "value": 1
                        }
                    }
                },
                "runAfter": {
                    "Initialize_KQL_Post_Index": [
                        "Succeeded"
                    ]
                },
                "expression": "@less(variables('KQLPostIndex'), 0)",
                "limit": {
                    "count": 10,
                    "timeout": "PT10M"
                },
                "type": "Until"
            },
            "Condition_High_Risk": {
                "actions": {
                    "Send_High_Risk_Email": {
                        "type": "ApiConnection",
                        "inputs": {
                            "host": {
                                "connection": {
                                    "name": "@parameters('$connections')['office365-1']['connectionId']"
                                }
                            },
                            "method": "post",
                            "body": {
                                "To": "<ANALYST-EMAIL>",
                                "Subject": "🚨 HIGH RISK Sentinel Incident - @{body('Get_incident')?['properties']?['title']} (#@{body('Get_incident')?['name']})",
                                "Body": "@concat('<html><body style=\"font-family:Segoe UI,Arial,sans-serif;font-size:13px;color:#222\"><div style=\"background:#c0392b;color:#fff;padding:14px 20px;border-radius:6px 6px 0 0\"><h2 style=\"margin:0\">🚨 HIGH RISK Security Incident Detected</h2></div><div style=\"border:1px solid #ddd;border-top:none;padding:20px;border-radius:0 0 6px 6px\"><table style=\"width:100%;border-collapse:collapse;margin-bottom:20px\"><tr><td style=\"padding:6px 12px;font-weight:bold;width:180px;background:#f5f5f5;border:1px solid #ddd\">Incident Number</td><td style=\"padding:6px 12px;border:1px solid #ddd;font-family:monospace\">', body('Get_incident')?['name'], '</td></tr><tr><td style=\"padding:6px 12px;font-weight:bold;background:#f5f5f5;border:1px solid #ddd\">Title</td><td style=\"padding:6px 12px;border:1px solid #ddd\">', body('Get_incident')?['properties']?['title'], '</td></tr><tr><td style=\"padding:6px 12px;font-weight:bold;background:#f5f5f5;border:1px solid #ddd\">Severity</td><td style=\"padding:6px 12px;border:1px solid #ddd;font-weight:bold\">', body('Get_incident')?['properties']?['severity'], '</td></tr></table><hr style=\"border:none;border-top:1px solid #ddd;margin:20px 0\"><h3 style=\"color:#c0392b\">🤖 AI Analysis</h3>', variables('FinalAIText'), '</div></body></html>')",
                                "Importance": "High",
                                "IsHtml": true
                            },
                            "path": "/v2/Mail"
                        }
                    }
                },
                "runAfter": {
                    "Until_AI_Posted_All_Chunks": [
                        "Succeeded",
                        "Failed"
                    ]
                },
                "else": {
                    "actions": {}
                },
                "expression": {
                    "and": [
                        {
                            "or": [
                                {
                                    "contains": [
                                        "@toLower(variables('FinalAIText'))",
                                        "severity assessment</strong><br>high"
                                    ]
                                },
                                {
                                    "contains": [
                                        "@toLower(variables('FinalAIText'))",
                                        "severity: high"
                                    ]
                                },
                                {
                                    "contains": [
                                        "@toLower(variables('FinalAIText'))",
                                        "severity assessment: high"
                                    ]
                                },
                                {
                                    "contains": [
                                        "@toLower(variables('FinalAIText'))",
                                        ">high<"
                                    ]
                                },
                                {
                                    "contains": [
                                        "@toLower(variables('FinalAIText'))",
                                        "risk level: high"
                                    ]
                                },
                                {
                                    "contains": [
                                        "@toLower(variables('FinalAIText'))",
                                        "overall risk: high"
                                    ]
                                }
                            ]
                        },
                        {
                            "or": [
                                {
                                    "contains": [
                                        "@toLower(variables('FinalAIText'))",
                                        "false positive likelihood</strong><br>low"
                                    ]
                                },
                                {
                                    "contains": [
                                        "@toLower(variables('FinalAIText'))",
                                        "false positive likelihood</strong><br>very low"
                                    ]
                                },
                                {
                                    "contains": [
                                        "@toLower(variables('FinalAIText'))",
                                        "false positive: low"
                                    ]
                                },
                                {
                                    "contains": [
                                        "@toLower(variables('FinalAIText'))",
                                        "false positive likelihood: low"
                                    ]
                                },
                                {
                                    "contains": [
                                        "@toLower(variables('FinalAIText'))",
                                        "false positive likelihood: very low"
                                    ]
                                },
                                {
                                    "contains": [
                                        "@toLower(variables('FinalAIText'))",
                                        "unlikely to be a false positive"
                                    ]
                                },
                                {
                                    "contains": [
                                        "@toLower(variables('FinalAIText'))",
                                        "low false positive"
                                    ]
                                },
                                {
                                    "contains": [
                                        "@toLower(variables('FinalAIText'))",
                                        "not a false positive"
                                    ]
                                },
                                {
                                    "contains": [
                                        "@toLower(variables('FinalAIText'))",
                                        "false positive likelihood</strong><br>minimal"
                                    ]
                                },
                                {
                                    "contains": [
                                        "@toLower(variables('FinalAIText'))",
                                        "false positive likelihood: minimal"
                                    ]
                                }
                            ]
                        }
                    ]
                },
                "type": "If"
            },
            "Condition_Operational_Review": {
                "actions": {
                    "Http_AI_Operational_Guidance": {
                        "type": "Http",
                        "inputs": {
                            "uri": "https://<AZURE-OPENAI-RESOURCE>.openai.azure.com/openai/v1/responses",
                            "method": "POST",
                            "headers": {
                                "Content-Type": "application/json",
                                "api-key": "<AZURE-OPENAI-API-KEY>"
                            },
                            "body": {
                                "model": "gpt-5.3-chat",
                                "instructions": "You are an IT operations advisor at a retail organization. You will receive a Microsoft Sentinel security incident analysis. Your job is NOT to re-analyze the security threat — that has already been done. Your job is to write a clear, actionable operational review memo for the internal <ORG> IT and operations teams.\n\nCONTEXT: <ORG> uses a 3rd-party SOC that reviews and closes security incidents. Some incidents — even when closed as non-threats — reveal underlying IT issues that need internal follow-up: misconfigurations, failed scripts, account sync issues, software deployment problems, user experience degradation, or root causes that will recur if not fixed.\n\nWRITE THE FOLLOWING SECTIONS IN HTML FORMAT:\n- Use <br> for line breaks, <strong> for bold, <em> for italic\n- No markdown, no HTML document tags, inline HTML content only\n- Use bullet character • for lists\n\nSECTION A — OPERATIONAL SUMMARY<br>\nOne short paragraph: what happened from an IT operations perspective (not a security perspective). Plain language suitable for a helpdesk supervisor or team lead.\n\nSECTION B — ROOT CAUSE (LIKELY)<br>\nWhat is the most probable non-security root cause? Be specific — name the script, process, account, system, or configuration that likely caused this.\n\nSECTION C — TEAMS TO INVOLVE<br>\nWhich internal teams should be looped in? (e.g. Endpoint Management, Identity/Entra, Helpdesk, Network, Application team). One bullet per team with a one-line reason why.\n\nSECTION D — RECOMMENDED ACTIONS<br>\nNumbered action list. Be specific and actionable. Include KQL queries or PowerShell commands where relevant. Each action should state: what to do, where (system/tool), and the expected outcome.\n\nSECTION E — RECURRENCE RISK<br>\nWill this happen again if nothing is done? What is the fix to prevent recurrence?\n\nSECTION F — URGENCY & SUGGESTED TIMELINE<br>\nGiven the operational review score and impact, how urgently should this be addressed? Suggest a timeline (e.g. 'Address within 24 hours', 'Schedule for next maintenance window', 'Monitor for 7 days then close').",
                                "input": "@concat('Provide an operational review memo for the following Sentinel incident. The security AI has already scored this with an Operational Review Need score. Focus entirely on what the internal IT/operations team needs to investigate and fix, not the security threat assessment.\\n\\nOriginal AI Security Analysis:\\n', variables('FinalAIText'), '\\n\\nFull Enrichment Context (accounts, hosts, Defender timeline):\\nAccount data: ', string(coalesce(outputs('Compose_Accounts_Response')?['results'], json('[]'))), '\\nHost data: ', string(coalesce(outputs('Compose_Hosts_Response')?['results'], json('[]'))), '\\nIncident title: ', outputs('Compose_Worker_Payload')?['incidentTitle'], '\\nIncident description: ', outputs('Compose_Worker_Payload')?['incidentDescription'])",
                                "max_output_tokens": 2000
                            }
                        }
                    },
                    "Parse_AI_Operational_Response": {
                        "runAfter": {
                            "Http_AI_Operational_Guidance": [
                                "Succeeded"
                            ]
                        },
                        "type": "ParseJson",
                        "inputs": {
                            "content": "@body('Http_AI_Operational_Guidance')",
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "output": {
                                        "type": "array",
                                        "items": {
                                            "type": "object",
                                            "properties": {
                                                "content": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "text": {
                                                                "type": "string"
                                                            },
                                                            "type": {
                                                                "type": "string"
                                                            }
                                                        }
                                                    }
                                                },
                                                "type": {
                                                    "type": "string"
                                                }
                                            }
                                        }
                                    },
                                    "usage": {
                                        "type": "object",
                                        "properties": {
                                            "total_tokens": {
                                                "type": "integer"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "Compose_AI_Operational_Text": {
                        "runAfter": {
                            "Parse_AI_Operational_Response": [
                                "Succeeded"
                            ]
                        },
                        "type": "Compose",
                        "inputs": "@{coalesce(body('Parse_AI_Operational_Response')?['output']?[1]?['content']?[0]?['text'], body('Parse_AI_Operational_Response')?['output']?[0]?['content']?[0]?['text'], 'Operational guidance AI response not found')}"
                    },
                    "Compose_OpsEmail_PartA": {
                        "runAfter": {
                            "Compose_AI_Operational_Text": [
                                "Succeeded",
                                "Failed"
                            ]
                        },
                        "type": "Compose",
                        "inputs": "@concat('<html><body style=\"font-family:Segoe UI,Arial,sans-serif;font-size:13px;color:#222;max-width:1400px;margin:0 auto\"><div style=\"background:#1565c0;color:#fff;padding:16px 24px;border-radius:6px 6px 0 0\"><h2 style=\"margin:0;font-size:18px\">&#128295; Operational Review Required</h2><p style=\"margin:4px 0 0;font-size:12px;opacity:.85\">Internal <ORG> Team Action Needed</p></div><div style=\"border:1px solid #ddd;border-top:none;padding:20px;border-radius:0 0 6px 6px;margin-bottom:20px\"><table style=\"width:100%;border-collapse:collapse;margin-bottom:20px\"><tr><td style=\"padding:6px 12px;font-weight:bold;width:180px;background:#f5f5f5;border:1px solid #ddd\">Incident Number</td><td style=\"padding:6px 12px;border:1px solid #ddd;font-family:monospace\">',body('Get_incident')?['name'],'</td></tr><tr><td style=\"padding:6px 12px;font-weight:bold;background:#f5f5f5;border:1px solid #ddd\">Title</td><td style=\"padding:6px 12px;border:1px solid #ddd\">',body('Get_incident')?['properties']?['title'],'</td></tr><tr><td style=\"padding:6px 12px;font-weight:bold;background:#f5f5f5;border:1px solid #ddd\">Severity</td><td style=\"padding:6px 12px;border:1px solid #ddd;font-weight:bold\">',body('Get_incident')?['properties']?['severity'],'</td></tr><tr><td style=\"padding:6px 12px;font-weight:bold;background:#f5f5f5;border:1px solid #ddd\">Analytic Rule</td><td style=\"padding:6px 12px;border:1px solid #ddd\">',coalesce(body('Get_Analytic_Rule')?['properties']?['displayName'],'Unknown'),'</td></tr><tr><td style=\"padding:6px 12px;font-weight:bold;background:#f5f5f5;border:1px solid #ddd\">Incident Time</td><td style=\"padding:6px 12px;border:1px solid #ddd;font-family:monospace\">',outputs('Compose_Incident_Time'),'</td></tr></table><div style=\"background:#e3f2fd;border-left:4px solid #1565c0;padding:16px 20px;border-radius:4px;margin-bottom:24px\"><h3 style=\"margin:0 0 12px;color:#1565c0;font-size:15px\">&#128295; Operational Guidance</h3>',outputs('Compose_AI_Operational_Text'),'</div><hr style=\"border:none;border-top:2px solid #eee;margin:24px 0\"><h3 style=\"color:#333;font-size:14px;margin:0 0 12px\">&#129302; AI Security Analysis</h3>',variables('FinalAIText'),'<hr style=\"border:none;border-top:2px solid #eee;margin:24px 0\"><h3 style=\"color:#333;font-size:14px;margin:0 0 12px\">&#129418; Enrichment Data</h3>')"
                    },
                    "Compose_OpsEmail_PartB": {
                        "runAfter": {
                            "Compose_OpsEmail_PartA": [
                                "Succeeded"
                            ]
                        },
                        "type": "Compose",
                        "inputs": "@concat(if(not(equals(coalesce(outputs('Compose_Hosts_Response')?['hostTableHTML'],''),'')), concat('<strong>&#128421; Host Defender Timeline</strong><br><table style=\"border-collapse:collapse;width:100%;font-size:12px\"><tr style=\"background:#1a1a2e;color:#fff\"><th style=\"padding:5px 8px;border:1px solid #444\">Host</th><th>OS</th><th>Timeline</th><th>Process</th><th>Network</th><th>File</th><th>Logon</th><th>Alerts</th><th>Events</th></tr>', outputs('Compose_Hosts_Response')?['hostTableHTML'], '</table><br>'), '<strong>&#128421; Host Defender Timeline</strong><br>No host entities.<br>'), if(not(equals(coalesce(outputs('Compose_Accounts_Response')?['accountTableHTML'],''),'')), concat('<strong>&#128100; Account Enrichment</strong><br><table style=\"border-collapse:collapse;width:100%;font-size:12px\"><tr style=\"background:#1a1a2e;color:#fff\"><th>Display Name</th><th>UPN</th><th>AD Account</th><th>Title</th><th>Dept</th><th>Status</th><th>Pwd Change</th><th>Sign-Ins</th><th>SVC</th><th>Risk</th><th>Cloud</th><th>On-Prem</th><th>Match</th></tr>', outputs('Compose_Accounts_Response')?['accountTableHTML'], '</table><br>'), '<strong>&#128100; Account Enrichment</strong><br>No account entities.<br>'))"
                    },
                    "Compose_OpsEmail_PartC": {
                        "runAfter": {
                            "Compose_OpsEmail_PartB": [
                                "Succeeded"
                            ]
                        },
                        "type": "Compose",
                        "inputs": "@concat(if(not(equals(coalesce(outputs('Compose_VT_Response')?['vtURLTableHTML'],''),'')), concat('<br><strong>&#128279; VirusTotal URL Reports</strong><br><table style=\"border-collapse:collapse;width:100%;font-size:12px\"><tr style=\"background:#1a1a2e;color:#fff\"><th>URL</th><th>Status</th><th>Malicious</th><th>Suspicious</th><th>Harmless</th><th>Undetected</th><th>Report</th></tr>', outputs('Compose_VT_Response')?['vtURLTableHTML'], '</table>'), '<br><strong>&#128279; VirusTotal URL Reports</strong><br>No URL entities.<br>'), if(not(equals(coalesce(outputs('Compose_VT_Response')?['vtIPTableHTML'],''),'')), concat('<br><strong>&#127760; VirusTotal IP Reports</strong><br><table style=\"border-collapse:collapse;width:100%;font-size:12px\"><tr style=\"background:#1a1a2e;color:#fff\"><th>IP</th><th>ASN</th><th>Owner</th><th>Country</th><th>Reputation</th><th>Malicious</th><th>Suspicious</th><th>Report</th></tr>', outputs('Compose_VT_Response')?['vtIPTableHTML'], '</table>'), '<br><strong>&#127760; VirusTotal IP Reports</strong><br>No IP entities.<br>'), if(not(equals(coalesce(outputs('Compose_VT_Response')?['vtHashTableHTML'],''),'')), concat('<br><strong>&#129516; VirusTotal Hash Reports</strong><br><table style=\"border-collapse:collapse;width:100%;font-size:12px\"><tr style=\"background:#1a1a2e;color:#fff\"><th>Hash</th><th>Algo</th><th>File Name</th><th>Type</th><th>Reputation</th><th>Malicious</th><th>Suspicious</th><th>Undetected</th><th>Report</th></tr>', outputs('Compose_VT_Response')?['vtHashTableHTML'], '</table>'), '<br><strong>&#129516; VirusTotal Hash Reports</strong><br>No hash entities.<br>'))"
                    },
                    "Compose_OpsEmail_PartD": {
                        "runAfter": {
                            "Compose_OpsEmail_PartC": [
                                "Succeeded"
                            ]
                        },
                        "type": "Compose",
                        "inputs": "@concat(if(not(equals(coalesce(outputs('Compose_Netskope_Response')?['nsURLTableHTML'],''),'')), concat('<br><strong>&#128737;&#65039; Netskope URL Categories</strong><br><table style=\"border-collapse:collapse;width:100%;font-size:12px\"><tr style=\"background:#1a1a2e;color:#fff\"><th>URL</th><th>Site</th><th>Primary Category</th><th>All Categories</th><th>URL Lists</th><th>Classification</th></tr>', outputs('Compose_Netskope_Response')?['nsURLTableHTML'], '</table>'), '<br><strong>&#128737;&#65039; Netskope URL Categories</strong><br>No URL entities.<br>'), if(not(equals(coalesce(outputs('Compose_AbuseIPDB_Response')?['abuseIPTableHTML'],''),'')), concat('<br><strong>&#128680; AbuseIPDB Reports</strong><br><table style=\"border-collapse:collapse;width:100%;font-size:12px\"><tr style=\"background:#1a1a2e;color:#fff\"><th>IP</th><th>Score</th><th>Reports</th><th>Country</th><th>ISP</th><th>Usage Type</th><th>Last Reported</th><th>Link</th></tr>', outputs('Compose_AbuseIPDB_Response')?['abuseIPTableHTML'], '</table>'), '<br><strong>&#128680; AbuseIPDB Reports</strong><br>No IP entities.<br>'), if(not(equals(coalesce(outputs('Compose_EmailTI_Response')?['tiTableHTML'],''),'')), concat('<br><strong>&#127919; Sentinel TI Matches</strong><br><table style=\"border-collapse:collapse;width:100%;font-size:12px\"><tr style=\"background:#1a1a2e;color:#fff\"><th>Type</th><th>Value</th><th>Matches</th><th>Threat Type</th><th>Severity</th><th>Confidence</th><th>Description</th></tr>', outputs('Compose_EmailTI_Response')?['tiTableHTML'], '</table>'), '<br><strong>&#127919; Sentinel TI Matches</strong><br>No TI matches.<br>'))"
                    },
                    "Compose_OpsEmail_PartE": {
                        "runAfter": {
                            "Compose_OpsEmail_PartD": [
                                "Succeeded",
                                "Failed"
                            ]
                        },
                        "type": "Compose",
                        "inputs": "@concat('<hr style=\"border:none;border-top:2px solid #eee;margin:24px 0\"><h3 style=\"color:#333;font-size:14px;margin:0 0 12px\">&#128203; KQL Query Reference</h3><em style=\"color:#666;font-size:11px\">All queries below are pre-populated with the exact time windows and entity values from this incident. Paste directly into Log Analytics to reproduce results.</em><br><br>', outputs('Compose_KQL_Full_Comment'), '<p style=\"color:#999;font-size:11px;margin-top:24px;border-top:1px solid #eee;padding-top:12px\">Generated by <ORG> Sentinel AI Triage. Operational Review threshold: score &gt; 2.</p></div></body></html>')"
                    },
                    "Send_Operational_Review_Email": {
                        "runAfter": {
                            "Compose_OpsEmail_PartE": [
                                "Succeeded",
                                "Failed"
                            ]
                        },
                        "type": "ApiConnection",
                        "inputs": {
                            "host": {
                                "connection": {
                                    "name": "@parameters('$connections')['office365-1']['connectionId']"
                                }
                            },
                            "method": "post",
                            "body": {
                                "To": "<ANALYST-EMAIL>;<OPS-LEAD-EMAIL>",
                                "Subject": "@concat('🔧 Operational Review Needed — ', body('Get_incident')?['properties']?['title'], ' (#', body('Get_incident')?['name'], ')')",
                                "Body": "@concat(outputs('Compose_OpsEmail_PartA'), outputs('Compose_OpsEmail_PartB'), outputs('Compose_OpsEmail_PartC'), outputs('Compose_OpsEmail_PartD'), outputs('Compose_OpsEmail_PartE'))",
                                "Importance": "Normal",
                                "IsHtml": true
                            },
                            "path": "/v2/Mail"
                        }
                    },
                    "Compose_ServiceNow_Worker_Payload": {
                        "runAfter": {
                            "Send_Operational_Review_Email": [
                                "Succeeded",
                                "Failed"
                            ]
                        },
                        "type": "Compose",
                        "inputs": {
                            "hardFingerprint": "@outputs('Compose_Hard_Fingerprint_Capped')",
                            "incidentId": "@outputs('Compose_Worker_Payload')?['incidentId']",
                            "incidentTitle": "@outputs('Compose_Worker_Payload')?['incidentTitle']",
                            "incidentSeverity": "@outputs('Compose_Worker_Payload')?['incidentSeverity']",
                            "analyticRuleName": "@coalesce(body('Get_Analytic_Rule')?['properties']?['displayName'], 'Unknown Rule')",
                            "incidentUrl": "@concat('https://portal.azure.com/#asset/Microsoft_Azure_Security_Insights/Incident/', triggerBody()?['object']?['id'])",
                            "aiAnalysisText": "@variables('FinalAIText')",
                            "aiOperationalText": "@outputs('Compose_AI_Operational_Text')",
                            "accounts": "@coalesce(outputs('Compose_Worker_Payload')?['accounts'], json('[]'))",
                            "hosts": "@coalesce(outputs('Compose_Worker_Payload')?['hosts'], json('[]'))",
                            "vtURLTableHTML": "@coalesce(outputs('Compose_VT_Response')?['vtURLTableHTML'], '')",
                            "vtIPTableHTML": "@coalesce(outputs('Compose_VT_Response')?['vtIPTableHTML'], '')",
                            "vtHashTableHTML": "@coalesce(outputs('Compose_VT_Response')?['vtHashTableHTML'], '')",
                            "abuseIPTableHTML": "@coalesce(outputs('Compose_AbuseIPDB_Response')?['abuseIPTableHTML'], '')",
                            "nsURLTableHTML": "@coalesce(outputs('Compose_Netskope_Response')?['nsURLTableHTML'], '')",
                            "nsClickTableHTML": "@coalesce(outputs('Compose_Netskope_Response')?['nsClickTableHTML'], '')",
                            "urlscanTableHTML": "@coalesce(outputs('Compose_URLScan_Response')?['urlscanTableHTML'], '')",
                            "emailTableHTML": "@coalesce(outputs('Compose_EmailTI_Response')?['emailTableHTML'], '')",
                            "tiTableHTML": "@coalesce(outputs('Compose_EmailTI_Response')?['tiTableHTML'], '')",
                            "kqlReferenceHTML": "@string(outputs('Compose_KQL_Full_Comment'))",
                            "hostTableHTML": "@coalesce(outputs('Compose_Hosts_Response')?['hostTableHTML'], '')",
                            "accountTableHTML": "@coalesce(outputs('Compose_Accounts_Response')?['accountTableHTML'], '')",
                            "mdeDeviceTableHTML": "@coalesce(outputs('Compose_MDE_Response')?['mdeDeviceTableHTML'], '')",
                            "mdeAlertTableHTML": "@coalesce(outputs('Compose_MDE_Response')?['mdeAlertTableHTML'], '')",
                            "mdeProcessTableHTML": "@coalesce(outputs('Compose_MDE_Response')?['mdeProcessTableHTML'], '')",
                            "mdeNetworkTableHTML": "@coalesce(outputs('Compose_MDE_Response')?['mdeNetworkTableHTML'], '')",
                            "mdeFileTableHTML": "@coalesce(outputs('Compose_MDE_Response')?['mdeFileTableHTML'], '')",
                            "mdeLogonTableHTML": "@coalesce(outputs('Compose_MDE_Response')?['mdeLogonTableHTML'], '')"
                        }
                    },
                    "Call_Worker_ServiceNow": {
                        "runAfter": {
                            "Compose_ServiceNow_Worker_Payload": [
                                "Succeeded"
                            ]
                        },
                        "type": "Http",
                        "inputs": {
                            "uri": "@parameters('WorkerURL_ServiceNow')",
                            "method": "POST",
                            "headers": {
                                "Content-Type": "application/json",
                                "x-worker-key": "@parameters('WorkerSharedKey')"
                            },
                            "body": "@outputs('Compose_ServiceNow_Worker_Payload')"
                        },
                        "operationOptions": "DisableAsyncPattern",
                        "runtimeConfiguration": {
                            "contentTransfer": {
                                "transferMode": "Chunked"
                            }
                        }
                    },
                    "Compose_ServiceNow_Response": {
                        "runAfter": {
                            "Call_Worker_ServiceNow": [
                                "Succeeded",
                                "Failed",
                                "TimedOut",
                                "Skipped"
                            ]
                        },
                        "type": "Compose",
                        "inputs": "@coalesce(body('Call_Worker_ServiceNow'), json('{\"action\":\"skipped\",\"ticketNumber\":\"\",\"ticketUrl\":\"\",\"message\":\"ServiceNow worker did not respond\"}'))"
                    }
                },
                "runAfter": {
                    "Until_KQL_Posted_All_Chunks": [
                        "Succeeded",
                        "Failed"
                    ],
                    "Compose_Hard_Fingerprint_Capped": [
                        "Succeeded"
                    ]
                },
                "else": {
                    "actions": {}
                },
                "expression": {
                    "or": [
                        {
                            "contains": [
                                "@toLower(variables('FinalAIText'))",
                                "operational review need: 8/10"
                            ]
                        },
                        {
                            "contains": [
                                "@toLower(variables('FinalAIText'))",
                                "operational review need: 8"
                            ]
                        },
                        {
                            "contains": [
                                "@toLower(variables('FinalAIText'))",
                                "operational review need</strong><br>8"
                            ]
                        },
                        {
                            "contains": [
                                "@toLower(variables('FinalAIText'))",
                                "operational review need</strong><br>8/10"
                            ]
                        },
                        {
                            "contains": [
                                "@toLower(variables('FinalAIText'))",
                                "(b) operational review need 1-10: 8"
                            ]
                        },
                        {
                            "contains": [
                                "@toLower(variables('FinalAIText'))",
                                "operational review need 1-10: 8"
                            ]
                        },
                        {
                            "contains": [
                                "@toLower(variables('FinalAIText'))",
                                "operational review need: 9/10"
                            ]
                        },
                        {
                            "contains": [
                                "@toLower(variables('FinalAIText'))",
                                "operational review need: 9"
                            ]
                        },
                        {
                            "contains": [
                                "@toLower(variables('FinalAIText'))",
                                "operational review need</strong><br>9"
                            ]
                        },
                        {
                            "contains": [
                                "@toLower(variables('FinalAIText'))",
                                "operational review need</strong><br>9/10"
                            ]
                        },
                        {
                            "contains": [
                                "@toLower(variables('FinalAIText'))",
                                "(b) operational review need 1-10: 9"
                            ]
                        },
                        {
                            "contains": [
                                "@toLower(variables('FinalAIText'))",
                                "operational review need 1-10: 9"
                            ]
                        },
                        {
                            "contains": [
                                "@toLower(variables('FinalAIText'))",
                                "operational review need: 10/10"
                            ]
                        },
                        {
                            "contains": [
                                "@toLower(variables('FinalAIText'))",
                                "operational review need: 10"
                            ]
                        },
                        {
                            "contains": [
                                "@toLower(variables('FinalAIText'))",
                                "operational review need</strong><br>10"
                            ]
                        },
                        {
                            "contains": [
                                "@toLower(variables('FinalAIText'))",
                                "operational review need</strong><br>10/10"
                            ]
                        },
                        {
                            "contains": [
                                "@toLower(variables('FinalAIText'))",
                                "(b) operational review need 1-10: 10"
                            ]
                        },
                        {
                            "contains": [
                                "@toLower(variables('FinalAIText'))",
                                "operational review need 1-10: 10"
                            ]
                        }
                    ]
                },
                "type": "If"
            },
            "Initialize_FinalAIText": {
                "runAfter": {
                    "Compose_AI_System_Prompt": [
                        "Succeeded"
                    ]
                },
                "type": "InitializeVariable",
                "inputs": {
                    "variables": [
                        {
                            "name": "FinalAIText",
                            "type": "string",
                            "value": ""
                        }
                    ]
                }
            },
            "Initialize_FinalAITokens": {
                "runAfter": {
                    "Compose_AI_System_Prompt": [
                        "Succeeded"
                    ]
                },
                "type": "InitializeVariable",
                "inputs": {
                    "variables": [
                        {
                            "name": "FinalAITokens",
                            "type": "integer",
                            "value": 0
                        }
                    ]
                }
            },
            "Initialize_FinalAIModel": {
                "runAfter": {
                    "Compose_AI_System_Prompt": [
                        "Succeeded"
                    ]
                },
                "type": "InitializeVariable",
                "inputs": {
                    "variables": [
                        {
                            "name": "FinalAIModel",
                            "type": "string",
                            "value": "gpt-5.3-chat"
                        }
                    ]
                }
            },
            "Initialize_AI_Chunk_Index": {
                "runAfter": {
                    "Condition_Needs_AI_Split": [
                        "Succeeded",
                        "Failed"
                    ]
                },
                "type": "InitializeVariable",
                "inputs": {
                    "variables": [
                        {
                            "name": "AICommentChunks",
                            "type": "array",
                            "value": []
                        },
                        {
                            "name": "AIChunkIndex",
                            "type": "integer",
                            "value": 0
                        }
                    ]
                }
            },
            "Initialize_AI_Post_Index": {
                "runAfter": {
                    "Until_AI_Chunks_Built": [
                        "Succeeded"
                    ]
                },
                "type": "InitializeVariable",
                "inputs": {
                    "variables": [
                        {
                            "name": "AIPostIndex",
                            "type": "integer",
                            "value": "@sub(length(variables('AICommentChunks')), 1)"
                        }
                    ]
                }
            },
            "Initialize_Enrichment_Chunk_Index": {
                "runAfter": {
                    "Compose_Enrichment_Full_Comment": [
                        "Succeeded"
                    ]
                },
                "type": "InitializeVariable",
                "inputs": {
                    "variables": [
                        {
                            "name": "EnrichmentCommentChunks",
                            "type": "array",
                            "value": []
                        },
                        {
                            "name": "EnrichmentChunkIndex",
                            "type": "integer",
                            "value": 0
                        }
                    ]
                }
            },
            "Initialize_Enrichment_Post_Index": {
                "runAfter": {
                    "Until_Enrichment_Chunks_Built": [
                        "Succeeded"
                    ]
                },
                "type": "InitializeVariable",
                "inputs": {
                    "variables": [
                        {
                            "name": "EnrichmentPostIndex",
                            "type": "integer",
                            "value": "@sub(length(variables('EnrichmentCommentChunks')), 1)"
                        }
                    ]
                }
            },
            "Initialize_KQL_Chunk_Index": {
                "runAfter": {
                    "Compose_KQL_Full_Comment": [
                        "Succeeded"
                    ]
                },
                "type": "InitializeVariable",
                "inputs": {
                    "variables": [
                        {
                            "name": "KQLCommentChunks",
                            "type": "array",
                            "value": []
                        },
                        {
                            "name": "KQLChunkIndex",
                            "type": "integer",
                            "value": 0
                        }
                    ]
                }
            },
            "Initialize_KQL_Post_Index": {
                "runAfter": {
                    "Until_KQL_Chunks_Built": [
                        "Succeeded"
                    ]
                },
                "type": "InitializeVariable",
                "inputs": {
                    "variables": [
                        {
                            "name": "KQLPostIndex",
                            "type": "integer",
                            "value": "@sub(length(variables('KQLCommentChunks')), 1)"
                        }
                    ]
                }
            }
        },
        "outputs": {},
        "parameters": {
            "WorkerURL_VT": {
                "defaultValue": "https://<LOGIC-APP-HOST>:443/workflows/<WORKFLOW-ID>/triggers/HTTP_Request/paths/invoke?api-version=2016-10-01&sp=%2Ftriggers%2FHTTP_Request%2Frun&sv=1.0&sig=<SAS-SIGNATURE>",
                "type": "String"
            },
            "WorkerURL_URLScan": {
                "defaultValue": "https://<LOGIC-APP-HOST>:443/workflows/<WORKFLOW-ID>/triggers/HTTP_Request/paths/invoke?api-version=2016-10-01&sp=%2Ftriggers%2FHTTP_Request%2Frun&sv=1.0&sig=<SAS-SIGNATURE>",
                "type": "String"
            },
            "WorkerURL_Netskope": {
                "defaultValue": "https://<LOGIC-APP-HOST>:443/workflows/<WORKFLOW-ID>/triggers/HTTP_Request/paths/invoke?api-version=2016-10-01&sp=%2Ftriggers%2FHTTP_Request%2Frun&sv=1.0&sig=<SAS-SIGNATURE>",
                "type": "String"
            },
            "WorkerURL_AbuseIPDB": {
                "defaultValue": "https://<LOGIC-APP-HOST>:443/workflows/<WORKFLOW-ID>/triggers/HTTP_Request/paths/invoke?api-version=2016-10-01&sp=%2Ftriggers%2FHTTP_Request%2Frun&sv=1.0&sig=<SAS-SIGNATURE>",
                "type": "String"
            },
            "WorkerURL_Accounts": {
                "defaultValue": "https://<LOGIC-APP-HOST>:443/workflows/<WORKFLOW-ID>/triggers/HTTP_Request/paths/invoke?api-version=2016-10-01&sp=%2Ftriggers%2FHTTP_Request%2Frun&sv=1.0&sig=<SAS-SIGNATURE>",
                "type": "String"
            },
            "WorkerURL_Hosts": {
                "defaultValue": "https://<LOGIC-APP-HOST>:443/workflows/<WORKFLOW-ID>/triggers/HTTP_Request/paths/invoke?api-version=2016-10-01&sp=%2Ftriggers%2FHTTP_Request%2Frun&sv=1.0&sig=<SAS-SIGNATURE>",
                "type": "String"
            },
            "WorkerURL_EmailTI": {
                "defaultValue": "https://<LOGIC-APP-HOST>:443/workflows/<WORKFLOW-ID>/triggers/HTTP_Request/paths/invoke?api-version=2016-10-01&sp=%2Ftriggers%2FHTTP_Request%2Frun&sv=1.0&sig=<SAS-SIGNATURE>",
                "type": "String"
            },
            "WorkerSharedKey": {
                "defaultValue": "<WORKER-SHARED-KEY>",
                "type": "String"
            },
            "WorkerURL_ServiceNow": {
                "defaultValue": "https://<LOGIC-APP-HOST>:443/workflows/<WORKFLOW-ID>/triggers/HTTP_Request/paths/invoke?api-version=2016-10-01&sp=%2Ftriggers%2FHTTP_Request%2Frun&sv=1.0&sig=<SAS-SIGNATURE>",
                "type": "String"
            },
            "WorkerURL_MDE": {
                "defaultValue": "https://<LOGIC-APP-HOST>:443/workflows/<WORKFLOW-ID>/triggers/HTTP_Request/paths/invoke?api-version=2016-10-01&sp=%2Ftriggers%2FHTTP_Request%2Frun&sv=1.0&sig=<SAS-SIGNATURE>",
                "type": "String"
            },
            "$connections": {
                "type": "Object",
                "defaultValue": {}
            }
        }
    },
    "parameters": {
        "WorkerURL_VT": {
            "value": "https://<LOGIC-APP-HOST>:443/workflows/<WORKFLOW-ID>/triggers/HTTP_Request/paths/invoke?api-version=2016-10-01&sp=%2Ftriggers%2FHTTP_Request%2Frun&sv=1.0&sig=<SAS-SIGNATURE>"
        },
        "WorkerURL_URLScan": {
            "value": "https://<LOGIC-APP-HOST>:443/workflows/<WORKFLOW-ID>/triggers/HTTP_Request/paths/invoke?api-version=2016-10-01&sp=%2Ftriggers%2FHTTP_Request%2Frun&sv=1.0&sig=<SAS-SIGNATURE>"
        },
        "WorkerURL_Netskope": {
            "value": "https://<LOGIC-APP-HOST>:443/workflows/<WORKFLOW-ID>/triggers/HTTP_Request/paths/invoke?api-version=2016-10-01&sp=%2Ftriggers%2FHTTP_Request%2Frun&sv=1.0&sig=<SAS-SIGNATURE>"
        },
        "WorkerURL_AbuseIPDB": {
            "value": "https://<LOGIC-APP-HOST>:443/workflows/<WORKFLOW-ID>/triggers/HTTP_Request/paths/invoke?api-version=2016-10-01&sp=%2Ftriggers%2FHTTP_Request%2Frun&sv=1.0&sig=<SAS-SIGNATURE>"
        },
        "WorkerURL_Accounts": {
            "value": "https://<LOGIC-APP-HOST>:443/workflows/<WORKFLOW-ID>/triggers/HTTP_Request/paths/invoke?api-version=2016-10-01&sp=%2Ftriggers%2FHTTP_Request%2Frun&sv=1.0&sig=<SAS-SIGNATURE>"
        },
        "WorkerURL_Hosts": {
            "value": "https://<LOGIC-APP-HOST>:443/workflows/<WORKFLOW-ID>/triggers/HTTP_Request/paths/invoke?api-version=2016-10-01&sp=%2Ftriggers%2FHTTP_Request%2Frun&sv=1.0&sig=<SAS-SIGNATURE>"
        },
        "WorkerURL_EmailTI": {
            "value": "https://<LOGIC-APP-HOST>:443/workflows/<WORKFLOW-ID>/triggers/HTTP_Request/paths/invoke?api-version=2016-10-01&sp=%2Ftriggers%2FHTTP_Request%2Frun&sv=1.0&sig=<SAS-SIGNATURE>"
        },
        "WorkerURL_ServiceNow": {
            "value": "https://<LOGIC-APP-HOST>:443/workflows/<WORKFLOW-ID>/triggers/HTTP_Request/paths/invoke?api-version=2016-10-01&sp=%2Ftriggers%2FHTTP_Request%2Frun&sv=1.0&sig=<SAS-SIGNATURE>"
        },
        "$connections": {
            "type": "Object",
            "value": {
                "azuresentinel-4": {
                    "id": "/subscriptions/<AZURE-SUBSCRIPTION-ID>/providers/Microsoft.Web/locations/westus2/managedApis/azuresentinel",
                    "connectionId": "/subscriptions/<AZURE-SUBSCRIPTION-ID>/resourceGroups/<RESOURCE-GROUP>/providers/Microsoft.Web/connections/azuresentinel-6",
                    "connectionName": "azuresentinel-6",
                    "connectionProperties": {}
                },
                "azuremonitorlogs": {
                    "id": "/subscriptions/<AZURE-SUBSCRIPTION-ID>/providers/Microsoft.Web/locations/westus2/managedApis/azuremonitorlogs",
                    "connectionId": "/subscriptions/<AZURE-SUBSCRIPTION-ID>/resourceGroups/<RESOURCE-GROUP>/providers/Microsoft.Web/connections/azuremonitorlogs-1",
                    "connectionName": "azuremonitorlogs-1",
                    "connectionProperties": {}
                },
                "office365-1": {
                    "id": "/subscriptions/<AZURE-SUBSCRIPTION-ID>/providers/Microsoft.Web/locations/westus2/managedApis/office365",
                    "connectionId": "/subscriptions/<AZURE-SUBSCRIPTION-ID>/resourceGroups/<RESOURCE-GROUP>/providers/Microsoft.Web/connections/office365-2",
                    "connectionName": "office365-2",
                    "connectionProperties": {}
                }
            }
        }
    }
}