diff --git a/Solutions/DORA Compliance/Data/Solution_DORACompliance.json b/Solutions/DORA Compliance/Data/Solution_DORACompliance.json new file mode 100644 index 00000000000..6103f4431ae --- /dev/null +++ b/Solutions/DORA Compliance/Data/Solution_DORACompliance.json @@ -0,0 +1,13 @@ +{ + "Name": "DORA Compliance", + "Author": "Microsoft - support@microsoft.com", + "Logo": "", + "Description": "This Solution enables Microsoft Sentinel users to harness the power of their SIEM to assist in meeting DORA requirements. This Solution comes with pre-defined dashboards, visualizations, and reports, providing users with immediate insights in their DORA environment.", + "Workbooks": [ + "Workbooks/DORACompliance.json" + ], + "Metadata": "SolutionMetadata.json", + "BasePath": "C:\\One\\Azure-Sentinel\\Solutions\\DORA Compliance", + "Version": "3.0.0", + "TemplateSpec": true +} \ No newline at end of file diff --git a/Solutions/DORA Compliance/Package/3.0.0.zip b/Solutions/DORA Compliance/Package/3.0.0.zip new file mode 100644 index 00000000000..1acfd89c15f Binary files /dev/null and b/Solutions/DORA Compliance/Package/3.0.0.zip differ diff --git a/Solutions/DORA Compliance/Package/createUiDefinition.json b/Solutions/DORA Compliance/Package/createUiDefinition.json new file mode 100644 index 00000000000..51800d7d4f6 --- /dev/null +++ b/Solutions/DORA Compliance/Package/createUiDefinition.json @@ -0,0 +1,103 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#", + "handler": "Microsoft.Azure.CreateUIDef", + "version": "0.1.2-preview", + "parameters": { + "config": { + "isWizard": false, + "basics": { + "description": "\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/DORA%20Compliance/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nThis Solution enables Microsoft Sentinel users to harness the power of their SIEM to assist in meeting DORA requirements. This Solution comes with pre-defined dashboards, visualizations, and reports, providing users with immediate insights in their DORA environment.\n\n**Workbooks:** 1\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)", + "subscription": { + "resourceProviders": [ + "Microsoft.OperationsManagement/solutions", + "Microsoft.OperationalInsights/workspaces/providers/alertRules", + "Microsoft.Insights/workbooks", + "Microsoft.Logic/workflows" + ] + }, + "location": { + "metadata": { + "hidden": "Hiding location, we get it from the log analytics workspace" + }, + "visible": false + }, + "resourceGroup": { + "allowExisting": true + } + } + }, + "basics": [ + { + "name": "getLAWorkspace", + "type": "Microsoft.Solutions.ArmApiControl", + "toolTip": "This filters by workspaces that exist in the Resource Group selected", + "condition": "[greater(length(resourceGroup().name),0)]", + "request": { + "method": "GET", + "path": "[concat(subscription().id,'/providers/Microsoft.OperationalInsights/workspaces?api-version=2020-08-01')]" + } + }, + { + "name": "workspace", + "type": "Microsoft.Common.DropDown", + "label": "Workspace", + "placeholder": "Select a workspace", + "toolTip": "This dropdown will list only workspace that exists in the Resource Group selected", + "constraints": { + "allowedValues": "[map(filter(basics('getLAWorkspace').value, (filter) => contains(toLower(filter.id), toLower(resourceGroup().name))), (item) => parse(concat('{\"label\":\"', item.name, '\",\"value\":\"', item.name, '\"}')))]", + "required": true + }, + "visible": true + } + ], + "steps": [ + { + "name": "workbooks", + "label": "Workbooks", + "subLabel": { + "preValidation": "Configure the workbooks", + "postValidation": "Done" + }, + "bladeTitle": "Workbooks", + "elements": [ + { + "name": "workbooks-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "This solution installs workbook(s) to help you gain insights into the telemetry collected in Microsoft Sentinel. After installing the solution, start using the workbook in Manage solution view." + } + }, + { + "name": "workbooks-link", + "type": "Microsoft.Common.TextBlock", + "options": { + "link": { + "label": "Learn more", + "uri": "https://docs.microsoft.com/azure/sentinel/tutorial-monitor-your-data" + } + } + }, + { + "name": "workbook1", + "type": "Microsoft.Common.Section", + "label": "DORA Compliance Workbook (Preview)", + "elements": [ + { + "name": "workbook1-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "Choose your subscription and workspace in which DORA assets are deployed" + } + } + ] + } + ] + } + ], + "outputs": { + "workspace-location": "[first(map(filter(basics('getLAWorkspace').value, (filter) => and(contains(toLower(filter.id), toLower(resourceGroup().name)),equals(filter.name,basics('workspace')))), (item) => item.location))]", + "location": "[location()]", + "workspace": "[basics('workspace')]" + } + } +} diff --git a/Solutions/DORA Compliance/Package/mainTemplate.json b/Solutions/DORA Compliance/Package/mainTemplate.json new file mode 100644 index 00000000000..8f43a10ef92 --- /dev/null +++ b/Solutions/DORA Compliance/Package/mainTemplate.json @@ -0,0 +1,213 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "author": "Microsoft - support@microsoft.com", + "comments": "Solution template for DORA Compliance" + }, + "parameters": { + "location": { + "type": "string", + "minLength": 1, + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Not used, but needed to pass arm-ttk test `Location-Should-Not-Be-Hardcoded`. We instead use the `workspace-location` which is derived from the LA workspace" + } + }, + "workspace-location": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "[concat('Region to deploy solution resources -- separate from location selection',parameters('location'))]" + } + }, + "workspace": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "Workspace name for Log Analytics where Microsoft Sentinel is setup" + } + }, + "workbook1-name": { + "type": "string", + "defaultValue": "DORA Compliance Workbook (Preview)", + "minLength": 1, + "metadata": { + "description": "Name for the workbook" + } + } + }, + "variables": { + "email": "support@microsoft.com", + "_email": "[variables('email')]", + "_solutionName": "DORA Compliance", + "_solutionVersion": "3.0.0", + "solutionId": "azuresentinel.azure-sentinel-solution-doracompliance", + "_solutionId": "[variables('solutionId')]", + "workbookVersion1": "1.0.0", + "workbookContentId1": "DORAComplianceWorkbook", + "workbookId1": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId1'))]", + "workbookTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId1'))))]", + "_workbookContentId1": "[variables('workbookContentId1')]", + "workspaceResourceId": "[resourceId('microsoft.OperationalInsights/Workspaces', parameters('workspace'))]", + "_workbookcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId1'),'-', variables('workbookVersion1'))))]", + "_solutioncontentProductId": "[concat(take(variables('_solutionId'),50),'-','sl','-', uniqueString(concat(variables('_solutionId'),'-','Solution','-',variables('_solutionId'),'-', variables('_solutionVersion'))))]" + }, + "resources": [ + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('workbookTemplateSpecName1')]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "DORACompliance Workbook with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('workbookVersion1')]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "type": "Microsoft.Insights/workbooks", + "name": "[variables('workbookContentId1')]", + "location": "[parameters('workspace-location')]", + "kind": "shared", + "apiVersion": "2021-08-01", + "metadata": { + "description": "Choose your subscription and workspace in which DORA assets are deployed" + }, + "properties": { + "displayName": "[parameters('workbook1-name')]", + "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"cdf04ff6-caee-458d-a25e-4b37f195ba04\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Subscription\",\"type\":6,\"description\":\"Choose your subscription in which DORA assets are deployed\",\"typeSettings\":{\"includeAll\":false},\"timeContext\":{\"durationMs\":86400000}},{\"id\":\"1317d6e1-f8fa-4ff1-ab04-e456fb11da6f\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Workspace\",\"label\":\"Workspace Name\",\"type\":5,\"description\":\"Choose Workspace where DORA assets reports logs\",\"timeContext\":{\"durationMs\":86400000}},{\"id\":\"453502c4-b5dd-47cb-b0a7-48128c7340cd\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Time\",\"label\":\"Time Range\",\"type\":4,\"description\":\"Choose the time range appropriate for your analysis\",\"typeSettings\":{\"selectableValues\":[{\"durationMs\":300000},{\"durationMs\":900000},{\"durationMs\":1800000},{\"durationMs\":3600000},{\"durationMs\":14400000},{\"durationMs\":43200000},{\"durationMs\":86400000},{\"durationMs\":172800000},{\"durationMs\":259200000},{\"durationMs\":604800000},{\"durationMs\":1209600000},{\"durationMs\":2419200000},{\"durationMs\":2592000000},{\"durationMs\":5184000000},{\"durationMs\":7776000000}],\"allowCustom\":true},\"timeContext\":{\"durationMs\":86400000},\"value\":{\"durationMs\":7776000000}}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 0\"},{\"type\":11,\"content\":{\"version\":\"LinkItem/1.0\",\"style\":\"tabs\",\"links\":[{\"id\":\"d24faee3-b6c4-413d-a517-7b0eeeebc4ca\",\"cellValue\":\"seltab\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Getting Started\",\"subTarget\":\"gettingstarted\",\"postText\":\"\",\"style\":\"link\"},{\"id\":\"3c8b1896-b71e-41e2-a56b-9fb798993288\",\"cellValue\":\"seltab\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Incident Management & Reporting\",\"subTarget\":\"incidentmanagmentreporting\",\"postText\":\"\",\"style\":\"link\"},{\"id\":\"ff48fd19-d478-43fd-91df-ec1e623e9844\",\"cellValue\":\"seltab\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Threat Intelligence & Detection\",\"subTarget\":\"threatintelligencedetection\",\"style\":\"link\"},{\"id\":\"9d3b9486-87f0-48db-9098-b7f1b7108098\",\"cellValue\":\"seltab\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Business Continuity & Recovery\",\"subTarget\":\"businesscontinuityrecovery\",\"style\":\"link\"},{\"id\":\"02fea1a1-b005-4482-aa05-2cd17136e23e\",\"cellValue\":\"seltab\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Compliance Mapping & Evidence\",\"subTarget\":\"compliancemappingevidence\",\"style\":\"link\"}]},\"name\":\"links - 7\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":1,\"content\":{\"json\":\"# DORA to NIST Control Mapping for Security Alerts\\r\\n\\r\\n| **Alert Type / Keyword** | **Mapped DORA Article** | **NIST Control (Reference)** |\\r\\n|--------------------------------------------------|------------------------------------------------|---------------------------------|\\r\\n| Credential Access / Brute Force | Art. 11 (Detection & Response) | PR.AC-1, PR.AC-4 |\\r\\n| Malware / Virus / Ransomware | Art. 10 (ICT Risk Mitigation) | PR.IP-9, DE.CM-4 |\\r\\n| Data Exfiltration / Leak | Art. 11 (Data Protection) | PR.DS-1 |\\r\\n| Service Outage / Availability | Art. 12 (Continuity) | PR.PT-5, RS.RP-1 |\\r\\n| Backup Failure | Art. 13 (Recovery & Resilience) | PR.IP-4 |\\r\\n| Unauthorized Access | Art. 10 (ICT Risk Controls) | PR.AC-6 |\\r\\n| Privilege Escalation | Art. 7 (Risk Management) | PR.AC-5 |\\r\\n| Lateral Movement / Remote Code Execution | Art. 10 (Threat Response) | DE.CM-7 |\\r\\n| Suspicious Login / MFA Bypass | Art. 11 (Access Monitoring) | PR.AC-7 |\\r\\n| Threat Intelligence Match | Art. 20 (Threat Intel) | DE.CM-1 |\\r\\n| Data Connector Failure | Art. 6 (Governance & Control) | ID.BE-5 |\\r\\n| DR Test Failure | Art. 15 (Continuity Testing) | RS.IM-1 |\\r\\n| Incident Closure / Reporting | Art. 25 (Reporting to Authorities) | RS.CO-5 |\\r\\n| TI Feed Activity / IOC Hits | Art. 18 & 20 (Information Sharing & TI) | DE.CM-1 |\\r\\n| Vulnerability Exploitation / CVE Match | Art. 8 (Risk Identification) | ID.RA-1 |\\r\\n| Configuration Change / Policy Update | Art. 6 (Governance) | ID.GV-2 |\\r\\n| Third-Party Service Alert | Art. 16 (Outsourcing Risk) | ID.SC-4 |\\r\\n| Attack Simulation or TLPT | Art. 19 (TLPT Readiness) | RS.IM-2 |\\r\\n| Critical System Unavailable | Art. 12 (Operational Continuity) | PR.PT-5 |\\r\\n| Compliance Violation Alert | Art. 24 (Audit Evidence) | ID.GV-3 |\\r\\n\",\"style\":\"info\"},\"customWidth\":\"50\",\"name\":\"text - 5\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let watchlist = (_GetWatchlist('dora_assets') |project DeviceName );\\r\\nSecurityAlert\\r\\n| extend ControlMapping = case(\\r\\n AlertName has_any (\\\"Credential Access\\\", \\\"Brute Force\\\", \\\"Password Spray\\\"), \\\"DORA-ART11 / NIST PR.AC-1\\\",\\r\\n AlertName has_any (\\\"Data Exfiltration\\\", \\\"Data Leak\\\"), \\\"DORA-ART11 / NIST PR.DS-1\\\",\\r\\n AlertName has_any (\\\"Malware\\\", \\\"Ransomware\\\", \\\"Trojan\\\"), \\\"DORA-ART10 / NIST PR.IP-9\\\",\\r\\n AlertName has_any (\\\"Unauthorized Access\\\", \\\"Privilege Escalation\\\"), \\\"DORA-ART10 / NIST PR.AC-6\\\",\\r\\n AlertName has_any (\\\"Service Outage\\\", \\\"System Down\\\", \\\"Unreachable\\\"), \\\"DORA-ART12 / NIST PR.PT-5\\\",\\r\\n AlertName has_any (\\\"Backup Failure\\\", \\\"Restore Failed\\\"), \\\"DORA-ART13 / NIST PR.IP-4\\\",\\r\\n AlertName has_any (\\\"Threat Intelligence\\\", \\\"IOC Match\\\", \\\"Indicator Hit\\\"), \\\"DORA-ART20 / NIST DE.CM-1\\\",\\r\\n AlertName has_any (\\\"Suspicious Login\\\", \\\"MFA Bypass\\\"), \\\"DORA-ART11 / NIST PR.AC-7\\\",\\r\\n AlertName has_any (\\\"Policy Change\\\", \\\"Configuration Change\\\"), \\\"DORA-ART6 / NIST ID.GV-2\\\",\\r\\n AlertName has_any (\\\"Vulnerability Exploitation\\\", \\\"CVE\\\"), \\\"DORA-ART8 / NIST ID.RA-1\\\",\\r\\n AlertName has_any (\\\"Third-Party\\\", \\\"External Vendor\\\"), \\\"DORA-ART16 / NIST ID.SC-4\\\",\\r\\n AlertName has_any (\\\"TLPT\\\", \\\"Pen Test\\\", \\\"Simulation\\\"), \\\"DORA-ART19 / NIST RS.IM-2\\\",\\r\\n AlertName has_any (\\\"Compliance Violation\\\", \\\"Audit\\\"), \\\"DORA-ART24 / NIST ID.GV-3\\\",\\r\\n AlertName has_any (\\\"Incident Reported\\\", \\\"Notification Sent\\\"), \\\"DORA-ART25 / NIST RS.CO-5\\\",\\r\\n \\\"Unmapped / Not Applicable\\\"\\r\\n)\\r\\n|extend data = todynamic(Entities)\\r\\n|mv-expand data\\r\\n|where tostring(data.Type) == \\\"host\\\"\\r\\n|extend hostname = tostring(data.HostName)\\r\\n|where hostname != \\\"\\\" and hostname in~ (watchlist)\\r\\n| summarize AlertCount = count() by ControlMapping \\r\\n| order by AlertCount desc\",\"size\":3,\"title\":\"Alerts per compliance control mapping\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"visualization\":\"piechart\",\"chartSettings\":{\"showLegend\":true}},\"customWidth\":\"50\",\"name\":\"query - 6\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let watchlist = (_GetWatchlist('dora_assets') |project DeviceName );\\r\\nlet myAlert = SecurityAlert\\r\\n| mv-expand Entity = todynamic(Entities)\\r\\n| extend EntityType = tostring(Entity.Type)\\r\\n| extend DeviceName = iff(EntityType == \\\"host\\\", tostring(Entity.HostName), \\\"\\\")\\r\\n| where DeviceName != \\\"\\\" and DeviceName in~ (watchlist)\\r\\n| summarize DeviceName = make_set(DeviceName) by AlertId = SystemAlertId;\\r\\nmyAlert\\r\\n| join kind=inner ( SecurityIncident | where Status != \\\"Closed\\\"| mv-expand AlertIds | extend AlertId = tostring(AlertIds) | project CreatedTime ,AlertId ,IncidentNumber , Title ,TimeGenerated ,Status , ProviderName, IncidentUrl\\r\\n| summarize arg_max(CreatedTime, *) by AlertId) on AlertId\\r\\n| summarize arg_max(TimeGenerated, *) by IncidentNumber ,tostring(DeviceName)\\r\\n| summarize Incidents = count(), Closed = countif(Status == \\\"Closed\\\"), Active = countif(Status != \\\"Closed\\\") by bin(TimeGenerated, 30d)\",\"size\":0,\"title\":\"Monthly Compliance Summary\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"50\",\"name\":\"query - 6\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"ThreatIntelIndicators\\r\\n|extend ThreatType = tostring(Data.indicator_types[0])\\r\\n| extend DORA_Mapping = case(\\r\\n ThreatType has_any (\\\"Malware\\\",\\\"Variant\\\"), \\\"DORA-ART9 / NIST PR.IP-9\\\",\\r\\n ThreatType has \\\"Phishing\\\", \\\"DORA-ART10 / NIST DE.CM-1\\\",\\r\\n ThreatType has_any (\\\"C2\\\", \\\"Botnet\\\", \\\"CommandAndControl\\\"), \\\"DORA-ART10 / NIST DE.CM-7\\\",\\r\\n ThreatType has_any (\\\"Vulnerability\\\", \\\"Exploit\\\"), \\\"DORA-ART8 / NIST ID.RA-1\\\",\\r\\n ThreatType has_any (\\\"SuspiciousDomain\\\", \\\"MaliciousURL\\\",\\\"malicious-activity\\\"), \\\"DORA-ART11 / NIST DE.CM-8\\\",\\r\\n ThreatType has_any (\\\"ThreatIntel\\\", \\\"APT\\\", \\\"Campaign\\\"), \\\"DORA-ART20 / NIST DE.CM-1\\\",\\r\\n \\\"Unmapped\\\"\\r\\n)\\r\\n| summarize IndicatorCount = count() by DORA_Mapping , ThreatType\\r\\n|where isnotempty(ThreatType)\\r\\n| order by IndicatorCount desc\",\"size\":0,\"title\":\"DORA Mapping by Threat Type present in Threat Intel Report\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"50\",\"name\":\"query - 4\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let watchlist = (_GetWatchlist('dora_assets') |project DeviceName );\\r\\nSecurityAlert\\r\\n| extend ControlMapping = case(\\r\\n AlertName has_any (\\\"Credential Access\\\", \\\"Brute Force\\\", \\\"Password Spray\\\"), \\\"DORA-ART11 / NIST PR.AC-1\\\",\\r\\n AlertName has_any (\\\"Data Exfiltration\\\", \\\"Data Leak\\\"), \\\"DORA-ART11 / NIST PR.DS-1\\\",\\r\\n AlertName has_any (\\\"Malware\\\", \\\"Ransomware\\\", \\\"Trojan\\\"), \\\"DORA-ART10 / NIST PR.IP-9\\\",\\r\\n AlertName has_any (\\\"Unauthorized Access\\\", \\\"Privilege Escalation\\\"), \\\"DORA-ART10 / NIST PR.AC-6\\\",\\r\\n AlertName has_any (\\\"Service Outage\\\", \\\"System Down\\\", \\\"Unreachable\\\"), \\\"DORA-ART12 / NIST PR.PT-5\\\",\\r\\n AlertName has_any (\\\"Backup Failure\\\", \\\"Restore Failed\\\"), \\\"DORA-ART13 / NIST PR.IP-4\\\",\\r\\n AlertName has_any (\\\"Threat Intelligence\\\", \\\"IOC Match\\\", \\\"Indicator Hit\\\"), \\\"DORA-ART20 / NIST DE.CM-1\\\",\\r\\n AlertName has_any (\\\"Suspicious Login\\\", \\\"MFA Bypass\\\"), \\\"DORA-ART11 / NIST PR.AC-7\\\",\\r\\n AlertName has_any (\\\"Policy Change\\\", \\\"Configuration Change\\\"), \\\"DORA-ART6 / NIST ID.GV-2\\\",\\r\\n AlertName has_any (\\\"Vulnerability Exploitation\\\", \\\"CVE\\\"), \\\"DORA-ART8 / NIST ID.RA-1\\\",\\r\\n AlertName has_any (\\\"Third-Party\\\", \\\"External Vendor\\\"), \\\"DORA-ART16 / NIST ID.SC-4\\\",\\r\\n AlertName has_any (\\\"TLPT\\\", \\\"Pen Test\\\", \\\"Simulation\\\"), \\\"DORA-ART19 / NIST RS.IM-2\\\",\\r\\n AlertName has_any (\\\"Compliance Violation\\\", \\\"Audit\\\"), \\\"DORA-ART24 / NIST ID.GV-3\\\",\\r\\n AlertName has_any (\\\"Incident Reported\\\", \\\"Notification Sent\\\"), \\\"DORA-ART25 / NIST RS.CO-5\\\",\\r\\n \\\"Unmapped / Not Applicable\\\"\\r\\n)\\r\\n|where ControlMapping != \\\"Unmapped / Not Applicable\\\"\\r\\n|extend data = todynamic(Entities)\\r\\n|mv-expand data\\r\\n|where tostring(data.Type) == \\\"host\\\"\\r\\n|extend hostname = tostring(data.HostName)\\r\\n|where hostname != \\\"\\\" and hostname in~ (watchlist)\\r\\n|summarize arg_max(TimeGenerated,*) by SystemAlertId\\r\\n| summarize AlertCount = count() by ControlMapping , AlertName , Tactics ,Techniques , AlertLink\\r\\n| order by AlertCount desc\\r\\n\",\"size\":0,\"title\":\"Mapping Alerts to Regulatory Controls\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"AlertLink\",\"formatter\":7,\"formatOptions\":{\"linkTarget\":\"Url\",\"customColumnWidthSetting\":\"100ch\"}}]}},\"name\":\"query - 6\",\"styleSettings\":{\"showBorder\":true}}]},\"conditionalVisibility\":{\"parameterName\":\"seltab\",\"comparison\":\"isEqualTo\",\"value\":\"compliancemappingevidence\"},\"name\":\"compliancemappingevidence\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let watchlist = (_GetWatchlist('dora_assets') |project DeviceName );\\r\\nHeartbeat\\r\\n|extend split_devicename = split(Computer, \\\".\\\" ,0)[0]\\r\\n|where split_devicename in~ (watchlist)\\r\\n| summarize LastHeartbeat = max(TimeGenerated) by Computer\\r\\n| extend TimeSinceLast = datetime_diff('minute', now(), LastHeartbeat)\\r\\n| where TimeSinceLast > 10\\r\\n| project Computer, LastHeartbeat, TimeSinceLast\",\"size\":0,\"title\":\"Inactive servers/devices\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"45\",\"name\":\"query - 4\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let watchlist = (_GetWatchlist('dora_assets') |project DeviceName );\\r\\nEvent\\r\\n| where EventID in (1001, 1069, 1205) or EventLevelName == \\\"Error\\\" and Computer in~ (watchlist)\\r\\n| where RenderedDescription has_any (\\\"failover\\\", \\\"cluster\\\", \\\"replica\\\", \\\"recovery\\\")\\r\\n| extend Action = iff(RenderedDescription contains \\\"failover\\\" ,\\\"Failover\\\", iff(RenderedDescription contains \\\"cluster\\\",\\\"Cluster\\\",iff(RenderedDescription contains \\\"replica\\\" ,\\\"Replica\\\",iff(RenderedDescription contains \\\"recovery\\\",\\\"Recovery\\\",\\\"Null\\\"))))\\r\\n| summarize Count = count() by bin(TimeGenerated, 1d), Computer ,Action \\r\\n|sort by Count\",\"size\":0,\"title\":\"Trend of failover, cluster switch, or backup site activation\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"50\",\"name\":\"query - 5\",\"styleSettings\":{\"showBorder\":true}}]},\"conditionalVisibility\":{\"parameterName\":\"seltab\",\"comparison\":\"isEqualTo\",\"value\":\"businesscontinuityrecovery\"},\"name\":\"businesscontinuityrecovery\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let watchlist = (_GetWatchlist('dora_assets') |project DeviceName );\\r\\nThreatIntelIndicators\\r\\n|where ObservableKey contains \\\"network-traffic\\\"\\r\\n| join kind=innerunique (\\r\\n DeviceNetworkEvents\\r\\n | extend NetworkIP = RemoteIP\\r\\n | where DeviceName != \\\"\\\" and DeviceName in~ (watchlist)\\r\\n) on $left.ObservableValue == $right.NetworkIP\\r\\n| project TimeGenerated, Id, Pattern ,NetworkIP, DeviceName, ActionType ,Data[\\\"indicator_types\\\"] ,Data[\\\"confidence\\\"] \\r\\n| summarize arg_max(TimeGenerated, *) by NetworkIP, DeviceName\",\"size\":0,\"title\":\"Active Threat Indicators (IOC Hits) (which endpoints communicated with IOC IPs)\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"50\",\"name\":\"query - 4\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let watchlist = (_GetWatchlist('dora_assets') |project DeviceName );\\r\\nSecurityAlert\\r\\n|extend data = todynamic(Entities)\\r\\n|mv-expand data\\r\\n|where tostring(data.Type) == \\\"host\\\"\\r\\n|extend hostname = tostring(data.HostName)\\r\\n|where hostname != \\\"\\\" and hostname in~ (watchlist)\\r\\n|summarize arg_max(TimeGenerated,*) by hostname , Tactics , SystemAlertId\\r\\n| summarize AlertCount = count() by Tactics\",\"size\":0,\"title\":\"Alerts by MITRE ATT&CK Techniques\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"AlertCount\",\"formatter\":8,\"formatOptions\":{\"palette\":\"blue\"}}]}},\"customWidth\":\"27\",\"name\":\"query - 5\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let watchlist = (_GetWatchlist('dora_assets') |project DeviceName );\\r\\nSecurityAlert\\r\\n|extend data = todynamic(Entities)\\r\\n|mv-expand data\\r\\n|where tostring(data.Type) == \\\"host\\\"\\r\\n|extend hostname = tostring(data.HostName)\\r\\n|where hostname != \\\"\\\" and hostname in~ (watchlist)\\r\\n|summarize arg_max(TimeGenerated,*) by SystemAlertId\\r\\n| where AlertName has_any (\\\"Blocked\\\", \\\"Prevented\\\")\\r\\n| summarize PreventedCount = count() by ProductName\",\"size\":0,\"title\":\"Failed Attack Attempts (Prevented by Control)\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"22\",\"name\":\"query - 7\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let watchlist = (_GetWatchlist('dora_assets') |project DeviceName );\\r\\nThreatIntelIndicators\\r\\n|where ObservableKey contains \\\"file:hashes.'SHA-256\\\"\\r\\n| join kind=inner (DeviceFileEvents|where DeviceName != \\\"\\\" and DeviceName in~ (watchlist)) on $left.ObservableValue == $right.SHA256\\r\\n| project TimeGenerated, DeviceName, InitiatingProcessFileName, FileName, ObservableValue, Pattern\",\"size\":0,\"title\":\"Malicious File or URL Detection\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"name\":\"query - 6\",\"styleSettings\":{\"showBorder\":true}}]},\"conditionalVisibility\":{\"parameterName\":\"seltab\",\"comparison\":\"isEqualTo\",\"value\":\"threatintelligencedetection\"},\"name\":\"threatintelligencedetectiongroup\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let watchlist = (_GetWatchlist('dora_assets') |project DeviceName );\\r\\nlet myAlert = SecurityAlert\\r\\n| mv-expand Entity = todynamic(Entities)\\r\\n| extend EntityType = tostring(Entity.Type)\\r\\n| extend DeviceName = iff(EntityType == \\\"host\\\", tostring(Entity.HostName), \\\"\\\")\\r\\n| where DeviceName != \\\"\\\" and DeviceName in~ (watchlist)\\r\\n| summarize DeviceName = make_set(DeviceName) by AlertId = SystemAlertId;\\r\\nmyAlert\\r\\n| join kind=inner ( SecurityIncident | where Status == \\\"Closed\\\"| mv-expand AlertIds | extend AlertId = tostring(AlertIds) | project ClosedTime , CreatedTime ,AlertId\\r\\n| summarize arg_max(CreatedTime, *) by AlertId) on AlertId\\r\\n| extend Duration = datetime_diff('hour', ClosedTime, CreatedTime)\\r\\n| summarize Avg_MTTR_Hours = avg(Duration)\",\"size\":4,\"title\":\"Mean Time to Resolve (MTTR)\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"visualization\":\"stat\",\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Avg_MTTR_Hours\"},\"showBorder\":false,\"sortCriteriaField\":\"Avg_MTTR_Hours\"},\"statSettings\":{\"valueAggregation\":\"None\",\"colorSettings\":{\"type\":\"heatmap\",\"mode\":\"foreground\",\"heatmapPalette\":\"coldHot\"},\"tagText\":\"\",\"valueFontStyle\":\"superLarge\"}},\"customWidth\":\"10\",\"name\":\"query - 2\",\"styleSettings\":{\"margin\":\"5px\",\"padding\":\"5px\",\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let watchlist = (_GetWatchlist('dora_assets') |project DeviceName );\\r\\nlet myAlert = SecurityAlert\\r\\n| mv-expand Entity = todynamic(Entities)\\r\\n| extend EntityType = tostring(Entity.Type)\\r\\n| extend DeviceName = iff(EntityType == \\\"host\\\", tostring(Entity.HostName), \\\"\\\")\\r\\n| where DeviceName != \\\"\\\" and DeviceName in~ (watchlist)\\r\\n| summarize DeviceName = make_set(DeviceName) by AlertId = SystemAlertId;\\r\\nmyAlert\\r\\n| join kind=inner ( SecurityIncident | mv-expand AlertIds | extend AlertId = tostring(AlertIds) | project ClosedTime , CreatedTime ,AlertId ,Severity\\r\\n| summarize arg_max(CreatedTime, *) by AlertId) on AlertId\\r\\n| summarize Count = count() by Severity\\r\\n| order by Count desc\",\"size\":1,\"title\":\"Incidents by Severity\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"visualization\":\"piechart\"},\"customWidth\":\"25\",\"name\":\"query - 3\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let watchlist = (_GetWatchlist('dora_assets') |project DeviceName );\\r\\nlet myAlert = SecurityAlert\\r\\n| mv-expand Entity = todynamic(Entities)\\r\\n| extend EntityType = tostring(Entity.Type)\\r\\n| extend DeviceName = iff(EntityType == \\\"host\\\", tostring(Entity.HostName), \\\"\\\")\\r\\n| where DeviceName != \\\"\\\" and DeviceName in~ (watchlist)\\r\\n| summarize DeviceName = make_set(DeviceName) by AlertId = SystemAlertId;\\r\\nmyAlert\\r\\n| join kind=inner ( SecurityIncident | mv-expand AlertIds | extend AlertId = tostring(AlertIds) | project ClosedTime , CreatedTime ,AlertId ,Severity ,Status,Owner\\r\\n| summarize arg_max(CreatedTime, *) by AlertId) on AlertId\\r\\n| where Status != \\\"Closed\\\"\\r\\n|extend assignedTo = Owner[\\\"assignedTo\\\"]\\r\\n|where isnotempty(assignedTo)\\r\\n| summarize OpenCount = count() by tostring(assignedTo)\\r\\n| order by OpenCount desc\",\"size\":1,\"title\":\"Open Incidents by Owner\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"25\",\"name\":\"query - 4\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let watchlist = (_GetWatchlist('dora_assets') |project DeviceName );\\r\\nlet myAlert = SecurityAlert\\r\\n| mv-expand Entity = todynamic(Entities)\\r\\n| extend EntityType = tostring(Entity.Type)\\r\\n| extend DeviceName = iff(EntityType == \\\"host\\\", tostring(Entity.HostName), \\\"\\\")\\r\\n| where DeviceName != \\\"\\\" and DeviceName in~ (watchlist)\\r\\n| summarize DeviceName = make_set(DeviceName) by AlertId = SystemAlertId;\\r\\nmyAlert\\r\\n| join kind=inner ( SecurityIncident | mv-expand AlertIds | extend AlertId = tostring(AlertIds) | project ClosedTime , CreatedTime ,AlertId ,IncidentNumber , Title , Tactics_Category = AdditionalData.tactics \\r\\n|mv-expand Tactics_Category\\r\\n| summarize arg_max(CreatedTime, *) by AlertId) on AlertId\\r\\n|summarize No_Of_Incidents = count() by tostring(Tactics_Category)\\r\\n|sort by No_Of_Incidents\",\"size\":1,\"title\":\"Top Incident Categories\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\"},\"customWidth\":\"40\",\"name\":\"query - 5\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let watchlist = (_GetWatchlist('dora_assets') |project DeviceName );\\r\\nlet myAlert = SecurityAlert\\r\\n| mv-expand Entity = todynamic(Entities)\\r\\n| extend EntityType = tostring(Entity.Type)\\r\\n| extend DeviceName = iff(EntityType == \\\"host\\\", tostring(Entity.HostName), \\\"\\\")\\r\\n| where DeviceName != \\\"\\\" and DeviceName in~ (watchlist)\\r\\n| summarize DeviceName = make_set(DeviceName) by AlertId = SystemAlertId;\\r\\nmyAlert\\r\\n| join kind=inner ( SecurityIncident | where Status == \\\"Closed\\\"| mv-expand AlertIds | extend AlertId = tostring(AlertIds) | project ClosedTime , CreatedTime ,AlertId ,IncidentNumber , Title ,TimeGenerated\\r\\n| summarize arg_max(CreatedTime, *) by AlertId) on AlertId\\r\\n| extend Duration = datetime_diff('hour', ClosedTime, CreatedTime)\\r\\n| summarize arg_max(TimeGenerated, *) by IncidentNumber , Title , CreatedTime , ClosedTime , Duration\\r\\n|project IncidentNumber , Title , CreatedTime , ClosedTime , Duration\\r\\n| sort by Duration\",\"size\":0,\"title\":\"Time taken to resolve the incidents\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"Title\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"Title\",\"sortOrder\":1}]},\"customWidth\":\"50\",\"name\":\"query - 1\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let watchlist = (_GetWatchlist('dora_assets') |project DeviceName );\\r\\nlet myAlert = SecurityAlert\\r\\n| mv-expand Entity = todynamic(Entities)\\r\\n| extend EntityType = tostring(Entity.Type)\\r\\n| extend DeviceName = iff(EntityType == \\\"host\\\", tostring(Entity.HostName), \\\"\\\")\\r\\n| where DeviceName != \\\"\\\" and DeviceName in~ (watchlist)\\r\\n| summarize DeviceName = make_set(DeviceName) by AlertId = SystemAlertId;\\r\\nmyAlert\\r\\n| join kind=inner ( SecurityIncident | where Status != \\\"Closed\\\"| mv-expand AlertIds | extend AlertId = tostring(AlertIds) | project CreatedTime ,AlertId ,IncidentNumber , Title ,TimeGenerated ,Status , ProviderName, IncidentUrl\\r\\n| summarize arg_max(CreatedTime, *) by AlertId) on AlertId\\r\\n| summarize arg_max(TimeGenerated, *) by IncidentNumber\\r\\n| extend Age_Hours = datetime_diff('hour', now(), CreatedTime)\\r\\n| where Age_Hours > 72\\r\\n| order by Age_Hours desc\\r\\n|project IncidentNumber, Title, Status , ProviderName, IncidentUrl , CreatedTime ,Age_Hours\",\"size\":0,\"title\":\"SLA Breach - Incidents Unresolved Beyond 72 Hours\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"IncidentUrl\",\"formatter\":7,\"formatOptions\":{\"linkTarget\":\"Url\"}}]}},\"customWidth\":\"50\",\"name\":\"query - 6\",\"styleSettings\":{\"showBorder\":true}}]},\"conditionalVisibility\":{\"parameterName\":\"seltab\",\"comparison\":\"isEqualTo\",\"value\":\"incidentmanagmentreporting\"},\"name\":\"incidentmanagmentreportinggroup\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":1,\"content\":{\"json\":\"The Microsoft Sentinel Solution for DORA (Digital Operational Resilience Act) Compliance delivers centralized, real-time visibility into your organization’s ICT risks, operational resilience posture, and regulatory readiness. Built for Compliance Officers, Risk Managers, Security Architects, SOC Analysts, and IT Administrators, this workbook enables you to monitor resilience controls, track incidents, map security signals to DORA Articles, and simplify evidence collection for audits.\\r\\n

