|
3 | 3 | "contentVersion": "1.0.0.0", |
4 | 4 | "metadata": { |
5 | 5 | "title": "PRODAFTUstaATP-Backfill", |
6 | | - "description": "On-demand backfill playbook for PRODAFT USTA - Account Takeover Prevention. Pages through the USTA compromised-credentials API and pushes historical tickets to the connector's Data Collection Endpoint (Logs Ingestion API), so the same DCR transform (password redaction, field mapping) is applied as for live polling. The codeless connector only polls forward from connection time; run this playbook once after connecting to load history.", |
| 6 | + "description": "On-demand backfill playbook for PRODAFT USTA - Account Takeover Prevention. Pages through the USTA compromised-credentials API and pushes historical tickets into the workspace via the Logs Ingestion API, applying the same transform (password redaction, field mapping) as live polling. The deployment is self-contained: it creates its own Data Collection Endpoint and Rule (writing into the existing PRODAFTUstaCompromisedCredentials_CL table) and assigns its identity the required role. The codeless connector only polls forward from connection time; run this playbook once after installing the solution to load history.", |
7 | 7 | "prerequisites": [ |
8 | | - "The PRODAFT USTA - Account Takeover Prevention solution installed and its data connector connected (this creates the DCE, DCR, and table).", |
9 | | - "The Data Collection Endpoint logs-ingestion URI and the DCR immutable ID (see readme.md for how to find them).", |
10 | | - "A PRODAFT USTA long-lived API key." |
| 8 | + "The PRODAFT USTA - Account Takeover Prevention solution installed (this creates the PRODAFTUstaCompromisedCredentials_CL table the backfill writes into); connecting the data connector starts forward polling.", |
| 9 | + "A PRODAFT USTA long-lived API key.", |
| 10 | + "Permission to create role assignments in the workspace resource group (Owner or User Access Administrator), since the template grants its identity 'Monitoring Metrics Publisher' automatically." |
11 | 11 | ], |
12 | 12 | "postDeployment": [ |
13 | | - "Grant the playbook's system-assigned managed identity the 'Monitoring Metrics Publisher' role on the connector's Data Collection Rule, then run the trigger once (see readme.md)." |
| 13 | + "Run the playbook's trigger once to start the backfill (see readme.md)." |
14 | 14 | ], |
15 | 15 | "lastUpdateTime": "2026-07-06T00:00:00.000Z", |
16 | 16 | "entities": [], |
|
22 | 22 | "name": "PRODAFT" |
23 | 23 | }, |
24 | 24 | "releaseNotes": [ |
| 25 | + { |
| 26 | + "version": "1.1", |
| 27 | + "title": "PRODAFTUstaATP-Backfill", |
| 28 | + "notes": [ "Playbook now self-provisions its Data Collection Endpoint and Rule and assigns its identity the Monitoring Metrics Publisher role; removes manual ingestion-endpoint and DCR immutable-ID setup." ] |
| 29 | + }, |
25 | 30 | { |
26 | 31 | "version": "1.0", |
27 | 32 | "title": "PRODAFTUstaATP-Backfill", |
|
35 | 40 | "type": "string", |
36 | 41 | "metadata": { "description": "Name of the Logic App playbook." } |
37 | 42 | }, |
38 | | - "DataCollectionEndpointUri": { |
| 43 | + "WorkspaceName": { |
39 | 44 | "type": "string", |
40 | | - "metadata": { "description": "Logs-ingestion URI of the connector's Data Collection Endpoint, e.g. https://<dce-name>-a1b2.westeurope-1.ingest.monitor.azure.com" } |
| 45 | + "metadata": { "description": "Name of the existing Microsoft Sentinel / Log Analytics workspace that the ATP connector ingests into." } |
41 | 46 | }, |
42 | | - "DataCollectionRuleImmutableId": { |
| 47 | + "WorkspaceLocation": { |
43 | 48 | "type": "string", |
44 | | - "metadata": { "description": "Immutable ID of the connector's Data Collection Rule, e.g. dcr-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" } |
| 49 | + "metadata": { "description": "Region of the workspace. The backfill Data Collection Endpoint and Rule are created in this region." } |
| 50 | + }, |
| 51 | + "WorkspaceResourceGroup": { |
| 52 | + "type": "string", |
| 53 | + "defaultValue": "[resourceGroup().name]", |
| 54 | + "metadata": { "description": "Resource group of the workspace. Leave as default if it is in the same resource group as this deployment." } |
45 | 55 | }, |
46 | 56 | "UstaBaseUrl": { |
47 | 57 | "type": "string", |
|
58 | 68 | "metadata": { "description": "Number of days of history to backfill." } |
59 | 69 | } |
60 | 70 | }, |
| 71 | + "variables": { |
| 72 | + "WorkspaceResourceId": "[resourceId(parameters('WorkspaceResourceGroup'), 'Microsoft.OperationalInsights/workspaces', parameters('WorkspaceName'))]", |
| 73 | + "DceName": "[concat(parameters('PlaybookName'), '-DCE')]", |
| 74 | + "DcrName": "[concat(parameters('PlaybookName'), '-DCR')]", |
| 75 | + "DceResourceId": "[resourceId('Microsoft.Insights/dataCollectionEndpoints', variables('DceName'))]", |
| 76 | + "DcrResourceId": "[resourceId('Microsoft.Insights/dataCollectionRules', variables('DcrName'))]", |
| 77 | + "MonitoringMetricsPublisherRoleId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')]" |
| 78 | + }, |
61 | 79 | "resources": [ |
| 80 | + { |
| 81 | + "type": "Microsoft.Insights/dataCollectionEndpoints", |
| 82 | + "apiVersion": "2024-03-11", |
| 83 | + "name": "[variables('DceName')]", |
| 84 | + "location": "[parameters('WorkspaceLocation')]", |
| 85 | + "properties": { |
| 86 | + "description": "Data Collection Endpoint for the PRODAFT USTA ATP backfill playbook (Logs Ingestion API).", |
| 87 | + "networkAcls": { |
| 88 | + "publicNetworkAccess": "Enabled" |
| 89 | + } |
| 90 | + } |
| 91 | + }, |
| 92 | + { |
| 93 | + "type": "Microsoft.Insights/dataCollectionRules", |
| 94 | + "apiVersion": "2024-03-11", |
| 95 | + "name": "[variables('DcrName')]", |
| 96 | + "location": "[parameters('WorkspaceLocation')]", |
| 97 | + "dependsOn": [ |
| 98 | + "[variables('DceResourceId')]" |
| 99 | + ], |
| 100 | + "properties": { |
| 101 | + "description": "DCR for the PRODAFT USTA ATP backfill playbook. Applies the same transform as the connector DCR and writes to the existing PRODAFTUstaCompromisedCredentials_CL table.", |
| 102 | + "dataCollectionEndpointId": "[variables('DceResourceId')]", |
| 103 | + "streamDeclarations": { |
| 104 | + "Custom-PRODAFTUstaCompromisedCredentials_CL": { |
| 105 | + "columns": [ |
| 106 | + { "name": "id", "type": "long" }, |
| 107 | + { "name": "status", "type": "string" }, |
| 108 | + { "name": "status_timestamp", "type": "datetime" }, |
| 109 | + { "name": "created", "type": "datetime" }, |
| 110 | + { "name": "content_type", "type": "string" }, |
| 111 | + { "name": "company", "type": "dynamic" }, |
| 112 | + { "name": "content", "type": "dynamic" } |
| 113 | + ] |
| 114 | + } |
| 115 | + }, |
| 116 | + "destinations": { |
| 117 | + "logAnalytics": [ |
| 118 | + { |
| 119 | + "workspaceResourceId": "[variables('WorkspaceResourceId')]", |
| 120 | + "name": "clv2ws1" |
| 121 | + } |
| 122 | + ] |
| 123 | + }, |
| 124 | + "dataFlows": [ |
| 125 | + { |
| 126 | + "streams": [ "Custom-PRODAFTUstaCompromisedCredentials_CL" ], |
| 127 | + "destinations": [ "clv2ws1" ], |
| 128 | + "transformKql": "source | extend c = content, co = company | project TimeGenerated = now(), TicketId = tolong(id), Status = tostring(status), StatusTimestamp = todatetime(status_timestamp), Created = todatetime(created), ContentType = tostring(content_type), CompanyId = toint(co.id), CompanyName = tostring(co.name), Username = tostring(c.username), Url = tostring(c.url), Source = tostring(c.source), IsCorporate = tobool(c.is_corporate), PasswordScore = tostring(c.password_complexity.score), PasswordLength = toint(c.password_complexity.length), VictimUid = tostring(c.victim_detail.victim_uid), VictimUsername = tostring(c.victim_detail.username), VictimCountry = tostring(c.victim_detail.country), VictimIp = tostring(c.victim_detail.ip), VictimComputerName = tostring(c.victim_detail.computer_name), VictimOs = tostring(c.victim_detail.victim_os), VictimMalware = tostring(c.victim_detail.malware), InfectionDate = todatetime(c.victim_detail.infection_date)", |
| 129 | + "outputStream": "Custom-PRODAFTUstaCompromisedCredentials_CL" |
| 130 | + } |
| 131 | + ] |
| 132 | + } |
| 133 | + }, |
62 | 134 | { |
63 | 135 | "type": "Microsoft.Logic/workflows", |
64 | 136 | "apiVersion": "2019-05-01", |
65 | 137 | "name": "[parameters('PlaybookName')]", |
66 | 138 | "location": "[resourceGroup().location]", |
67 | 139 | "identity": { "type": "SystemAssigned" }, |
| 140 | + "dependsOn": [ |
| 141 | + "[variables('DceResourceId')]", |
| 142 | + "[variables('DcrResourceId')]" |
| 143 | + ], |
68 | 144 | "tags": { |
69 | 145 | "hidden-SentinelTemplateName": "PRODAFTUstaATP-Backfill", |
70 | | - "hidden-SentinelTemplateVersion": "1.0" |
| 146 | + "hidden-SentinelTemplateVersion": "1.1" |
71 | 147 | }, |
72 | 148 | "properties": { |
73 | 149 | "state": "Enabled", |
74 | 150 | "definition": { |
75 | 151 | "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", |
76 | 152 | "contentVersion": "1.0.0.0", |
77 | 153 | "parameters": { |
78 | | - "DataCollectionEndpointUri": { "type": "String", "defaultValue": "[parameters('DataCollectionEndpointUri')]" }, |
79 | | - "DataCollectionRuleImmutableId": { "type": "String", "defaultValue": "[parameters('DataCollectionRuleImmutableId')]" }, |
| 154 | + "DataCollectionEndpointUri": { "type": "String", "defaultValue": "[reference(variables('DceResourceId'), '2024-03-11').logsIngestion.endpoint]" }, |
| 155 | + "DataCollectionRuleImmutableId": { "type": "String", "defaultValue": "[reference(variables('DcrResourceId'), '2024-03-11').immutableId]" }, |
80 | 156 | "UstaBaseUrl": { "type": "String", "defaultValue": "[parameters('UstaBaseUrl')]" }, |
81 | 157 | "UstaApiKey": { "type": "SecureString", "defaultValue": "[parameters('UstaApiKey')]" }, |
82 | 158 | "BackfillDays": { "type": "Int", "defaultValue": "[parameters('BackfillDays')]" } |
|
164 | 240 | }, |
165 | 241 | "parameters": {} |
166 | 242 | } |
| 243 | + }, |
| 244 | + { |
| 245 | + "type": "Microsoft.Authorization/roleAssignments", |
| 246 | + "apiVersion": "2022-04-01", |
| 247 | + "name": "[guid(variables('DcrResourceId'), parameters('PlaybookName'), variables('MonitoringMetricsPublisherRoleId'))]", |
| 248 | + "scope": "[variables('DcrResourceId')]", |
| 249 | + "dependsOn": [ |
| 250 | + "[resourceId('Microsoft.Logic/workflows', parameters('PlaybookName'))]", |
| 251 | + "[variables('DcrResourceId')]" |
| 252 | + ], |
| 253 | + "properties": { |
| 254 | + "roleDefinitionId": "[variables('MonitoringMetricsPublisherRoleId')]", |
| 255 | + "principalId": "[reference(resourceId('Microsoft.Logic/workflows', parameters('PlaybookName')), '2019-05-01', 'Full').identity.principalId]", |
| 256 | + "principalType": "ServicePrincipal" |
| 257 | + } |
167 | 258 | } |
168 | 259 | ], |
169 | 260 | "outputs": { |
170 | | - "playbookPrincipalId": { |
| 261 | + "playbookName": { |
| 262 | + "type": "string", |
| 263 | + "value": "[parameters('PlaybookName')]" |
| 264 | + }, |
| 265 | + "dataCollectionEndpoint": { |
| 266 | + "type": "string", |
| 267 | + "value": "[reference(variables('DceResourceId'), '2024-03-11').logsIngestion.endpoint]" |
| 268 | + }, |
| 269 | + "dataCollectionRuleName": { |
| 270 | + "type": "string", |
| 271 | + "value": "[variables('DcrName')]" |
| 272 | + }, |
| 273 | + "dataCollectionRuleImmutableId": { |
171 | 274 | "type": "string", |
172 | | - "value": "[reference(resourceId('Microsoft.Logic/workflows', parameters('PlaybookName')), '2019-05-01', 'full').identity.principalId]" |
| 275 | + "value": "[reference(variables('DcrResourceId'), '2024-03-11').immutableId]" |
173 | 276 | } |
174 | 277 | } |
175 | 278 | } |
0 commit comments