\\r\\nThis workbook includes pre-built KQL queries aligned with key DORA themes—ICT Risk Management, Incident Reporting, Threat Intelligence, Business Continuity, and Audit & Oversight. These queries can be exported or extended to support deeper investigations, operational reviews, or regulatory assessments.\\r\\n

\\r\\nThe Microsoft Sentinel team welcomes your feedback on this DORA Compliance Solution, including suggestions for additional mappings or automation to further strengthen your organization’s operational resilience obligations. Please share your feedback with us [Here](https://forms.office.com/Pages/ResponsePage.aspx?id=v4j5cvGGr0GRqy180BHbR5vpbw39GIlPr6oh7FnjxTFUOVhBOFowTFlaT1pOSTAxVDdRT1pIUDlINy4u) .\",\"style\":\"info\"},\"name\":\"text - 7\"},{\"type\":1,\"content\":{\"json\":\"### Getting Started with the DORA Compliance Solution\\r\\n\\r\\nThe DORA compliance report in Microsoft Sentinel helps financial institutions and service providers assess and validate adherence to the Digital Operational Resilience Act (DORA). It provides visibility into ICT risk management, incident reporting, resilience measures, and continuity controls across critical infrastructure and digital services.\\r\\n\\r\\nUse the dashboard to:\\r\\n\\r\\n - Monitor disruptions and security incidents mapped to DORA Articles\\r\\n - Evaluate threat intelligence activity\\r\\n - Ensure continuity and recovery mechanisms are effective\\r\\n\\r\\n\\r\\nThe solution also supports streamlined audit preparation, evidence collection, and integration with Azure services to strengthen overall digital operational resilience.\\r\\n\\r\\nPre-requisites to get started:
\\r\\n\\r\\n1. **Connect Data Sources:** \\r\\n Connect applicable data sources to populate reports. Supported data sources include:
\\r\\nNote: Install Sentinel solutions using the links below for each data source. After installation, configure their data connectors (skip if already done).
\\r\\n - ***SecurityEvent / SecurityAlert / SecurityIncident*** (Windows server event logs — login activity, access attempts, anomaly and incident detection). Links : [Install Microsoft Defender for Cloud](https://portal.azure.com/#view/Microsoft_Azure_Marketplace/GalleryItemDetailsBladeNopdl/id/azuresentinel.azure-sentinel-solution-microsoftdefenderforcloud), [Install Microsoft Defender for Office 365](https://portal.azure.com/#view/Microsoft_Azure_Marketplace/GalleryItemDetailsBladeNopdl/id/azuresentinel.azure-sentinel-solution-microsoftdefenderforo365) ,[Install Microsoft Defender XDR](https://portal.azure.com/#view/Microsoft_Azure_Marketplace/GalleryItemDetailsBladeNopdl/id/azuresentinel.azure-sentinel-solution-microsoft365defender) and [Install Microsoft Defender for Endpoint](https://portal.azure.com/#view/Microsoft_Azure_Marketplace/GalleryItemDetailsBladeNopdl/id/azuresentinel.azure-sentinel-solution-microsoftdefenderendpoint)\\r\\n - ***Event/SecurityEvent*** (for fetching latest security events). Link : [Install Windows Security Events via AMA](https://portal.azure.com/#view/Microsoft_Azure_Marketplace/GalleryItemDetailsBladeNopdl/id/azuresentinel.azure-sentinel-solution-securityevents)\\r\\n - ***ThreatIntelIndicators*** (for fetching latest threatID's). Link : [Install Threat Intel](https://portal.azure.com/#view/Microsoft_Azure_Marketplace/GalleryItemDetailsBladeNopdl/id/azuresentinel.azure-sentinel-solution-threatintelligence-updated)
\\r\\n\\r\\n2. **Define DORA Assets:**
\\r\\n Define DORA-relevant assets within your compliance scope using a Watchlist:

\\r\\n\\r\\n **DORA Assets Watchlist** \\r\\n - Save a CSV file with the following columns: `DeviceName, DeviceType`\\r\\n - Repeat same steps as above but use:\\r\\n - **Name:** `dora_assets`\\r\\n - **Alias:** `dora_assets`\\r\\n - **SearchKey:** `DeviceName` \\r\\n
\\r\\n\\r\\n### Included in the Microsoft Sentinel DORA Compliance Solution\\r\\n\\r\\nThis solution enables Microsoft Sentinel users to leverage SIEM capabilities to meet DORA requirements, including resilience monitoring, incident reporting, threat intelligence integration, and business continuity oversight.
\\r\\n\\r\\nThe included Watchlist allows users to define assets within their compliance scope.
\\r\\nThe Workbook contains four tabs with dashboards, visualizations, and reports for immediate insights into your DORA environment:
\\r\\n\\r\\n**Incident Management & Reporting** \\r\\nProvides visibility into incident severity, resolution time, SLA adherence, and analyst workload: \\r\\n\\r\\n1. **Mean Time to Resolve (MTTR):** Average resolution time for incidents.\\r\\n2. **Incidents by Severity:** Breakdown by severity (High, Medium, Low). \\r\\n3. **Open Incidents by Owner:** Active incidents grouped by owner.\\r\\n4. **Top Incident Categories:** Common incident types (malware, phishing, identity compromise, misconfigurations). \\r\\n5. **Time Taken to Resolve the Incidents:** Highlights slow investigations and outliers.\\r\\n6. **SLA Breach – Incidents Unresolved Beyond 72 Hours:** Lists unresolved incidents past SLA threshold. \\r\\n
\\r\\n\\r\\n**Threat Intelligence & Detection** \\r\\nThis tab provides a unified view of threat indicators, adversary behaviors, and detection activity across your environment. It helps analysts correlate real-time IOCs with security alerts, understand attacker tactics using MITRE ATT&CK, identify prevented attacks, and prioritize threats based on confidence and activity levels. This tab strengthens proactive defense by combining threat intelligence with Sentinel’s detection capabilities to surface the most relevant and high-risk threats for investigation.\\r\\n\\r\\n1. **Active Threat Indicators (IOC Hits):** Displays all active indicators of compromise (IOCs) that matched with your environment, showing which endpoints or resources communicated with malicious IPs/domains.\\r\\n2. **Alerts by MITRE ATT&CK Techniques:** Shows all security alerts categorized by MITRE ATT&CK techniques (e.g., Initial Access, Credential Access, Lateral Movement).\\r\\n3. **Failed Attack Attempts (Prevented by Control):** Highlights attacks that were attempted but successfully blocked by security controls (e.g., firewall blocks, Defender real-time protection, policy enforcement).\\r\\n4. **Malicious File or URL Detection:** Displays detections related to malicious files, URLs, email links, or attachments identified by your security solutions.\\r\\n4. **Focus on Indicators with High Confidence and Activity:** Surfaces IOCs with both high confidence (validated, reliable intelligence) and high activity (multiple hits or detections).
\\r\\n\\r\\n**Business Continuity & Recovery** \\r\\nProvides visibility into the operational health of critical infrastructure and the effectiveness of your continuity mechanisms. It helps teams identify inactive or unreachable systems, monitor failover patterns, and track recovery behavior across servers, clusters, and backup sites:\\r\\n\\r\\n1. **Inactive Servers / Devices:** This panel displays servers or devices that have stopped sending heartbeats or logs within the expected time window..\\r\\n2. **Trend of Failover, Cluster Switch, or Backup Site Activation:** It provides insights into whether failover events are expected (planned maintenance) or abnormal (service disruption).
\\r\\n\\r\\n**Compliance Mapping & Evidence** \\r\\nProvides a centralized view of how security alerts, threat intelligence signals, and operational activities align with key DORA regulatory requirements. It helps compliance teams visualize control coverage, track monthly compliance trends, and review evidence that supports regulatory assessments and audits. This tab strengthens operational resilience by ensuring that alerts and threats are mapped to the appropriate DORA Articles, enabling accurate reporting, continuous monitoring, and easier audit preparation.:\\r\\n\\r\\n1. **Alerts per Compliance Control Mapping:** Displays security alerts categorized based on their mapped DORA controls or Articles.\\r\\n2. **Monthly Compliance Summary:** Presents month-over-month tracking of compliance-related activity, including alerts, mapped controls, and evidence logs.\\r\\n3. **DORA Mapping by Threat Type (from Threat Intel Reports)** Correlates threat intelligence categories (e.g., malware, phishing, credential theft, APT activity) with relevant DORA Articles and requirements.\\r\\n4. **Mapping Alerts to Regulatory Controls** Shows detailed alignment between each alert and its corresponding regulatory control or Article, helping auditors validate evidence.
\",\"style\":\"upsell\"},\"name\":\"text - 8\"}]},\"conditionalVisibility\":{\"parameterName\":\"seltab\",\"comparison\":\"isEqualTo\",\"value\":\"gettingstarted\"},\"name\":\"gettingstarted\"}],\"fromTemplateId\":\"sentinel-DORAComplianceWorkbook\",\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\r\n", + "version": "1.0", + "sourceId": "[variables('workspaceResourceId')]", + "category": "sentinel" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Workbook-', last(split(variables('workbookId1'),'/'))))]", + "properties": { + "description": "@{workbookKey=DORAComplianceWorkbook; logoFileName=Azure_Sentinel.svg; description=Choose your subscription and workspace in which DORA assets are deployed; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=1.0.0; title=DORA Compliance Workbook (Preview); templateRelativePath=DORACompliance.json; subtitle=; provider=Microsoft}.description", + "parentId": "[variables('workbookId1')]", + "contentId": "[variables('_workbookContentId1')]", + "kind": "Workbook", + "version": "[variables('workbookVersion1')]", + "source": { + "kind": "Solution", + "name": "DORA Compliance", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Microsoft", + "email": "[variables('_email')]" + }, + "support": { + "tier": "Microsoft", + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "link": "https://support.microsoft.com/" + }, + "dependencies": { + "operator": "AND", + "criteria": [ + { + "contentId": "SecurityEvent", + "kind": "DataType" + }, + { + "contentId": "SecurityAlert", + "kind": "DataType" + }, + { + "contentId": "SecurityIncident", + "kind": "DataType" + }, + { + "contentId": "Event", + "kind": "DataType" + }, + { + "contentId": "ThreatIntelIndicators", + "kind": "DataType" + } + ] + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_workbookContentId1')]", + "contentKind": "Workbook", + "displayName": "[parameters('workbook1-name')]", + "contentProductId": "[variables('_workbookcontentProductId1')]", + "id": "[variables('_workbookcontentProductId1')]", + "version": "[variables('workbookVersion1')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentPackages", + "apiVersion": "2023-04-01-preview", + "location": "[parameters('workspace-location')]", + "properties": { + "version": "3.0.0", + "kind": "Solution", + "contentSchemaVersion": "3.0.0", + "displayName": "DORA Compliance", + "publisherDisplayName": "Microsoft Sentinel, Microsoft Corporation", + "descriptionHtml": "

Note: Please refer to the following before installing the solution:

\n

• Review the solution Release Notes

\n

• There may be known issues pertaining to this Solution, please refer to them before installing.

\n

This Solution enables Microsoft Sentinel users to harness the power of their SIEM to assist in meeting DORA requirements. This Solution comes with pre-defined dashboards, visualizations, and reports, providing users with immediate insights in their DORA environment.

\n

Workbooks: 1

\n

Learn more about Microsoft Sentinel | Learn more about Solutions

\n", + "contentKind": "Solution", + "contentProductId": "[variables('_solutioncontentProductId')]", + "id": "[variables('_solutioncontentProductId')]", + "icon": "", + "contentId": "[variables('_solutionId')]", + "parentId": "[variables('_solutionId')]", + "source": { + "kind": "Solution", + "name": "DORA Compliance", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Microsoft", + "email": "[variables('_email')]" + }, + "support": { + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "tier": "Microsoft", + "link": "https://support.microsoft.com/" + }, + "dependencies": { + "operator": "AND", + "criteria": [ + { + "kind": "Workbook", + "contentId": "[variables('_workbookContentId1')]", + "version": "[variables('workbookVersion1')]" + } + ] + }, + "firstPublishDate": "2025-10-08", + "providers": [ + "Microsoft" + ], + "categories": { + "domains": [ + "Compliance" + ] + } + }, + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', variables('_solutionId'))]" + } + ], + "outputs": {} +} diff --git a/Solutions/DORA Compliance/Package/testParameters.json b/Solutions/DORA Compliance/Package/testParameters.json new file mode 100644 index 00000000000..d11bd91bb50 --- /dev/null +++ b/Solutions/DORA Compliance/Package/testParameters.json @@ -0,0 +1,32 @@ +{ + "location": { + "type": "string", + "minLength": 1, + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Not used, but needed to pass arm-ttk test `Location-Should-Not-Be-Hardcoded`. We instead use the `workspace-location` which is derived from the LA workspace" + } + }, + "workspace-location": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "[concat('Region to deploy solution resources -- separate from location selection',parameters('location'))]" + } + }, + "workspace": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "Workspace name for Log Analytics where Microsoft Sentinel is setup" + } + }, + "workbook1-name": { + "type": "string", + "defaultValue": "DORA Compliance Workbook (Preview)", + "minLength": 1, + "metadata": { + "description": "Name for the workbook" + } + } +} diff --git a/Solutions/DORA Compliance/ReleaseNotes.md b/Solutions/DORA Compliance/ReleaseNotes.md new file mode 100644 index 00000000000..4fe076673cd --- /dev/null +++ b/Solutions/DORA Compliance/ReleaseNotes.md @@ -0,0 +1,3 @@ +| **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** | +|-------------|--------------------------------|------------------------------------------------------------------| +| 3.0.0 | 16-12-2025 | Initial Solution release | \ No newline at end of file diff --git a/Solutions/DORA Compliance/SolutionMetadata.json b/Solutions/DORA Compliance/SolutionMetadata.json new file mode 100644 index 00000000000..3235f8fc3cc --- /dev/null +++ b/Solutions/DORA Compliance/SolutionMetadata.json @@ -0,0 +1,15 @@ +{ + "publisherId": "azuresentinel", + "offerId": "azure-sentinel-solution-doracompliance", + "firstPublishDate": "2025-10-08", + "providers": [ "Microsoft" ], + "categories": { + "domains": [ "Compliance" ] + }, + "support": { + "tier": "Microsoft", + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "link": "https://support.microsoft.com/" + } +} \ No newline at end of file diff --git a/Solutions/DORA Compliance/Workbooks/DORACompliance.json b/Solutions/DORA Compliance/Workbooks/DORACompliance.json new file mode 100644 index 00000000000..c59fd5f0b64 --- /dev/null +++ b/Solutions/DORA Compliance/Workbooks/DORACompliance.json @@ -0,0 +1,656 @@ +{ + "version": "Notebook/1.0", + "items": [ + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "parameters": [ + { + "id": "cdf04ff6-caee-458d-a25e-4b37f195ba04", + "version": "KqlParameterItem/1.0", + "name": "Subscription", + "type": 6, + "description": "Choose your subscription in which DORA assets are deployed", + "typeSettings": { + "additionalResourceOptions": [], + "includeAll": false + }, + "timeContext": { + "durationMs": 86400000 + } + }, + { + "id": "1317d6e1-f8fa-4ff1-ab04-e456fb11da6f", + "version": "KqlParameterItem/1.0", + "name": "Workspace", + "label": "Workspace Name", + "type": 5, + "description": "Choose Workspace where DORA assets reports logs", + "typeSettings": { + "additionalResourceOptions": [] + }, + "timeContext": { + "durationMs": 86400000 + } + }, + { + "id": "453502c4-b5dd-47cb-b0a7-48128c7340cd", + "version": "KqlParameterItem/1.0", + "name": "Time", + "label": "Time Range", + "type": 4, + "description": "Choose the time range appropriate for your analysis", + "typeSettings": { + "selectableValues": [ + { + "durationMs": 300000 + }, + { + "durationMs": 900000 + }, + { + "durationMs": 1800000 + }, + { + "durationMs": 3600000 + }, + { + "durationMs": 14400000 + }, + { + "durationMs": 43200000 + }, + { + "durationMs": 86400000 + }, + { + "durationMs": 172800000 + }, + { + "durationMs": 259200000 + }, + { + "durationMs": 604800000 + }, + { + "durationMs": 1209600000 + }, + { + "durationMs": 2419200000 + }, + { + "durationMs": 2592000000 + }, + { + "durationMs": 5184000000 + }, + { + "durationMs": 7776000000 + } + ], + "allowCustom": true + }, + "timeContext": { + "durationMs": 86400000 + }, + "value": { + "durationMs": 7776000000 + } + } + ], + "style": "pills", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "name": "parameters - 0" + }, + { + "type": 11, + "content": { + "version": "LinkItem/1.0", + "style": "tabs", + "links": [ + { + "id": "d24faee3-b6c4-413d-a517-7b0eeeebc4ca", + "cellValue": "seltab", + "linkTarget": "parameter", + "linkLabel": "Getting Started", + "subTarget": "gettingstarted", + "postText": "", + "style": "link" + }, + { + "id": "3c8b1896-b71e-41e2-a56b-9fb798993288", + "cellValue": "seltab", + "linkTarget": "parameter", + "linkLabel": "Incident Management & Reporting", + "subTarget": "incidentmanagmentreporting", + "postText": "", + "style": "link" + }, + { + "id": "ff48fd19-d478-43fd-91df-ec1e623e9844", + "cellValue": "seltab", + "linkTarget": "parameter", + "linkLabel": "Threat Intelligence & Detection", + "subTarget": "threatintelligencedetection", + "style": "link" + }, + { + "id": "9d3b9486-87f0-48db-9098-b7f1b7108098", + "cellValue": "seltab", + "linkTarget": "parameter", + "linkLabel": "Business Continuity & Recovery", + "subTarget": "businesscontinuityrecovery", + "style": "link" + }, + { + "id": "02fea1a1-b005-4482-aa05-2cd17136e23e", + "cellValue": "seltab", + "linkTarget": "parameter", + "linkLabel": "Compliance Mapping & Evidence", + "subTarget": "compliancemappingevidence", + "style": "link" + } + ] + }, + "name": "links - 7" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "# DORA to NIST Control Mapping for Security Alerts\r\n\r\n| **Alert Type / Keyword** | **Mapped DORA Article** | **NIST Control (Reference)** |\r\n|--------------------------------------------------|------------------------------------------------|---------------------------------|\r\n| Credential Access / Brute Force | Art. 11 (Detection & Response) | PR.AC-1, PR.AC-4 |\r\n| Malware / Virus / Ransomware | Art. 10 (ICT Risk Mitigation) | PR.IP-9, DE.CM-4 |\r\n| Data Exfiltration / Leak | Art. 11 (Data Protection) | PR.DS-1 |\r\n| Service Outage / Availability | Art. 12 (Continuity) | PR.PT-5, RS.RP-1 |\r\n| Backup Failure | Art. 13 (Recovery & Resilience) | PR.IP-4 |\r\n| Unauthorized Access | Art. 10 (ICT Risk Controls) | PR.AC-6 |\r\n| Privilege Escalation | Art. 7 (Risk Management) | PR.AC-5 |\r\n| Lateral Movement / Remote Code Execution | Art. 10 (Threat Response) | DE.CM-7 |\r\n| Suspicious Login / MFA Bypass | Art. 11 (Access Monitoring) | PR.AC-7 |\r\n| Threat Intelligence Match | Art. 20 (Threat Intel) | DE.CM-1 |\r\n| Data Connector Failure | Art. 6 (Governance & Control) | ID.BE-5 |\r\n| DR Test Failure | Art. 15 (Continuity Testing) | RS.IM-1 |\r\n| Incident Closure / Reporting | Art. 25 (Reporting to Authorities) | RS.CO-5 |\r\n| TI Feed Activity / IOC Hits | Art. 18 & 20 (Information Sharing & TI) | DE.CM-1 |\r\n| Vulnerability Exploitation / CVE Match | Art. 8 (Risk Identification) | ID.RA-1 |\r\n| Configuration Change / Policy Update | Art. 6 (Governance) | ID.GV-2 |\r\n| Third-Party Service Alert | Art. 16 (Outsourcing Risk) | ID.SC-4 |\r\n| Attack Simulation or TLPT | Art. 19 (TLPT Readiness) | RS.IM-2 |\r\n| Critical System Unavailable | Art. 12 (Operational Continuity) | PR.PT-5 |\r\n| Compliance Violation Alert | Art. 24 (Audit Evidence) | ID.GV-3 |\r\n", + "style": "info" + }, + "customWidth": "50", + "name": "text - 5", + "styleSettings": { + "showBorder": true + } + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "let watchlist = (_GetWatchlist('dora_assets') |project DeviceName );\r\nSecurityAlert\r\n| extend ControlMapping = case(\r\n AlertName has_any (\"Credential Access\", \"Brute Force\", \"Password Spray\"), \"DORA-ART11 / NIST PR.AC-1\",\r\n AlertName has_any (\"Data Exfiltration\", \"Data Leak\"), \"DORA-ART11 / NIST PR.DS-1\",\r\n AlertName has_any (\"Malware\", \"Ransomware\", \"Trojan\"), \"DORA-ART10 / NIST PR.IP-9\",\r\n AlertName has_any (\"Unauthorized Access\", \"Privilege Escalation\"), \"DORA-ART10 / NIST PR.AC-6\",\r\n AlertName has_any (\"Service Outage\", \"System Down\", \"Unreachable\"), \"DORA-ART12 / NIST PR.PT-5\",\r\n AlertName has_any (\"Backup Failure\", \"Restore Failed\"), \"DORA-ART13 / NIST PR.IP-4\",\r\n AlertName has_any (\"Threat Intelligence\", \"IOC Match\", \"Indicator Hit\"), \"DORA-ART20 / NIST DE.CM-1\",\r\n AlertName has_any (\"Suspicious Login\", \"MFA Bypass\"), \"DORA-ART11 / NIST PR.AC-7\",\r\n AlertName has_any (\"Policy Change\", \"Configuration Change\"), \"DORA-ART6 / NIST ID.GV-2\",\r\n AlertName has_any (\"Vulnerability Exploitation\", \"CVE\"), \"DORA-ART8 / NIST ID.RA-1\",\r\n AlertName has_any (\"Third-Party\", \"External Vendor\"), \"DORA-ART16 / NIST ID.SC-4\",\r\n AlertName has_any (\"TLPT\", \"Pen Test\", \"Simulation\"), \"DORA-ART19 / NIST RS.IM-2\",\r\n AlertName has_any (\"Compliance Violation\", \"Audit\"), \"DORA-ART24 / NIST ID.GV-3\",\r\n AlertName has_any (\"Incident Reported\", \"Notification Sent\"), \"DORA-ART25 / NIST RS.CO-5\",\r\n \"Unmapped / Not Applicable\"\r\n)\r\n|extend data = todynamic(Entities)\r\n|mv-expand data\r\n|where tostring(data.Type) == \"host\"\r\n|extend hostname = tostring(data.HostName)\r\n|where hostname != \"\" and hostname in~ (watchlist)\r\n| summarize AlertCount = count() by ControlMapping \r\n| order by AlertCount desc", + "size": 3, + "title": "Alerts per compliance control mapping", + "timeContextFromParameter": "Time", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "crossComponentResources": [ + "{Workspace}" + ], + "visualization": "piechart", + "chartSettings": { + "showLegend": true + } + }, + "customWidth": "50", + "name": "query - 6", + "styleSettings": { + "showBorder": true + } + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "let watchlist = (_GetWatchlist('dora_assets') |project DeviceName );\r\nlet myAlert = SecurityAlert\r\n| mv-expand Entity = todynamic(Entities)\r\n| extend EntityType = tostring(Entity.Type)\r\n| extend DeviceName = iff(EntityType == \"host\", tostring(Entity.HostName), \"\")\r\n| where DeviceName != \"\" and DeviceName in~ (watchlist)\r\n| summarize DeviceName = make_set(DeviceName) by AlertId = SystemAlertId;\r\nmyAlert\r\n| join kind=inner ( SecurityIncident | where Status != \"Closed\"| mv-expand AlertIds | extend AlertId = tostring(AlertIds) | project CreatedTime ,AlertId ,IncidentNumber , Title ,TimeGenerated ,Status , ProviderName, IncidentUrl\r\n| summarize arg_max(CreatedTime, *) by AlertId) on AlertId\r\n| summarize arg_max(TimeGenerated, *) by IncidentNumber ,tostring(DeviceName)\r\n| summarize Incidents = count(), Closed = countif(Status == \"Closed\"), Active = countif(Status != \"Closed\") by bin(TimeGenerated, 30d)", + "size": 0, + "title": "Monthly Compliance Summary", + "timeContextFromParameter": "Time", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "crossComponentResources": [ + "{Workspace}" + ] + }, + "customWidth": "50", + "name": "query - 6", + "styleSettings": { + "showBorder": true + } + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "ThreatIntelIndicators\r\n|extend ThreatType = tostring(Data.indicator_types[0])\r\n| extend DORA_Mapping = case(\r\n ThreatType has_any (\"Malware\",\"Variant\"), \"DORA-ART9 / NIST PR.IP-9\",\r\n ThreatType has \"Phishing\", \"DORA-ART10 / NIST DE.CM-1\",\r\n ThreatType has_any (\"C2\", \"Botnet\", \"CommandAndControl\"), \"DORA-ART10 / NIST DE.CM-7\",\r\n ThreatType has_any (\"Vulnerability\", \"Exploit\"), \"DORA-ART8 / NIST ID.RA-1\",\r\n ThreatType has_any (\"SuspiciousDomain\", \"MaliciousURL\",\"malicious-activity\"), \"DORA-ART11 / NIST DE.CM-8\",\r\n ThreatType has_any (\"ThreatIntel\", \"APT\", \"Campaign\"), \"DORA-ART20 / NIST DE.CM-1\",\r\n \"Unmapped\"\r\n)\r\n| summarize IndicatorCount = count() by DORA_Mapping , ThreatType\r\n|where isnotempty(ThreatType)\r\n| order by IndicatorCount desc", + "size": 0, + "title": "DORA Mapping by Threat Type present in Threat Intel Report", + "timeContextFromParameter": "Time", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "crossComponentResources": [ + "{Workspace}" + ] + }, + "customWidth": "50", + "name": "query - 4", + "styleSettings": { + "showBorder": true + } + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "let watchlist = (_GetWatchlist('dora_assets') |project DeviceName );\r\nSecurityAlert\r\n| extend ControlMapping = case(\r\n AlertName has_any (\"Credential Access\", \"Brute Force\", \"Password Spray\"), \"DORA-ART11 / NIST PR.AC-1\",\r\n AlertName has_any (\"Data Exfiltration\", \"Data Leak\"), \"DORA-ART11 / NIST PR.DS-1\",\r\n AlertName has_any (\"Malware\", \"Ransomware\", \"Trojan\"), \"DORA-ART10 / NIST PR.IP-9\",\r\n AlertName has_any (\"Unauthorized Access\", \"Privilege Escalation\"), \"DORA-ART10 / NIST PR.AC-6\",\r\n AlertName has_any (\"Service Outage\", \"System Down\", \"Unreachable\"), \"DORA-ART12 / NIST PR.PT-5\",\r\n AlertName has_any (\"Backup Failure\", \"Restore Failed\"), \"DORA-ART13 / NIST PR.IP-4\",\r\n AlertName has_any (\"Threat Intelligence\", \"IOC Match\", \"Indicator Hit\"), \"DORA-ART20 / NIST DE.CM-1\",\r\n AlertName has_any (\"Suspicious Login\", \"MFA Bypass\"), \"DORA-ART11 / NIST PR.AC-7\",\r\n AlertName has_any (\"Policy Change\", \"Configuration Change\"), \"DORA-ART6 / NIST ID.GV-2\",\r\n AlertName has_any (\"Vulnerability Exploitation\", \"CVE\"), \"DORA-ART8 / NIST ID.RA-1\",\r\n AlertName has_any (\"Third-Party\", \"External Vendor\"), \"DORA-ART16 / NIST ID.SC-4\",\r\n AlertName has_any (\"TLPT\", \"Pen Test\", \"Simulation\"), \"DORA-ART19 / NIST RS.IM-2\",\r\n AlertName has_any (\"Compliance Violation\", \"Audit\"), \"DORA-ART24 / NIST ID.GV-3\",\r\n AlertName has_any (\"Incident Reported\", \"Notification Sent\"), \"DORA-ART25 / NIST RS.CO-5\",\r\n \"Unmapped / Not Applicable\"\r\n)\r\n|where ControlMapping != \"Unmapped / Not Applicable\"\r\n|extend data = todynamic(Entities)\r\n|mv-expand data\r\n|where tostring(data.Type) == \"host\"\r\n|extend hostname = tostring(data.HostName)\r\n|where hostname != \"\" and hostname in~ (watchlist)\r\n|summarize arg_max(TimeGenerated,*) by SystemAlertId\r\n| summarize AlertCount = count() by ControlMapping , AlertName , Tactics ,Techniques , AlertLink\r\n| order by AlertCount desc\r\n", + "size": 0, + "title": "Mapping Alerts to Regulatory Controls", + "timeContextFromParameter": "Time", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "crossComponentResources": [ + "{Workspace}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "AlertLink", + "formatter": 7, + "formatOptions": { + "linkTarget": "Url", + "customColumnWidthSetting": "100ch" + } + } + ] + } + }, + "name": "query - 6", + "styleSettings": { + "showBorder": true + } + } + ] + }, + "conditionalVisibility": { + "parameterName": "seltab", + "comparison": "isEqualTo", + "value": "compliancemappingevidence" + }, + "name": "compliancemappingevidence" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "let watchlist = (_GetWatchlist('dora_assets') |project DeviceName );\r\nHeartbeat\r\n|extend split_devicename = split(Computer, \".\" ,0)[0]\r\n|where split_devicename in~ (watchlist)\r\n| summarize LastHeartbeat = max(TimeGenerated) by Computer\r\n| extend TimeSinceLast = datetime_diff('minute', now(), LastHeartbeat)\r\n| where TimeSinceLast > 10\r\n| project Computer, LastHeartbeat, TimeSinceLast", + "size": 0, + "title": "Inactive servers/devices", + "timeContextFromParameter": "Time", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "crossComponentResources": [ + "{Workspace}" + ] + }, + "customWidth": "45", + "name": "query - 4", + "styleSettings": { + "showBorder": true + } + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "let watchlist = (_GetWatchlist('dora_assets') |project DeviceName );\r\nEvent\r\n| where EventID in (1001, 1069, 1205) or EventLevelName == \"Error\" and Computer in~ (watchlist)\r\n| where RenderedDescription has_any (\"failover\", \"cluster\", \"replica\", \"recovery\")\r\n| extend Action = iff(RenderedDescription contains \"failover\" ,\"Failover\", iff(RenderedDescription contains \"cluster\",\"Cluster\",iff(RenderedDescription contains \"replica\" ,\"Replica\",iff(RenderedDescription contains \"recovery\",\"Recovery\",\"Null\"))))\r\n| summarize Count = count() by bin(TimeGenerated, 1d), Computer ,Action \r\n|sort by Count", + "size": 0, + "title": "Trend of failover, cluster switch, or backup site activation", + "timeContextFromParameter": "Time", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "crossComponentResources": [ + "{Workspace}" + ] + }, + "customWidth": "50", + "name": "query - 5", + "styleSettings": { + "showBorder": true + } + } + ] + }, + "conditionalVisibility": { + "parameterName": "seltab", + "comparison": "isEqualTo", + "value": "businesscontinuityrecovery" + }, + "name": "businesscontinuityrecovery" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "let watchlist = (_GetWatchlist('dora_assets') |project DeviceName );\r\nThreatIntelIndicators\r\n|where ObservableKey contains \"network-traffic\"\r\n| join kind=innerunique (\r\n DeviceNetworkEvents\r\n | extend NetworkIP = RemoteIP\r\n | where DeviceName != \"\" and DeviceName in~ (watchlist)\r\n) on $left.ObservableValue == $right.NetworkIP\r\n| project TimeGenerated, Id, Pattern ,NetworkIP, DeviceName, ActionType ,Data[\"indicator_types\"] ,Data[\"confidence\"] \r\n| summarize arg_max(TimeGenerated, *) by NetworkIP, DeviceName", + "size": 0, + "title": "Active Threat Indicators (IOC Hits) (which endpoints communicated with IOC IPs)", + "timeContextFromParameter": "Time", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "crossComponentResources": [ + "{Workspace}" + ] + }, + "customWidth": "50", + "name": "query - 4", + "styleSettings": { + "showBorder": true + } + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "let watchlist = (_GetWatchlist('dora_assets') |project DeviceName );\r\nSecurityAlert\r\n|extend data = todynamic(Entities)\r\n|mv-expand data\r\n|where tostring(data.Type) == \"host\"\r\n|extend hostname = tostring(data.HostName)\r\n|where hostname != \"\" and hostname in~ (watchlist)\r\n|summarize arg_max(TimeGenerated,*) by hostname , Tactics , SystemAlertId\r\n| summarize AlertCount = count() by Tactics", + "size": 0, + "title": "Alerts by MITRE ATT&CK Techniques", + "timeContextFromParameter": "Time", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "crossComponentResources": [ + "{Workspace}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "AlertCount", + "formatter": 8, + "formatOptions": { + "palette": "blue" + } + } + ] + } + }, + "customWidth": "27", + "name": "query - 5", + "styleSettings": { + "showBorder": true + } + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "let watchlist = (_GetWatchlist('dora_assets') |project DeviceName );\r\nSecurityAlert\r\n|extend data = todynamic(Entities)\r\n|mv-expand data\r\n|where tostring(data.Type) == \"host\"\r\n|extend hostname = tostring(data.HostName)\r\n|where hostname != \"\" and hostname in~ (watchlist)\r\n|summarize arg_max(TimeGenerated,*) by SystemAlertId\r\n| where AlertName has_any (\"Blocked\", \"Prevented\")\r\n| summarize PreventedCount = count() by ProductName", + "size": 0, + "title": "Failed Attack Attempts (Prevented by Control)", + "timeContextFromParameter": "Time", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "crossComponentResources": [ + "{Workspace}" + ] + }, + "customWidth": "22", + "name": "query - 7", + "styleSettings": { + "showBorder": true + } + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "let watchlist = (_GetWatchlist('dora_assets') |project DeviceName );\r\nThreatIntelIndicators\r\n|where ObservableKey contains \"file:hashes.'SHA-256\"\r\n| join kind=inner (DeviceFileEvents|where DeviceName != \"\" and DeviceName in~ (watchlist)) on $left.ObservableValue == $right.SHA256\r\n| project TimeGenerated, DeviceName, InitiatingProcessFileName, FileName, ObservableValue, Pattern", + "size": 0, + "title": "Malicious File or URL Detection", + "timeContextFromParameter": "Time", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "crossComponentResources": [ + "{Workspace}" + ] + }, + "name": "query - 6", + "styleSettings": { + "showBorder": true + } + } + ] + }, + "conditionalVisibility": { + "parameterName": "seltab", + "comparison": "isEqualTo", + "value": "threatintelligencedetection" + }, + "name": "threatintelligencedetectiongroup" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "let watchlist = (_GetWatchlist('dora_assets') |project DeviceName );\r\nlet myAlert = SecurityAlert\r\n| mv-expand Entity = todynamic(Entities)\r\n| extend EntityType = tostring(Entity.Type)\r\n| extend DeviceName = iff(EntityType == \"host\", tostring(Entity.HostName), \"\")\r\n| where DeviceName != \"\" and DeviceName in~ (watchlist)\r\n| summarize DeviceName = make_set(DeviceName) by AlertId = SystemAlertId;\r\nmyAlert\r\n| join kind=inner ( SecurityIncident | where Status == \"Closed\"| mv-expand AlertIds | extend AlertId = tostring(AlertIds) | project ClosedTime , CreatedTime ,AlertId\r\n| summarize arg_max(CreatedTime, *) by AlertId) on AlertId\r\n| extend Duration = datetime_diff('hour', ClosedTime, CreatedTime)\r\n| summarize Avg_MTTR_Hours = avg(Duration)", + "size": 4, + "title": "Mean Time to Resolve (MTTR)", + "timeContextFromParameter": "Time", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "crossComponentResources": [ + "{Workspace}" + ], + "visualization": "stat", + "tileSettings": { + "titleContent": { + "columnMatch": "Avg_MTTR_Hours" + }, + "showBorder": false, + "sortCriteriaField": "Avg_MTTR_Hours" + }, + "statSettings": { + "valueAggregation": "None", + "colorSettings": { + "type": "heatmap", + "mode": "foreground", + "heatmapPalette": "coldHot", + "thresholdsGrid": [] + }, + "iconSettings": { + "thresholdsGrid": [] + }, + "tagText": "", + "valueFontStyle": "superLarge" + } + }, + "customWidth": "10", + "name": "query - 2", + "styleSettings": { + "margin": "5px", + "padding": "5px", + "showBorder": true + } + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "let watchlist = (_GetWatchlist('dora_assets') |project DeviceName );\r\nlet myAlert = SecurityAlert\r\n| mv-expand Entity = todynamic(Entities)\r\n| extend EntityType = tostring(Entity.Type)\r\n| extend DeviceName = iff(EntityType == \"host\", tostring(Entity.HostName), \"\")\r\n| where DeviceName != \"\" and DeviceName in~ (watchlist)\r\n| summarize DeviceName = make_set(DeviceName) by AlertId = SystemAlertId;\r\nmyAlert\r\n| join kind=inner ( SecurityIncident | mv-expand AlertIds | extend AlertId = tostring(AlertIds) | project ClosedTime , CreatedTime ,AlertId ,Severity\r\n| summarize arg_max(CreatedTime, *) by AlertId) on AlertId\r\n| summarize Count = count() by Severity\r\n| order by Count desc", + "size": 1, + "title": "Incidents by Severity", + "timeContextFromParameter": "Time", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "crossComponentResources": [ + "{Workspace}" + ], + "visualization": "piechart" + }, + "customWidth": "25", + "name": "query - 3", + "styleSettings": { + "showBorder": true + } + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "let watchlist = (_GetWatchlist('dora_assets') |project DeviceName );\r\nlet myAlert = SecurityAlert\r\n| mv-expand Entity = todynamic(Entities)\r\n| extend EntityType = tostring(Entity.Type)\r\n| extend DeviceName = iff(EntityType == \"host\", tostring(Entity.HostName), \"\")\r\n| where DeviceName != \"\" and DeviceName in~ (watchlist)\r\n| summarize DeviceName = make_set(DeviceName) by AlertId = SystemAlertId;\r\nmyAlert\r\n| join kind=inner ( SecurityIncident | mv-expand AlertIds | extend AlertId = tostring(AlertIds) | project ClosedTime , CreatedTime ,AlertId ,Severity ,Status,Owner\r\n| summarize arg_max(CreatedTime, *) by AlertId) on AlertId\r\n| where Status != \"Closed\"\r\n|extend assignedTo = Owner[\"assignedTo\"]\r\n|where isnotempty(assignedTo)\r\n| summarize OpenCount = count() by tostring(assignedTo)\r\n| order by OpenCount desc", + "size": 1, + "title": "Open Incidents by Owner", + "timeContextFromParameter": "Time", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "customWidth": "25", + "name": "query - 4", + "styleSettings": { + "showBorder": true + } + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "let watchlist = (_GetWatchlist('dora_assets') |project DeviceName );\r\nlet myAlert = SecurityAlert\r\n| mv-expand Entity = todynamic(Entities)\r\n| extend EntityType = tostring(Entity.Type)\r\n| extend DeviceName = iff(EntityType == \"host\", tostring(Entity.HostName), \"\")\r\n| where DeviceName != \"\" and DeviceName in~ (watchlist)\r\n| summarize DeviceName = make_set(DeviceName) by AlertId = SystemAlertId;\r\nmyAlert\r\n| join kind=inner ( SecurityIncident | mv-expand AlertIds | extend AlertId = tostring(AlertIds) | project ClosedTime , CreatedTime ,AlertId ,IncidentNumber , Title , Tactics_Category = AdditionalData.tactics \r\n|mv-expand Tactics_Category\r\n| summarize arg_max(CreatedTime, *) by AlertId) on AlertId\r\n|summarize No_Of_Incidents = count() by tostring(Tactics_Category)\r\n|sort by No_Of_Incidents", + "size": 1, + "title": "Top Incident Categories", + "timeContextFromParameter": "Time", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "piechart" + }, + "customWidth": "40", + "name": "query - 5", + "styleSettings": { + "showBorder": true + } + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "let watchlist = (_GetWatchlist('dora_assets') |project DeviceName );\r\nlet myAlert = SecurityAlert\r\n| mv-expand Entity = todynamic(Entities)\r\n| extend EntityType = tostring(Entity.Type)\r\n| extend DeviceName = iff(EntityType == \"host\", tostring(Entity.HostName), \"\")\r\n| where DeviceName != \"\" and DeviceName in~ (watchlist)\r\n| summarize DeviceName = make_set(DeviceName) by AlertId = SystemAlertId;\r\nmyAlert\r\n| join kind=inner ( SecurityIncident | where Status == \"Closed\"| mv-expand AlertIds | extend AlertId = tostring(AlertIds) | project ClosedTime , CreatedTime ,AlertId ,IncidentNumber , Title ,TimeGenerated\r\n| summarize arg_max(CreatedTime, *) by AlertId) on AlertId\r\n| extend Duration = datetime_diff('hour', ClosedTime, CreatedTime)\r\n| summarize arg_max(TimeGenerated, *) by IncidentNumber , Title , CreatedTime , ClosedTime , Duration\r\n|project IncidentNumber , Title , CreatedTime , ClosedTime , Duration\r\n| sort by Duration", + "size": 0, + "title": "Time taken to resolve the incidents", + "timeContextFromParameter": "Time", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "crossComponentResources": [ + "{Workspace}" + ], + "gridSettings": { + "sortBy": [ + { + "itemKey": "Title", + "sortOrder": 1 + } + ] + }, + "sortBy": [ + { + "itemKey": "Title", + "sortOrder": 1 + } + ] + }, + "customWidth": "50", + "name": "query - 1", + "styleSettings": { + "showBorder": true + } + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "let watchlist = (_GetWatchlist('dora_assets') |project DeviceName );\r\nlet myAlert = SecurityAlert\r\n| mv-expand Entity = todynamic(Entities)\r\n| extend EntityType = tostring(Entity.Type)\r\n| extend DeviceName = iff(EntityType == \"host\", tostring(Entity.HostName), \"\")\r\n| where DeviceName != \"\" and DeviceName in~ (watchlist)\r\n| summarize DeviceName = make_set(DeviceName) by AlertId = SystemAlertId;\r\nmyAlert\r\n| join kind=inner ( SecurityIncident | where Status != \"Closed\"| mv-expand AlertIds | extend AlertId = tostring(AlertIds) | project CreatedTime ,AlertId ,IncidentNumber , Title ,TimeGenerated ,Status , ProviderName, IncidentUrl\r\n| summarize arg_max(CreatedTime, *) by AlertId) on AlertId\r\n| summarize arg_max(TimeGenerated, *) by IncidentNumber\r\n| extend Age_Hours = datetime_diff('hour', now(), CreatedTime)\r\n| where Age_Hours > 72\r\n| order by Age_Hours desc\r\n|project IncidentNumber, Title, Status , ProviderName, IncidentUrl , CreatedTime ,Age_Hours", + "size": 0, + "title": "SLA Breach - Incidents Unresolved Beyond 72 Hours", + "timeContextFromParameter": "Time", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "crossComponentResources": [ + "{Workspace}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "IncidentUrl", + "formatter": 7, + "formatOptions": { + "linkTarget": "Url" + } + } + ] + } + }, + "customWidth": "50", + "name": "query - 6", + "styleSettings": { + "showBorder": true + } + } + ] + }, + "conditionalVisibility": { + "parameterName": "seltab", + "comparison": "isEqualTo", + "value": "incidentmanagmentreporting" + }, + "name": "incidentmanagmentreportinggroup" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "The Microsoft Sentinel Solution for DORA (Digital Operational Resilience Act) Compliance delivers centralized, real-time visibility into your organization’s ICT risks, operational resilience posture, and regulatory readiness. Built for Compliance Officers, Risk Managers, Security Architects, SOC Analysts, and IT Administrators, this workbook enables you to monitor resilience controls, track incidents, map security signals to DORA Articles, and simplify evidence collection for audits.\r\n

\r\nThis workbook includes pre-built KQL queries aligned with key DORA themes—ICT Risk Management, Incident Reporting, Threat Intelligence, Business Continuity, and Audit & Oversight. These queries can be exported or extended to support deeper investigations, operational reviews, or regulatory assessments.\r\n

\r\nThe Microsoft Sentinel team welcomes your feedback on this DORA Compliance Solution, including suggestions for additional mappings or automation to further strengthen your organization’s operational resilience obligations. Please share your feedback with us [Here](https://forms.office.com/Pages/ResponsePage.aspx?id=v4j5cvGGr0GRqy180BHbR5vpbw39GIlPr6oh7FnjxTFUOVhBOFowTFlaT1pOSTAxVDdRT1pIUDlINy4u) .", + "style": "info" + }, + "name": "text - 7" + }, + { + "type": 1, + "content": { + "json": "### Getting Started with the DORA Compliance Solution\r\n\r\nThe DORA compliance report in Microsoft Sentinel helps financial institutions and service providers assess and validate adherence to the Digital Operational Resilience Act (DORA). It provides visibility into ICT risk management, incident reporting, resilience measures, and continuity controls across critical infrastructure and digital services.\r\n\r\nUse the dashboard to:\r\n\r\n - Monitor disruptions and security incidents mapped to DORA Articles\r\n - Evaluate threat intelligence activity\r\n - Ensure continuity and recovery mechanisms are effective\r\n\r\n\r\nThe solution also supports streamlined audit preparation, evidence collection, and integration with Azure services to strengthen overall digital operational resilience.\r\n\r\nPre-requisites to get started:
\r\n\r\n1. **Connect Data Sources:** \r\n Connect applicable data sources to populate reports. Supported data sources include:
\r\nNote: Install Sentinel solutions using the links below for each data source. After installation, configure their data connectors (skip if already done).
\r\n - ***SecurityEvent / SecurityAlert / SecurityIncident*** (Windows server event logs — login activity, access attempts, anomaly and incident detection). Links : [Install Microsoft Defender for Cloud](https://portal.azure.com/#view/Microsoft_Azure_Marketplace/GalleryItemDetailsBladeNopdl/id/azuresentinel.azure-sentinel-solution-microsoftdefenderforcloud), [Install Microsoft Defender for Office 365](https://portal.azure.com/#view/Microsoft_Azure_Marketplace/GalleryItemDetailsBladeNopdl/id/azuresentinel.azure-sentinel-solution-microsoftdefenderforo365) ,[Install Microsoft Defender XDR](https://portal.azure.com/#view/Microsoft_Azure_Marketplace/GalleryItemDetailsBladeNopdl/id/azuresentinel.azure-sentinel-solution-microsoft365defender) and [Install Microsoft Defender for Endpoint](https://portal.azure.com/#view/Microsoft_Azure_Marketplace/GalleryItemDetailsBladeNopdl/id/azuresentinel.azure-sentinel-solution-microsoftdefenderendpoint)\r\n - ***Event/SecurityEvent*** (for fetching latest security events). Link : [Install Windows Security Events via AMA](https://portal.azure.com/#view/Microsoft_Azure_Marketplace/GalleryItemDetailsBladeNopdl/id/azuresentinel.azure-sentinel-solution-securityevents)\r\n - ***ThreatIntelIndicators*** (for fetching latest threatID's). Link : [Install Threat Intel](https://portal.azure.com/#view/Microsoft_Azure_Marketplace/GalleryItemDetailsBladeNopdl/id/azuresentinel.azure-sentinel-solution-threatintelligence-updated)
\r\n\r\n2. **Define DORA Assets:**
\r\n Define DORA-relevant assets within your compliance scope using a Watchlist:

\r\n\r\n **DORA Assets Watchlist** \r\n - Save a CSV file with the following columns: `DeviceName, DeviceType`\r\n - Repeat same steps as above but use:\r\n - **Name:** `dora_assets`\r\n - **Alias:** `dora_assets`\r\n - **SearchKey:** `DeviceName` \r\n
\r\n\r\n### Included in the Microsoft Sentinel DORA Compliance Solution\r\n\r\nThis solution enables Microsoft Sentinel users to leverage SIEM capabilities to meet DORA requirements, including resilience monitoring, incident reporting, threat intelligence integration, and business continuity oversight.
\r\n\r\nThe included Watchlist allows users to define assets within their compliance scope.
\r\nThe Workbook contains four tabs with dashboards, visualizations, and reports for immediate insights into your DORA environment:
\r\n\r\n**Incident Management & Reporting** \r\nProvides visibility into incident severity, resolution time, SLA adherence, and analyst workload: \r\n\r\n1. **Mean Time to Resolve (MTTR):** Average resolution time for incidents.\r\n2. **Incidents by Severity:** Breakdown by severity (High, Medium, Low). \r\n3. **Open Incidents by Owner:** Active incidents grouped by owner.\r\n4. **Top Incident Categories:** Common incident types (malware, phishing, identity compromise, misconfigurations). \r\n5. **Time Taken to Resolve the Incidents:** Highlights slow investigations and outliers.\r\n6. **SLA Breach – Incidents Unresolved Beyond 72 Hours:** Lists unresolved incidents past SLA threshold. \r\n
\r\n\r\n**Threat Intelligence & Detection** \r\nThis tab provides a unified view of threat indicators, adversary behaviors, and detection activity across your environment. It helps analysts correlate real-time IOCs with security alerts, understand attacker tactics using MITRE ATT&CK, identify prevented attacks, and prioritize threats based on confidence and activity levels. This tab strengthens proactive defense by combining threat intelligence with Sentinel’s detection capabilities to surface the most relevant and high-risk threats for investigation.\r\n\r\n1. **Active Threat Indicators (IOC Hits):** Displays all active indicators of compromise (IOCs) that matched with your environment, showing which endpoints or resources communicated with malicious IPs/domains.\r\n2. **Alerts by MITRE ATT&CK Techniques:** Shows all security alerts categorized by MITRE ATT&CK techniques (e.g., Initial Access, Credential Access, Lateral Movement).\r\n3. **Failed Attack Attempts (Prevented by Control):** Highlights attacks that were attempted but successfully blocked by security controls (e.g., firewall blocks, Defender real-time protection, policy enforcement).\r\n4. **Malicious File or URL Detection:** Displays detections related to malicious files, URLs, email links, or attachments identified by your security solutions.\r\n4. **Focus on Indicators with High Confidence and Activity:** Surfaces IOCs with both high confidence (validated, reliable intelligence) and high activity (multiple hits or detections).
\r\n\r\n**Business Continuity & Recovery** \r\nProvides visibility into the operational health of critical infrastructure and the effectiveness of your continuity mechanisms. It helps teams identify inactive or unreachable systems, monitor failover patterns, and track recovery behavior across servers, clusters, and backup sites:\r\n\r\n1. **Inactive Servers / Devices:** This panel displays servers or devices that have stopped sending heartbeats or logs within the expected time window..\r\n2. **Trend of Failover, Cluster Switch, or Backup Site Activation:** It provides insights into whether failover events are expected (planned maintenance) or abnormal (service disruption).
\r\n\r\n**Compliance Mapping & Evidence** \r\nProvides a centralized view of how security alerts, threat intelligence signals, and operational activities align with key DORA regulatory requirements. It helps compliance teams visualize control coverage, track monthly compliance trends, and review evidence that supports regulatory assessments and audits. This tab strengthens operational resilience by ensuring that alerts and threats are mapped to the appropriate DORA Articles, enabling accurate reporting, continuous monitoring, and easier audit preparation.:\r\n\r\n1. **Alerts per Compliance Control Mapping:** Displays security alerts categorized based on their mapped DORA controls or Articles.\r\n2. **Monthly Compliance Summary:** Presents month-over-month tracking of compliance-related activity, including alerts, mapped controls, and evidence logs.\r\n3. **DORA Mapping by Threat Type (from Threat Intel Reports)** Correlates threat intelligence categories (e.g., malware, phishing, credential theft, APT activity) with relevant DORA Articles and requirements.\r\n4. **Mapping Alerts to Regulatory Controls** Shows detailed alignment between each alert and its corresponding regulatory control or Article, helping auditors validate evidence.
", + "style": "upsell" + }, + "name": "text - 8" + } + ] + }, + "conditionalVisibility": { + "parameterName": "seltab", + "comparison": "isEqualTo", + "value": "gettingstarted" + }, + "name": "gettingstarted" + } + ], + "fromTemplateId": "sentinel-DORAComplianceWorkbook", + "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json" +} diff --git a/Solutions/DORA Compliance/Workbooks/Images/Preview/DORAComplianceBlack01.png b/Solutions/DORA Compliance/Workbooks/Images/Preview/DORAComplianceBlack01.png new file mode 100644 index 00000000000..85a9170c1e1 Binary files /dev/null and b/Solutions/DORA Compliance/Workbooks/Images/Preview/DORAComplianceBlack01.png differ diff --git a/Solutions/DORA Compliance/Workbooks/Images/Preview/DORAComplianceBlack02.png b/Solutions/DORA Compliance/Workbooks/Images/Preview/DORAComplianceBlack02.png new file mode 100644 index 00000000000..36f8cf870f5 Binary files /dev/null and b/Solutions/DORA Compliance/Workbooks/Images/Preview/DORAComplianceBlack02.png differ diff --git a/Solutions/DORA Compliance/Workbooks/Images/Preview/DORAComplianceWhite01.png b/Solutions/DORA Compliance/Workbooks/Images/Preview/DORAComplianceWhite01.png new file mode 100644 index 00000000000..af28bc7448d Binary files /dev/null and b/Solutions/DORA Compliance/Workbooks/Images/Preview/DORAComplianceWhite01.png differ diff --git a/Solutions/DORA Compliance/Workbooks/Images/Preview/DORAComplianceWhite02.png b/Solutions/DORA Compliance/Workbooks/Images/Preview/DORAComplianceWhite02.png new file mode 100644 index 00000000000..dddcc7b7cfc Binary files /dev/null and b/Solutions/DORA Compliance/Workbooks/Images/Preview/DORAComplianceWhite02.png differ diff --git a/Workbooks/Images/Preview/DORAComplianceBlack01.png b/Workbooks/Images/Preview/DORAComplianceBlack01.png new file mode 100644 index 00000000000..85a9170c1e1 Binary files /dev/null and b/Workbooks/Images/Preview/DORAComplianceBlack01.png differ diff --git a/Workbooks/Images/Preview/DORAComplianceBlack02.png b/Workbooks/Images/Preview/DORAComplianceBlack02.png new file mode 100644 index 00000000000..36f8cf870f5 Binary files /dev/null and b/Workbooks/Images/Preview/DORAComplianceBlack02.png differ diff --git a/Workbooks/Images/Preview/DORAComplianceWhite01.png b/Workbooks/Images/Preview/DORAComplianceWhite01.png new file mode 100644 index 00000000000..af28bc7448d Binary files /dev/null and b/Workbooks/Images/Preview/DORAComplianceWhite01.png differ diff --git a/Workbooks/Images/Preview/DORAComplianceWhite02.png b/Workbooks/Images/Preview/DORAComplianceWhite02.png new file mode 100644 index 00000000000..dddcc7b7cfc Binary files /dev/null and b/Workbooks/Images/Preview/DORAComplianceWhite02.png differ diff --git a/Workbooks/WorkbooksMetadata.json b/Workbooks/WorkbooksMetadata.json index 2dcc3cbe9b6..5a186b8616d 100644 --- a/Workbooks/WorkbooksMetadata.json +++ b/Workbooks/WorkbooksMetadata.json @@ -9868,5 +9868,29 @@ "templateRelativePath": "LookoutSecurityInvestigationDashboard.json", "subtitle": "", "provider": "Lookout" + }, + { + "workbookKey": "DORAComplianceWorkbook", + "logoFileName": "Azure_Sentinel.svg", + "description": "Choose your subscription and workspace in which DORA assets are deployed", + "dataTypesDependencies": [ + "SecurityEvent", + "SecurityAlert", + "SecurityIncident", + "Event", + "ThreatIntelIndicators" + ], + "dataConnectorsDependencies": [], + "previewImagesFileNames": [ + "DORAComplianceBlack01.png", + "DORAComplianceBlack02.png", + "DORAComplianceWhite01.png", + "DORAComplianceWhite02.png" + ], + "version": "1.0.0", + "title": "DORA Compliance Workbook (Preview)", + "templateRelativePath": "DORACompliance.json", + "subtitle": "", + "provider": "Microsoft" } ] \ No newline at end of file