diff --git a/Solutions/Recorded Future Identity/Analytic Rules/IncidentCreation/RecordedFutureIdentityExposure.yaml b/Solutions/Recorded Future Identity/Analytic Rules/IncidentCreation/RecordedFutureIdentityExposure.yaml
index 89153b3e083..1351a9da71a 100644
--- a/Solutions/Recorded Future Identity/Analytic Rules/IncidentCreation/RecordedFutureIdentityExposure.yaml
+++ b/Solutions/Recorded Future Identity/Analytic Rules/IncidentCreation/RecordedFutureIdentityExposure.yaml
@@ -12,31 +12,31 @@ tactics:
- CredentialAccess
relevantTechniques: []
query: |
- RecordedFutureIdentity_PlaybookAlertResults_CL
+ RFI_PlaybookAlertResults_V2_CL
| where TimeGenerated >= now(-15m)
eventGroupingSettings:
aggregationKind: AlertPerResult
alertDetailsOverride:
- alertDisplayNameFormat: 'Identity Exposure: {{panel_status_entity_name_s}} with priority: {{panel_status_priority_s}}'
+ alertDisplayNameFormat: 'Identity Exposure: {{panel_status_entity_name}} with priority: {{panel_status_priority}}'
alertDescriptionFormat: |
_Recorded Future Identity Alert_
- **Rule Name:** {{panel_status_alert_rule_name_s}}
+ **Rule Name:** {{panel_status_alert_rule_name}}
- **Alert ID:** {{playbook_alert_id_s}}
+ **Alert ID:** {{playbook_alert_id}}
- **Evidence Summary:** {{alert_description_s}}
+ **Evidence Summary:** {{alert_description}}
Investigate this identity by searching in log analytics workspace for the Alert ID.
alertDynamicProperties: []
customDetails:
RFLabel: Type
- AlertId: playbook_alert_id_s
+ AlertId: playbook_alert_id
entityMappings:
- entityType: Account
fieldMappings:
- identifier: Name
- columnName: panel_status_entity_name_s
+ columnName: panel_status_entity_name
incidentConfiguration:
createIncident: true
groupingConfiguration:
@@ -48,6 +48,5 @@ incidentConfiguration:
- Account
groupByAlertDetails: []
groupByCustomDetails: []
-version: 1.0.0
+version: 1.1.0
kind: NRT
-
diff --git a/Solutions/Recorded Future Identity/Analytic Rules/IncidentCreation/azuredeploy.json b/Solutions/Recorded Future Identity/Analytic Rules/IncidentCreation/azuredeploy.json
new file mode 100644
index 00000000000..b7080881084
--- /dev/null
+++ b/Solutions/Recorded Future Identity/Analytic Rules/IncidentCreation/azuredeploy.json
@@ -0,0 +1,100 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "1.1.0.0",
+ "metadata": {
+ "title": "Recorded Future Identity - Credential Exposure Analytic Rule",
+ "description": "Deploys the NRT Analytic Rule that creates Microsoft Sentinel incidents when Recorded Future Identity detects compromised credentials. Requires the RFI_PlaybookAlertResults_V2_CL table to exist (deploy azuredeploy-alert-importer.json first).",
+ "lastUpdateTime": "2026-06-02T00:00:00.000Z",
+ "support": {
+ "tier": "Partner"
+ },
+ "author": {
+ "name": "Recorded Future"
+ },
+ "releaseNotes": [
+ {
+ "version": "1.0",
+ "title": "Initial version",
+ "notes": [
+ "NRT analytic rule querying RFI_PlaybookAlertResults_V2_CL.",
+ "Groups incidents by Account entity.",
+ "Alert title includes entity name and priority."
+ ]
+ },
+ {
+ "version": "1.1",
+ "title": "Updated table and field names",
+ "notes": [
+ "Updated query to use RFI_PlaybookAlertResults_V2_CL table.",
+ "Updated field references to remove _s suffix (new Log Ingestion API schema)."
+ ]
+ }
+ ]
+ },
+ "parameters": {
+ "workspace": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. Name of the Log Analytics Workspace where the analytic rule will be deployed."
+ }
+ }
+ },
+ "resources": [
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules",
+ "name": "[concat(parameters('workspace'), '/Microsoft.SecurityInsights/b1c2d3e4-5678-90ab-cdef-444444444444')]",
+ "apiVersion": "2023-12-01-preview",
+ "kind": "NRT",
+ "properties": {
+ "displayName": "Recorded Future Identity - Credential Exposure Detected",
+ "description": "Creates incidents when Recorded Future Identity detects compromised credentials for users in your organization.",
+ "severity": "High",
+ "enabled": true,
+ "query": "RFI_PlaybookAlertResults_V2_CL\n| where TimeGenerated >= now(-15m)",
+ "suppressionDuration": "PT5H",
+ "suppressionEnabled": false,
+ "tactics": [
+ "CredentialAccess"
+ ],
+ "techniques": [],
+ "eventGroupingSettings": {
+ "aggregationKind": "AlertPerResult"
+ },
+ "alertDetailsOverride": {
+ "alertDisplayNameFormat": "Identity Exposure: {{panel_status_entity_name}} with priority: {{panel_status_priority}}",
+ "alertDescriptionFormat": "_Recorded Future Identity Alert_\n\n**Rule Name:** {{panel_status_alert_rule_name}}\n\n**Alert ID:** {{playbook_alert_id}}\n\n**Evidence Summary:** {{alert_description}}\n\nInvestigate this identity by searching in log analytics workspace for the Alert ID.",
+ "alertDynamicProperties": []
+ },
+ "customDetails": {
+ "RFLabel": "Type",
+ "AlertId": "playbook_alert_id"
+ },
+ "entityMappings": [
+ {
+ "entityType": "Account",
+ "fieldMappings": [
+ {
+ "identifier": "Name",
+ "columnName": "panel_status_entity_name"
+ }
+ ]
+ }
+ ],
+ "incidentConfiguration": {
+ "createIncident": true,
+ "groupingConfiguration": {
+ "enabled": true,
+ "reopenClosedIncident": false,
+ "lookbackDuration": "PT15M",
+ "matchingMethod": "AllEntities",
+ "groupByEntities": [
+ "Account"
+ ],
+ "groupByAlertDetails": [],
+ "groupByCustomDetails": []
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/Solutions/Recorded Future Identity/Data Connectors/azuredeploy-alert-importer.json b/Solutions/Recorded Future Identity/Data Connectors/azuredeploy-alert-importer.json
new file mode 100644
index 00000000000..0f6ceaa7d61
--- /dev/null
+++ b/Solutions/Recorded Future Identity/Data Connectors/azuredeploy-alert-importer.json
@@ -0,0 +1,305 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "metadata": {
+ "title": "Recorded Future Identity - Alert Importer Data Connectors",
+ "description": "Deploys shared infrastructure (DCE, DCR, LA table, connector definition) used by the RFI-Playbook-Alert-Importer-LAW playbook to write Playbook Alert data to Log Analytics via the Azure Monitor Logs Ingestion API.",
+ "lastUpdateTime": "2026-06-02T00:00:00.000Z",
+ "support": {
+ "tier": "Partner"
+ },
+ "author": {
+ "name": "Recorded Future"
+ },
+ "releaseNotes": [
+ {
+ "version": "1.0",
+ "title": "Initial version",
+ "notes": [
+ "DCE, DCR, and LA table for RFI-Playbook-Alert-Importer-LAW.",
+ "Single-stream DCR with 11 columns and todynamic transformKql."
+ ]
+ }
+ ]
+ },
+ "parameters": {
+ "log_analytics_workspace_name": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. Name of the Log Analytics Workspace where the table will be created. Must be in the same resource group as this deployment."
+ }
+ },
+ "log_analytics_workspace_location": {
+ "type": "string",
+ "defaultValue": "[resourceGroup().location]",
+ "metadata": {
+ "description": "Location of the Log Analytics Workspace. Defaults to the resource group location."
+ }
+ }
+ },
+ "variables": {
+ "DceName": "recorded-future-identity-dce",
+ "DcrName": "recorded-future-identity-dcr-playbook-alerts",
+ "TableName": "RFI_PlaybookAlertResults_V2_CL",
+ "StreamName": "Custom-RFI_PlaybookAlertResults_V2_CL",
+ "workspaceResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('log_analytics_workspace_name'))]",
+ "dceResourceId": "[resourceId('Microsoft.Insights/dataCollectionEndpoints', variables('DceName'))]",
+ "dcrResourceId": "[resourceId('Microsoft.Insights/dataCollectionRules', variables('DcrName'))]",
+ "tableResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces/tables', parameters('log_analytics_workspace_name'), variables('TableName'))]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Insights/dataCollectionEndpoints",
+ "apiVersion": "2024-03-11",
+ "name": "[variables('DceName')]",
+ "location": "[resourceGroup().location]",
+ "properties": {
+ "networkAcls": {
+ "publicNetworkAccess": "Enabled"
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/tables",
+ "apiVersion": "2022-10-01",
+ "name": "[concat(parameters('log_analytics_workspace_name'), '/', variables('TableName'))]",
+ "properties": {
+ "schema": {
+ "name": "[variables('TableName')]",
+ "columns": [
+ {
+ "name": "TimeGenerated",
+ "type": "datetime"
+ },
+ {
+ "name": "playbook_alert_id",
+ "type": "string"
+ },
+ {
+ "name": "panel_status_status",
+ "type": "string"
+ },
+ {
+ "name": "panel_status_priority",
+ "type": "string"
+ },
+ {
+ "name": "panel_status_created",
+ "type": "datetime"
+ },
+ {
+ "name": "panel_status_entity_name",
+ "type": "string"
+ },
+ {
+ "name": "panel_status_alert_rule_name",
+ "type": "string"
+ },
+ {
+ "name": "panel_status_alert_rule_id",
+ "type": "string"
+ },
+ {
+ "name": "alert_description",
+ "type": "string"
+ },
+ {
+ "name": "panel_status",
+ "type": "dynamic"
+ },
+ {
+ "name": "panel_evidence_summary",
+ "type": "dynamic"
+ }
+ ]
+ },
+ "retentionInDays": 90,
+ "plan": "Analytics"
+ }
+ },
+ {
+ "type": "Microsoft.Insights/dataCollectionRules",
+ "apiVersion": "2024-03-11",
+ "name": "[variables('DcrName')]",
+ "location": "[resourceGroup().location]",
+ "dependsOn": [
+ "[variables('dceResourceId')]",
+ "[variables('tableResourceId')]"
+ ],
+ "properties": {
+ "dataCollectionEndpointId": "[variables('dceResourceId')]",
+ "streamDeclarations": {
+ "Custom-RFI_PlaybookAlertResults_V2_CL": {
+ "columns": [
+ {
+ "name": "TimeGenerated",
+ "type": "datetime"
+ },
+ {
+ "name": "playbook_alert_id",
+ "type": "string"
+ },
+ {
+ "name": "panel_status_status",
+ "type": "string"
+ },
+ {
+ "name": "panel_status_priority",
+ "type": "string"
+ },
+ {
+ "name": "panel_status_created",
+ "type": "datetime"
+ },
+ {
+ "name": "panel_status_entity_name",
+ "type": "string"
+ },
+ {
+ "name": "panel_status_alert_rule_name",
+ "type": "string"
+ },
+ {
+ "name": "panel_status_alert_rule_id",
+ "type": "string"
+ },
+ {
+ "name": "alert_description",
+ "type": "string"
+ },
+ {
+ "name": "panel_status",
+ "type": "dynamic"
+ },
+ {
+ "name": "panel_evidence_summary",
+ "type": "dynamic"
+ }
+ ]
+ }
+ },
+ "destinations": {
+ "logAnalytics": [
+ {
+ "workspaceResourceId": "[variables('workspaceResourceId')]",
+ "name": "workspace"
+ }
+ ]
+ },
+ "dataFlows": [
+ {
+ "streams": [
+ "Custom-RFI_PlaybookAlertResults_V2_CL"
+ ],
+ "destinations": [
+ "workspace"
+ ],
+ "transformKql": "source | project TimeGenerated = now(), playbook_alert_id = tostring(playbook_alert_id), panel_status_status = tostring(todynamic(panel_status).status), panel_status_priority = tostring(todynamic(panel_status).priority), panel_status_created = todatetime(todynamic(panel_status).created), panel_status_entity_name = tostring(todynamic(panel_status).entity_name), panel_status_alert_rule_name = tostring(todynamic(panel_status).alert_rule.name), panel_status_alert_rule_id = tostring(todynamic(panel_status).alert_rule.id), alert_description = tostring(alert_description), panel_status = todynamic(panel_status), panel_evidence_summary = todynamic(panel_evidence_summary)",
+ "outputStream": "Custom-RFI_PlaybookAlertResults_V2_CL"
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectorDefinitions",
+ "apiVersion": "2022-09-01-preview",
+ "name": "[concat(parameters('log_analytics_workspace_name'), '/Microsoft.SecurityInsights/RecordedFutureIdentityAlertImporter')]",
+ "location": "[parameters('log_analytics_workspace_location')]",
+ "kind": "Customizable",
+ "properties": {
+ "connectorUiConfig": {
+ "id": "RecordedFutureIdentityAlertImporter",
+ "title": "Recorded Future Identity - Playbook Alert Importer",
+ "publisher": "Recorded Future",
+ "descriptionMarkdown": "Imports Recorded Future Identity Playbook Alerts into Microsoft Sentinel via the Azure Monitor Logs Ingestion API. Enables incident creation via Analytic Rules on the `RFI_PlaybookAlertResults_V2_CL` table.",
+ "graphQueries": [
+ {
+ "metricName": "Playbook Alert Results",
+ "legend": "RFI_PlaybookAlertResults_V2_CL",
+ "baseQuery": "RFI_PlaybookAlertResults_V2_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "All playbook alert results",
+ "query": "RFI_PlaybookAlertResults_V2_CL\n| sort by TimeGenerated desc"
+ },
+ {
+ "description": "High priority exposures",
+ "query": "RFI_PlaybookAlertResults_V2_CL\n| where panel_status_priority == 'High'\n| sort by TimeGenerated desc"
+ },
+ {
+ "description": "New alerts only",
+ "query": "RFI_PlaybookAlertResults_V2_CL\n| where panel_status_status == 'New'\n| sort by TimeGenerated desc"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "RFI_PlaybookAlertResults_V2_CL",
+ "lastDataReceivedQuery": "RFI_PlaybookAlertResults_V2_CL\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)"
+ }
+ ],
+ "connectivityCriteria": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "RFI_PlaybookAlertResults_V2_CL\n| summarize LastLog = max(TimeGenerated)\n| where LastLog >= ago(24h)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "Read and write permissions are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Azure Subscription",
+ "description": "Contributor permissions required to deploy ARM templates (Data Connectors infrastructure and playbook)."
+ },
+ {
+ "name": "Recorded Future API Token",
+ "description": "A Recorded Future Identity API token is required to authorize the RFI Custom Connector used by the playbook."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "Step 1 \u2014 Deploy Data Connectors infrastructure",
+ "description": "Deploys the shared Data Collection Endpoint (DCE), Data Collection Rule (DCR), Log Analytics table (`RFI_PlaybookAlertResults_V2_CL`), and this connector definition tile.\n\n[](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Frecordedfuture%2FAzure-Sentinel%2FRFPD-77178-log-ingestion-api%2FSolutions%2FRecorded%20Future%20Identity%2FData%20Connectors%2Fazuredeploy-alert-importer.json)"
+ },
+ {
+ "title": "Step 2 \u2014 Deploy the RFI-Playbook-Alert-Importer-LAW playbook",
+ "description": "Deploys the Logic App that imports Recorded Future Identity Playbook Alerts and writes them to the Log Analytics table via the Logs Ingestion API using Managed Identity.\n\n[](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Frecordedfuture%2FAzure-Sentinel%2FRFPD-77178-log-ingestion-api%2FSolutions%2FRecorded%20Future%20Identity%2FPlaybooks%2FRFI-Playbook-Alert-Importer-LAW%2Fazuredeploy.json)\n\nAfter deployment, open the Logic App and authorize the different connectors, then enable the Logic App."
+ }
+ ]
+ }
+ }
+ }
+ ],
+ "outputs": {
+ "dceEndpoint": {
+ "type": "string",
+ "value": "[reference(variables('dceResourceId'), '2024-03-11').logsIngestion.endpoint]"
+ },
+ "dcrImmutableId": {
+ "type": "string",
+ "value": "[reference(variables('dcrResourceId'), '2024-03-11').immutableId]"
+ },
+ "streamName": {
+ "type": "string",
+ "value": "[variables('StreamName')]"
+ }
+ }
+}
\ No newline at end of file
diff --git a/Solutions/Recorded Future Identity/Playbooks/RFI-Playbook-Alert-Importer-LAW/azuredeploy.json b/Solutions/Recorded Future Identity/Playbooks/RFI-Playbook-Alert-Importer-LAW/azuredeploy.json
index 6f469bfa646..1ffcbb343cf 100644
--- a/Solutions/Recorded Future Identity/Playbooks/RFI-Playbook-Alert-Importer-LAW/azuredeploy.json
+++ b/Solutions/Recorded Future Identity/Playbooks/RFI-Playbook-Alert-Importer-LAW/azuredeploy.json
@@ -1,10 +1,11 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.1.0.0",
+ "contentVersion": "1.2.0.0",
"metadata": {
"title": "RFI-Playbook-Alert-Importer-LAW",
"description": "This playbook fetches identity compromises from Recorded Future, places users in a security group and confirms them as 'risky users' in Entra ID.",
"prerequisites": [
+ "Deploy the Data Connectors infrastructure (DCE, DCR, Log Analytics table, and connector definition) by deploying the azuredeploy-alert-importer.json template from the Data Connectors folder before deploying this playbook.",
"First install the RFI-CustomConnector-0-2-0 custom connector",
"To use the Recorded Future Identity connector, you will need a valid API token from Recorded Future as described in the [documentation](https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Recorded%20Future%20Identity/Playbooks/readme.md#how-to-obtain-recorded-future-api-token)"
],
@@ -12,9 +13,11 @@
"After deployment, open the playbook to configure all connections and press save."
],
"prerequisitesDeployTemplateFile": "../Connectors/RFI-CustomConnector-0-2-0/azuredeploy.json",
- "lastUpdateTime": "2025-04-29T00:00:00.000Z",
+ "lastUpdateTime": "2026-06-02T00:00:00.000Z",
"entities": [],
- "tags": ["Identity protection"],
+ "tags": [
+ "Identity protection"
+ ],
"support": {
"tier": "Partner"
},
@@ -25,12 +28,25 @@
{
"version": "1.0",
"title": "Initial version",
- "notes": [ "Initial version" ]
+ "notes": [
+ "Initial version"
+ ]
},
{
"version": "1.1",
"title": "Improved stability",
- "notes": [ "Removed Get Risky User action due to instability" ]
+ "notes": [
+ "Removed Get Risky User action due to instability"
+ ]
+ },
+ {
+ "version": "1.2",
+ "title": "Migrated to Logs Ingestion API",
+ "notes": [
+ "Replaced azureloganalyticsdatacollector connector with Azure Monitor Logs Ingestion API.",
+ "MSI authentication via Monitoring Metrics Publisher role on shared DCR.",
+ "DCE, DCR, and LA table moved to shared Data Connectors template."
+ ]
}
]
},
@@ -54,11 +70,11 @@
"type": "String"
},
"confirm_user_as_risky": {
- "metadata":{
+ "metadata": {
"description": "Optional. If specified, will confirm user as risky. Requires Microsoft Entra ID P1 or P2 license"
},
- "defaultValue": false,
- "type": "Bool"
+ "defaultValue": false,
+ "type": "Bool"
},
"entra_id_domain": {
"defaultValue": "",
@@ -75,7 +91,7 @@
"type": "Bool"
},
"playbook_alert_log_analytics_custom_log_name": {
- "defaultValue": "RecordedFutureIdentity_PlaybookAlertResults_CL",
+ "defaultValue": "RFI_PlaybookAlertResults_V2_CL",
"metadata": {
"description": "Required. The name of the Log Analytics Workspace table where Playbook Alerts should be saved."
},
@@ -86,6 +102,13 @@
"description": "Required. The name of the Log Analytics Workspace to query for existing tables."
},
"type": "String"
+ },
+ "create_role_assignment": {
+ "type": "Bool",
+ "defaultValue": true,
+ "metadata": {
+ "description": "If true, automatically assigns the Monitoring Metrics Publisher role on the shared DCR to the Logic App managed identity. Requires Owner or Role Based Access Control Administrator on the resource group. Set to false to assign the role manually after deployment."
+ }
}
},
"resources": [
@@ -95,7 +118,6 @@
"[resourceId('Microsoft.Web/connections', variables('Rfi-Customconnector-0-2-0ConnectionName'))]",
"[resourceId('Microsoft.Web/connections', variables('AzureadConnectionName'))]",
"[resourceId('Microsoft.Web/connections', variables('AzureadipConnectionName'))]",
- "[resourceId('Microsoft.Web/connections', variables('AzureloganalyticsdatacollectorConnectionName'))]",
"[resourceId('Microsoft.Web/connections', variables('AzuremonitorlogsConnectionName'))]"
],
"identity": {
@@ -269,19 +291,18 @@
"Succeeded"
]
},
- "type": "ApiConnection",
+ "type": "Http",
"inputs": {
- "host": {
- "connection": {
- "name": "@parameters('$connections')['azureloganalyticsdatacollector']['connectionId']"
- }
- },
- "method": "post",
- "body": "@string(body('Playbook_Alerts_-_Detailed_Identity_Novel_Exposures_alert_data')?['result'])",
+ "method": "POST",
+ "uri": "@{parameters('DceEndpoint')}/dataCollectionRules/@{parameters('DcrImmutableId')}/streams/@{parameters('StreamName')}?api-version=2023-01-01",
"headers": {
- "Log-Type": "@parameters('playbook_alert_log_analytics_custom_log_name')"
+ "Content-Type": "application/json"
},
- "path": "/api/logs"
+ "body": "@createArray(body('Playbook_Alerts_-_Detailed_Identity_Novel_Exposures_alert_data')?['result'])",
+ "authentication": {
+ "type": "ManagedServiceIdentity",
+ "audience": "https://monitor.azure.com"
+ }
}
}
},
@@ -396,63 +417,7 @@
"method": "post",
"path": "/playbook-alerts/search"
},
- "runAfter": {
- "Create_table_if_missing": [
- "Succeeded",
- "Skipped"
- ],
- "Check_if_table_exists": [
- "Succeeded",
- "Failed"
- ]
- }
- },
- "Check_if_table_exists": {
- "type": "ApiConnection",
- "inputs": {
- "host": {
- "connection": {
- "name": "@parameters('$connections')['azuremonitorlogs']['connectionId']"
- }
- },
- "method": "post",
- "body": {
- "query": "RecordedFutureIdentity_PlaybookAlertResults_CL | take 1",
- "timerangetype": "2",
- "timerange": {
- "relativeTimeRange": "Last 7 days"
- }
- },
- "path": "/queryDataV2",
- "queries": {
- "subscriptions": "[subscription().subscriptionId]",
- "resourcegroups": "[resourceGroup().name]",
- "resourcetype": "Log Analytics Workspace",
- "resourcename": "[parameters('log_analytics_workspace_name')]"
- }
- },
"runAfter": {}
- },
- "Create_table_if_missing": {
- "type": "ApiConnection",
- "inputs": {
- "host": {
- "connection": {
- "name": "@parameters('$connections')['azureloganalyticsdatacollector']['connectionId']"
- }
- },
- "method": "post",
- "body": "[\n {\n \"panel_evidence_summary_assessments\": \"TEST_ASSESSMENTS\",\n \"panel_evidence_summary_authorization_url\": \"https://test.example.com/test\",\n \"panel_evidence_summary_compromised_host_antivirus\": \"TEST_ANTIVIRUS\",\n \"panel_evidence_summary_compromised_host_computer_name\": \"TEST_COMPUTER\",\n \"panel_evidence_summary_compromised_host_exfiltration_date\": \"2020-01-01T00:00:00.000Z\",\n \"panel_evidence_summary_compromised_host_malware_file\": \"TEST_MALWARE_FILE\",\n \"panel_evidence_summary_compromised_host_os\": \"TEST_OS\",\n \"panel_evidence_summary_compromised_host_os_username\": \"TEST_USERNAME\",\n \"panel_evidence_summary_compromised_host_timezone\": \"TEST_TIMEZONE\",\n \"panel_evidence_summary_compromised_host_uac\": \"TEST_UAC\",\n \"panel_evidence_summary_dump_description\": \"TEST_DUMP_DESCRIPTION\",\n \"panel_evidence_summary_dump_name\": \"TEST_DUMP_NAME\",\n \"panel_evidence_summary_exposed_secret_details_clear_text_hint\": \"TEST_HINT\",\n \"panel_evidence_summary_exposed_secret_details_properties\": \"TEST_PROPERTIES\",\n \"panel_evidence_summary_exposed_secret_effectively_clear\": false,\n \"panel_evidence_summary_exposed_secret_hashes\": \"TEST_HASHES\",\n \"panel_evidence_summary_exposed_secret_type\": \"TEST_SECRET_TYPE\",\n \"panel_evidence_summary_infrastructure_ip\": \"0.0.0.0\",\n \"panel_evidence_summary_malware_family_id\": \"TEST_MALWARE_ID\",\n \"panel_evidence_summary_malware_family_name\": \"TEST_MALWARE_NAME\",\n \"panel_evidence_summary_subject\": \"TEST_SUBJECT\",\n \"panel_evidence_summary_technologies\": \"TEST_TECHNOLOGIES\",\n \"panel_status_actions_taken\": \"TEST_ACTIONS\",\n \"panel_status_alert_rule_id\": \"TEST_ALERT_RULE_ID\",\n \"panel_status_alert_rule_label\": \"TEST_ALERT_RULE_LABEL\",\n \"panel_status_alert_rule_name\": \"TEST_ALERT_RULE_NAME\",\n \"panel_status_assignee_id\": \"TEST_ASSIGNEE_ID\",\n \"panel_status_assignee_name\": \"TEST_ASSIGNEE_NAME\",\n \"panel_status_case_rule_id\": \"TEST_CASE_RULE_ID\",\n \"panel_status_case_rule_label\": \"TEST_CASE_RULE_LABEL\",\n \"panel_status_created\": \"2020-01-01T00:00:00.000Z\",\n \"panel_status_entity_id\": \"TEST_ENTITY_ID\",\n \"panel_status_entity_name\": \"TEST_ENTITY_NAME\",\n \"panel_status_organisation_id\": \"TEST_ORG_ID\",\n \"panel_status_organisation_name\": \"TEST_ORG_NAME\",\n \"panel_status_owner_id\": \"TEST_OWNER_ID\",\n \"panel_status_owner_name\": \"TEST_OWNER_NAME\",\n \"panel_status_owner_organisation_details_enterprise_id\": \"TEST_ENTERPRISE_ID\",\n \"panel_status_owner_organisation_details_enterprise_name\": \"TEST_ENTERPRISE_NAME\",\n \"panel_status_owner_organisation_details_organisations\": \"TEST_ORGANISATIONS\",\n \"panel_status_priority\": \"TEST_PRIORITY\",\n \"panel_status_reopen\": \"TEST_REOPEN\",\n \"panel_status_status\": \"TEST_STATUS\",\n \"panel_status_targets\": \"TEST_TARGETS\",\n \"panel_status_updated\": \"2020-01-01T00:00:00.000Z\",\n \"playbook_alert_id\": \"TEST_PLAYBOOK_ALERT_ID\",\n \"alert_description\": \"TEST_ALERT_DESCRIPTION\"\n }\n]\n",
- "headers": {
- "Log-Type": "@parameters('playbook_alert_log_analytics_custom_log_name')"
- },
- "path": "/api/logs"
- },
- "runAfter": {
- "Check_if_table_exists": [
- "Failed"
- ]
- }
}
},
"contentVersion": "1.0.0.0",
@@ -474,13 +439,18 @@
"defaultValue": "[parameters('confirm_user_as_risky')]",
"type": "Bool"
},
- "playbook_alert_log_analytics_custom_log_name": {
- "defaultValue": "[parameters('playbook_alert_log_analytics_custom_log_name')]",
- "type": "String"
- },
"save_to_log_analytics_workspace": {
"defaultValue": "[parameters('save_to_log_analytics_workspace')]",
"type": "Bool"
+ },
+ "DceEndpoint": {
+ "type": "String"
+ },
+ "DcrImmutableId": {
+ "type": "String"
+ },
+ "StreamName": {
+ "type": "String"
}
},
"triggers": {
@@ -510,11 +480,6 @@
"connectionName": "[variables('AzureadipConnectionName')]",
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/Azureadip')]"
},
- "azureloganalyticsdatacollector": {
- "connectionId": "[resourceId('Microsoft.Web/connections', variables('AzureloganalyticsdatacollectorConnectionName'))]",
- "connectionName": "[variables('AzureloganalyticsdatacollectorConnectionName')]",
- "id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/Azureloganalyticsdatacollector')]"
- },
"rfi-customconnector-0-2-0": {
"connectionId": "[resourceId('Microsoft.Web/connections', variables('Rfi-Customconnector-0-2-0ConnectionName'))]",
"connectionName": "[variables('Rfi-Customconnector-0-2-0ConnectionName')]",
@@ -526,6 +491,15 @@
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/Azuremonitorlogs')]"
}
}
+ },
+ "DceEndpoint": {
+ "value": "[reference(variables('dceResourceId'), '2024-03-11').logsIngestion.endpoint]"
+ },
+ "DcrImmutableId": {
+ "value": "[reference(variables('dcrResourceId'), '2024-03-11').immutableId]"
+ },
+ "StreamName": {
+ "value": "[variables('StreamName')]"
}
},
"provisioningState": "Succeeded",
@@ -533,6 +507,21 @@
},
"type": "Microsoft.Logic/workflows"
},
+ {
+ "type": "Microsoft.Authorization/roleAssignments",
+ "apiVersion": "2022-04-01",
+ "name": "[guid(variables('dcrResourceId'), parameters('PlaybookName'), variables('MonitoringMetricsPublisherRoleId'))]",
+ "scope": "[variables('dcrResourceId')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Logic/workflows', parameters('PlaybookName'))]"
+ ],
+ "properties": {
+ "roleDefinitionId": "[variables('MonitoringMetricsPublisherRoleId')]",
+ "principalId": "[reference(resourceId('Microsoft.Logic/workflows', parameters('PlaybookName')), '2019-05-01', 'Full').identity.principalId]",
+ "principalType": "ServicePrincipal"
+ },
+ "condition": "[parameters('create_role_assignment')]"
+ },
{
"apiVersion": "2016-06-01",
"kind": "V1",
@@ -575,20 +564,6 @@
},
"type": "Microsoft.Web/connections"
},
- {
- "apiVersion": "2016-06-01",
- "kind": "V1",
- "location": "[resourceGroup().location]",
- "name": "[variables('AzureloganalyticsdatacollectorConnectionName')]",
- "properties": {
- "api": {
- "id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/Azureloganalyticsdatacollector')]"
- },
- "customParameterValues": {},
- "displayName": "[variables('AzureloganalyticsdatacollectorConnectionName')]"
- },
- "type": "Microsoft.Web/connections"
- },
{
"apiVersion": "2016-06-01",
"kind": "V1",
@@ -607,8 +582,13 @@
"variables": {
"AzureadConnectionName": "[concat('Azuread-', parameters('PlaybookName'))]",
"AzureadipConnectionName": "[concat('Azureadip-', parameters('PlaybookName'))]",
- "AzureloganalyticsdatacollectorConnectionName": "[concat('Azureloganalyticsdatacollector-', parameters('PlaybookName'))]",
"AzuremonitorlogsConnectionName": "[concat('Azuremonitorlogs-', parameters('PlaybookName'))]",
- "Rfi-Customconnector-0-2-0ConnectionName": "RFI-CustomConnector-0-2-0"
+ "Rfi-Customconnector-0-2-0ConnectionName": "RFI-CustomConnector-0-2-0",
+ "MonitoringMetricsPublisherRoleId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')]",
+ "DceName": "recorded-future-identity-dce",
+ "DcrName": "recorded-future-identity-dcr-playbook-alerts",
+ "StreamName": "Custom-RFI_PlaybookAlertResults_V2_CL",
+ "dceResourceId": "[resourceId('Microsoft.Insights/dataCollectionEndpoints', variables('DceName'))]",
+ "dcrResourceId": "[resourceId('Microsoft.Insights/dataCollectionRules', variables('DcrName'))]"
}
-}
+}
\ No newline at end of file
diff --git a/Solutions/Recorded Future Identity/Playbooks/readme.md b/Solutions/Recorded Future Identity/Playbooks/readme.md
index 3adbfe123d3..a04b2fdfcc9 100644
--- a/Solutions/Recorded Future Identity/Playbooks/readme.md
+++ b/Solutions/Recorded Future Identity/Playbooks/readme.md
@@ -2,178 +2,224 @@
Link to [Recorded Future Identity main readme](../readme.md)
+---
+
+## Migrations & Breaking Changes
+
> [!IMPORTANT]
-> ## Microsoft Defender Platform Migration - Breaking Changes
+> ### Log Ingestion API migration (deadline: 2026-09-14)
>
-> **The `RFI-Playbook-Alert-Importer-LAW-Sentinel` playbook is deprecated**. Incidents created via the Azure Sentinel Logic Apps connector do not appear in the unified Microsoft Defender portal.
+> The `RFI-Playbook-Alert-Importer-LAW` playbook used the deprecated Azure Log Analytics Data Collector connector, which Microsoft is retiring on September 14, 2026.
>
-> ### Migration Path
-> 1. Use **`RFI-Playbook-Alert-Importer-LAW`** to write identity exposure data to Log Analytics
-> 2. Deploy **Analytics Rule** to create incidents from the `RecordedFutureIdentity_PlaybookAlertResults_CL` table
+> Notable solution changes:
+> - `RFI-Playbook-Alert-Importer-LAW` has been updated to use the Log Ingestion API instead, which authenticates via managed identity and routes data through a Data Collection Endpoint (DCE) and Data Collection Rule (DCR) rather than a shared workspace key.
+> - The LAW table has been renamed from `RecordedFutureIdentity_PlaybookAlertResults_CL` to `RFI_PlaybookAlertResults_V2_CL` (Microsoft doesn't allow us to target an existing "v1" table with DCR/DCE without running migration scripts, so a new table was needed)
+>
+> **Migration path:**
+> 1. Deploy the Data Connectors infrastructure (step B1) and the updated Logic App (step B3).
+> 2. Deploy the updated Analytics Rule that creates incidents from `RFI_PlaybookAlertResults_V2_CL` (step B4).
+> 3. _Optional_: If you have other logic apps or processes dependent on `RecordedFutureIdentity_PlaybookAlertResults_CL`, update these references to `RFI_PlaybookAlertResults_V2_CL`.
+
+> [!WARNING]
+> ### Microsoft Defender Platform Migration
>
->## Incident Creation via Analytic Rules
-> Instead of relying on incident creation via Logic Apps, we provide templates for Analytic Rules that will create Alerts via Analytic Rules, grouping them by common denominator and then creating incidents. See [Incident Creation](readme.md#incident-creation) for more information.
-
-
-## Table of Contents
-
-1. [Overview](#overview)
-1. [Deployment](#deployment)
-1. [Prerequisites](#prerequisites)
-1. [Playbooks](#playbooks)
- 1. ["Connector" playbooks](#connector_playbooks)
- 1. [RFI-CustomConnector](#RFI-CustomConnector)
- 1. ["Alert" playbooks](#alert_playbooks)
- 1. [RFI-playbook-alert-importer](#RFI-playbook-alert-importer)
- 1. [RFI-playbook-alert-importer-law](#RFI-playbook-alert-importer-law)
- 1. [RFI-playbook-alert-importer-law-sentinel (DEPRECATED)](#RFI-playbook-alert-importer-law-sentinel)
-1. [How to configure playbooks](#configuration)
- 1. [How to find the playbooks (Logic Apps) after deployment](#find_playbooks_after_deployment)
- 1. [Configuring Playbooks Connections](#configuration_connections)
- 1. [API connector authorization](#API-connector-authorization)
- 1. [Configuring Playbooks Parameters](#configuration_parameters)
-1. [How to Run Playbooks](#how_to_run_playbooks)
-1. [Suggestions for advanced users](#suggestions_for_advanced_users)
-1. [How to access Log Analytics Custom Logs](#how_to_access_log_analytics_custom_logs)
-1. [Customization](#customization)
-1. [Known Issues](#known-issues)
-1. [Useful Azure documentation](#useful_documentation)
-1. [How to obtain Recorded Future API token](#how_to_obtain_Recorded_Future_API_token)
-1. [How to contact Recorded Future](#how_to_contact_Recorded_Future)
-
-
+> The `RFI-Playbook-Alert-Importer-LAW-Sentinel` playbook is deprecated. Incidents created via the Azure Sentinel Logic Apps connector no longer appear in the Microsoft Defender portal.
+>
+> **Migration path:**
+> 1. Deploy the Data Connectors infrastructure (step B1).
+> 2. Deploy the Logic App `RFI-Playbook-Alert-Importer-LAW` (step B3) to write alert data to Log Analytics.
+> 3. Deploy the Analytics Rule (step B4) to create incidents from the `RFI_PlaybookAlertResults_V2_CL` table.
+
+---
+
## Overview
This solution contains two approaches to deal with exposed credentials.
+
- The recommended variant (based on Recorded Future Playbook Alerts) is described in this readme
-- The old variant (based on the Recorded Future Identity API) is located in the [v3.0](./v3.0/readme.md) folder
+- The old variant (based on the Recorded Future Identity API) is located in the [v3.0](v3.0) folder
-The playbooks need to be installed in the following order: custom-connector, and one of the alert playbooks.
+For importing playbook alerts, there are two options available, depending on your organization's needs and existing infrastructure:
-Expand playbook overview
+| Option | When to use |
+|-|-|
+| A. Entra ID only | Choose if only Entra ID is available. |
+| B. Entra ID + Log Analytics + Incident Creation | Choose if Entra ID and Log Analytics Workspace (LAW) is available. **Recommended.** |
-
+### How it works
-Connector playbooks:
-Custom connector are used to communicate and authorize towards Recorded Future backend API.
+Both options poll Recorded Future for Novel Identity Exposure Playbook Alerts on a recurring schedule, place affected users in an Entra ID security group, optionally confirm them as risky in Entra ID Identity Protection, and report actions taken back to Recorded Future.
-| Playbook Name| Description |
-|-|-|
-| **RFI-CustomConnector** | RFI-CustomConnector connection and authorization to Recorded Future Backend API.|
+Detailed workflow
-Alert playbook:
-These are the main playbooks
+| # | Action | Option A | Option B |
+|-|-|-|-|
+| 1 | Pull novel identity exposure Playbook Alerts from Recorded Future based on previously done Playbook Alert setup. | ✅ | ✅ |
+| 2 | For each user, check if they exist within the domain, if so, place them in a specified security group. If the user is already flagged as a "Risky user" by Microsoft, confirm them as risky. | ✅ | ✅ |
+| 3 | Save all information related to the Playbook Alert in a Log Analytics Workspace. | ❌ | ✅ |
+| 4 | Create a Microsoft Sentinel incident with information pertaining to the identity exposure. | ❌ | ✅ |
+| 5 | Report back actions taken for each specific Playbook Alert to Recorded Future, for viewing in Recorded Future Portal. | ✅ | ✅ |
-| Playbook Name | Description |
-|-|-|
-| **RFI-playbook-alert-importer** | Search new exposures for Workforce users. Choose this one if only Entra ID is available |
-| **RFI-playbook-alert-importer-law** | Search new exposures for Workforce users. Choose this one if Entra ID and Log Analytics Workspace (LAW) is available. **Recommended for Microsoft Defender Portal.** |
-| **RFI-playbook-alert-importer-law-sentinel** | **DEPRECATED** - Use RFI-playbook-alert-importer-law with a Scheduled Analytics Rule instead, eee [Incident Creation](readme.md#incident-creation) for more information.|
+
+
+
+
+Post-deployment, authorizing the connectors also requires:
+- **Entra ID** (`azuread`): the authorizing user must have the Entra role `Directory Writers`
+- **Entra ID Identity Protection** (`azureadip`): the authorizing user must have the Entra role `Security Administrator`
+
+---
-- For `Recorded Future Identity` Connections you will need `Recorded Future Identity API` token. To obtain one - check out [this section](#how_to_obtain_Recorded_Future_API_token).
-- Configure `Recorded Future Identity Exposure Playbook Alerts` for your use case within the Recorded Future portal. For detailed instructions, see this guide (requires Recorded Future login).
+## Deployment
+### Deploying Option A - Entra ID only
-#### Optional prerequisites
-These prerequisites is required for the **RFI-playbook-alert-importer-law** playbooks:
-- A [Log Analytics workspace](https://docs.microsoft.com/azure/azure-monitor/essentials/resource-logs#send-to-log-analytics-workspace). If you don't have a workspace, learn [how to create a Log Analytics workspace](https://docs.microsoft.com/azure/azure-monitor/logs/quick-create-workspace). Note that the custom logs specified as parameters in these Logic Apps will be created automatically if they don’t already exist. Note the name of the Log Analytic Workspace, it will be used at a later stage of the deployment.
-- The user who installs the Logic Apps require _**Logic App Contributor**_ and _**Microsoft Sentinel Contributor**_ permissions on a **Resource Group** level.
+This option handles Entra ID group assignment and optional risky user confirmation, but does not write any data to Log Analytics.
+Deploy the following resources **in order**:
-
-## Playbooks
+#### A1 — Deploy RFI-CustomConnector
-> [!IMPORTANT]
-> Deploy connector before deploying the alert importer playbooks.
+The custom connector handles communication with the Recorded Future API.
-
-### Connector-playbooks
+
+
-Connector playbooks are used by other playbooks in this solution to communicate with Recorded Future backend API.
+
+
+
+
+ Deployment step
+ Permission
+
+
+ B1 - Data connectors
+ Monitoring Contributor and Log Analytics Contributor on the Resource Group level.
+
+
+ B2 - Custom connector
+ Logic App Contributor and Microsoft Sentinel Contributor permissions on a Resource Group level.
+
+
+ B3 - Logic app (create_role_assignment=true)
+
+ Either:
+
+
+
+
+
+ B3 - Logic app (create_role_assignment=false)
+
+ Logic App Contributor and Microsoft Sentinel Contributor permissions on a Resource Group level.
+
+
Note: if you use create_role_assignment=false, an Azure administrator needs to manually assign Monitoring Metrics Publisher role on the recorded-future-identity-dcr-playbook-alerts Data Collection Rule to the Logic App's managed identity after deployment.
+
+
+
+
+B4 - Analytic rules
+ Microsoft Sentinel Contributor permissions on a Resource Group level.
+ Expand deployment parameters:
-## RFI-CustomConnector
+| Parameter | Description |
+|-|-|
+| **Connector-Name** | Name for this connector resource (default: `RFI-CustomConnector-0-2-0`). |
+| **Service Endpoint** | Always use the default: `https://api.recordedfuture.com/gw/azure-identity` |
-This connector is used by other playbooks in this solution to communicate with Recorded Future backend API.
+Expand deployment parameters:
| Parameter | Description |
|-|-|
-| **Subscription** | Your Azure Subscription to deploy the Solution in. All resources in an Azure subscription are billed together. |
-| **Resource group** | Resource group in your Subscription to deploy the Solution in. A resource group is a collection of resources that share the same lifecycle, permissions, and policies. |
-| **Region** | Choose the Azure region that's right for you and your customers. Not every resource is available in every region. |
-| **Connector-Name** | Connector name to use for this playbook (ex. `RFI-CustomConnector-0-2-0`). |
-|**Service Endpoint**| API Endpoint, always use the default ```https://api.recordedfuture.com/gw/azure-identity```|
+| **Playbook Name** | Name for this Logic App (default: `RFI-Playbook-Alert-Importer`). |
+| **Entra_id_security_group_id** | Object ID of the Entra ID security group to place risky users into. The group must be pre-created — search for "Groups" in the Azure Portal. Leave empty to skip group assignment. |
+| **Confirm_user_as_risky** | Confirm affected users as risky in Entra ID Identity Protection. Note: this only acts on users already flagged as risky by Microsoft — it does not flag them itself. Requires Entra ID P1 or P2 license. |
+| **Entra_id_domain** | Optional domain override — use this if your Entra ID domain differs from the leaked credential domain (e.g. leaked email is `user@acme.com` but the Entra ID UPN is `user@acme.onmicrosoft.com`, set this to `acme.onmicrosoft.com`). Leave empty if your Entra ID domain matches the leaked credential domain. |
+| **RFI Custom Connector** | Name of the connector deployed in A1 (default: `RFI-CustomConnector-0-2-0`). |
+
-
+---
+
+### Deploying Option B — Entra ID + Log Analytics + Incident Creation
+
+This option handles Entra ID group assignment and optional risky user confirmation, as well as saving detailed Playbook Alert data to a Log Analytics Workspace and enabling automatic incident creation via an Analytic Rule.
+
+Deploy the following resources **in order**:
-## Alert Playbooks
+#### B1 — Deploy Data Connectors infrastructure
-Search the Recorded Future Identity Intelligence Module for compromised identities. Depending on your use case, select the playbook that fits.
+Shared infrastructure required by the playbook to write data to Log Analytics: a Data Collection Endpoint (DCE), a Data Collection Rule (DCR), the `RFI_PlaybookAlertResults_V2_CL` Log Analytics table, and the Data Connector tile in the Microsoft Sentinel Data Connectors blade. Deploy this into the same resource group as your Log Analytics Workspace.
+
+
+
Workflow of Alert Playbooks
+Expand deployment parameters:
-| # | Action |
-|-|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| 1 | Pull novel identity exposure Playbook Alerts from Recorded Future based on previously done Playbook Alert setup. |
-| 2 | For each user, check if they exist within the domain, if so, place them in a specified security group. If the user is already flagged as a "Risky user" by Microsoft, confirm them as risky. |
-| 3 | (Optional) Save all information related to the Playbook Alert in a Log Analytics Workspace. |
-| 3 | (Optional) Create a Microsoft Sentinel incident with information pertaining the identity exposure. |
-| 4 | Report back actions taken for each specific Playbook Alert to Recorded Future, for viewing in Recorded Future Portal. |
+| Parameter | Description |
+|-|-|
+| **log_analytics_workspace_name** | Name of your Log Analytics Workspace. Must be in the same resource group. |
+| **log_analytics_workspace_location** | Location of the workspace. Defaults to the resource group location. |
Expand deployment parameters:
-| Parameter | Description |
-|--------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| **Subscription** | Your Azure Subscription to deploy the Solution in. All resources in an Azure subscription are billed together. |
-| **Resource group** | Resource group in your Subscription to deploy the Solution in. A resource group is a collection of resources that share the same lifecycle, permissions, and policies. |
-| **Region** | Choose the Azure region that's right for you and your customers. Not every resource is available in every region. |
-| **Playbook Name** | Playbook name to use for this playbook (ex. `RFI-Playbook-Alert-Importer`). |
-| **Entra_id_security_group_id** | (Optional) ID of the the group in which to place risky users. If left empty, a user will **not** be placed in a Entra ID security group. |
-|**Confirm_user_as_risky**| Boolean parameter to determine if a user should be confirmed as risky. Requires Microsoft Entra ID P1 or P2 license. |
-| **Entra_id_domain** | (Optional) If domains does not match between external and Entra ID domains specify the domain used in Entra ID. Example: john.smith@acme -> john.smith@onmicrosoft.com |
-| **RFI Custom Connector** | Name of the custom connector which to connect to Recorded Future with, should typically not deviate from `RFI-CustomConnector-0-2-0` |
+| Parameter | Description |
+|-|-|
+| **Connector-Name** | Name for this connector resource (default: `RFI-CustomConnector-0-2-0`). |
+| **Service Endpoint** | Always use the default: `https://api.recordedfuture.com/gw/azure-identity` |
+
-
-### Deployment RFI-playbook-alert-importer-law
+#### B3 — Deploy RFI-Playbook-Alert-Importer-LAW
+
+Logic App that runs on a recurring schedule.


@@ -181,92 +227,60 @@ Depending on your use case, deploy **one** of the following playbooks:
Expand deployment parameters:
-| Parameter | Description |
-|--------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| **Subscription** | Your Azure Subscription to deploy the Solution in. All resources in an Azure subscription are billed together. |
-| **Resource group** | Resource group in your Subscription to deploy the Solution in. A resource group is a collection of resources that share the same lifecycle, permissions, and policies. |
-| **Region** | Choose the Azure region that's right for you and your customers. Not every resource is available in every region. |
-| **Playbook Name** | Playbook name to use for this playbook (ex. "RFI-Playbook-Alert-Importer-LAW"). |
-| **Save_to_log_analytics_workspace** | Boolean parameter to determine if the playbook should save the detailed Playbook Alert information to Log Analytics Workspace (LAW). |
-| **Entra_id_security_group_id** | (Optional) ID of the the group in which to place risky users. If left empty, a user will **not** be placed in a Entra ID security group. |
-|**Confirm_user_as_risky**| Boolean parameter to determine if a user should be confirmed as risky. Requires Microsoft Entra ID P1 or P2 license. |
-| **Entra_id_domain** | (Optional) If domains does not match between external and Entra ID domains specify the domain used in Entra ID. Example: john.smith@acme -> john.smith@onmicrosoft.com |
-| **Playbook_alert_log_analytics_custom_log_name** | Name of the custom log in Log Analytics Workspace, defaults to `RecordedFutureIdentity_PlaybookAlertResults_CL`. |
-| **RFI Custom Connector** | Name of the custom connector which to connect to Recorded Future with, should typically not deviate from `RFI-CustomConnector-0-2-0` |
-
+| Parameter | Description |
+|-|-|
+| **Playbook Name** | Name for this Logic App (default: `RFI-Playbook-Alert-Importer-LAW`). |
+| **Save_to_log_analytics_workspace** | Whether to save detailed Playbook Alert data to Log Analytics. Defaults to `true`. |
+| **Entra_id_security_group_id** | Object ID of the Entra ID security group to place risky users into. The group must be pre-created — search for "Groups" in the Azure Portal. Leave empty to skip group assignment. |
+| **Confirm_user_as_risky** | Confirm affected users as risky in Entra ID Identity Protection. Note: this only acts on users already flagged as risky by Microsoft — it does not flag them itself. Requires Entra ID P1 or P2 license. |
+| **Entra_id_domain** | Optional domain override — use this if your Entra ID domain differs from the leaked credential domain (e.g. leaked email is `user@acme.com` but the Entra ID UPN is `user@acme.onmicrosoft.com`, set this to `acme.onmicrosoft.com`). Leave empty if your Entra ID domain matches the leaked credential domain. |
+| **Playbook_alert_log_analytics_custom_log_name** | Name of the Log Analytics table to write alert data to (default: `RFI_PlaybookAlertResults_V2_CL`). |
+| **log_analytics_workspace_name** | Name of your Log Analytics Workspace. |
+| **create_role_assignment** | Whether to automatically assign the _Monitoring Metrics Publisher_ role on the DCR to the Logic App's managed identity. See [Required Permissions](#required-permissions) for details. |
+| **RFI Custom Connector** | Name of the connector deployed in B2 (default: `RFI-CustomConnector-0-2-0`). |
-
-### Deployment RFI-playbook-alert-importer-law-sentinel (DEPRECATED)
+Expand deployment parameters:
+
-| Parameter | Description |
-|--------------------------------------------------|-|
-| **Subscription** | Your Azure Subscription to deploy the Solution in. All resources in an Azure subscription are billed together. |
-| **Resource group** | Resource group in your Subscription to deploy the Solution in. A resource group is a collection of resources that share the same lifecycle, permissions, and policies. |
-| **Region** | Choose the Azure region that's right for you and your customers. Not every resource is available in every region. |
-| **Playbook Name** | Playbook name to use for this playbook (ex. "RFI-Playbook-Alert-Importer-LAW-Sentinel"). |
-| **Save_to_log_analytics_workspace** |Boolean parameter to determine if the playbook should save the detailed Playbook Alert information to Log Analytics Workspace (LAW)|
-| **Entra_id_security_group_id** | (Optional) ID of the the group in which to place risky users. If left empty, a user will **not** be placed in a Entra ID security group. |
-|**Confirm_user_as_risky**| Boolean parameter to determine if a user should be confirmed as risky. Requires Microsoft Entra ID P1 or P2 license. |
-| **Create_incident** |**DEPRECATED** - Boolean parameter to determine if the playbook should create a incident in Microsoft Sentinel. **Incidents created this way will not appear in Microsoft Defender portal.**|
-| **Sentinel_workspace_name** |**DEPRECATED** - Workspace name in which to create Microsoft Sentinel incidents|
-| **Entra_id_domain** | (Optional) If domains does not match between external and Entra ID domains specify the domain used in Entra ID. Example: john.smith@acme -> john.smith@onmicrosoft.com |
-| **Playbook_alert_log_analytics_custom_log_name** |Name of the custom log in Log Analytics Workspace, defaults to `RecordedFutureIdentity_PlaybookAlertResults_CL`|
-| **RFI Custom Connector** | Name of the custom connector which to connect to Recorded Future with, should typically not deviate from `RFI-CustomConnector-0-2-0`|
-
+After deployment the Logic App will show errors until all connections are authorized. Navigate to the Logic App → **Development tools** → **API connections**.
-After all the Connections are created/validated, it's important to enable the Logic App.
+
-
-### API connector authorization
-The Recorded Future identity solution uses the following connectors, some are required and and some optional. Information on how to authorize connectors is documented in the provided links. Playbooks use connectors that have to be individually authorized during deployment.
+The Recorded Future identity solution uses the following connectors. Each needs to be individually authorized after deployment.
| Connector | Description |
|-|-|
-| **/RFI-CustomConnector** | [RecordedFuture-CustomConnector](../../Recorded%20Future/Playbooks/Connectors/RecordedFuture-CustomConnector/readme.md)
+
-(Example above shows some parameters, number of parameters depends on playbook used)
+### Running the playbook
-### Playbook parameters
+The playbook runs on a recurring schedule. You can also trigger it manually or adjust the interval from the Logic App designer.
-- **You need to create a Microsoft Entra ID group, and provide the Object ID as a parameter to the Playbook. For more information, see [Microsoft EntraID Groups](https://learn.microsoft.com/en-us/entra/fundamentals/how-to-manage-groups) documentation.**
-
-| Parameter | Description |
-|-|-|
-| **entra_id_security_group_id** | Object ID of Microsoft EntraID Group for users at risk. You need to pre-create it by hand: search for "Groups" in Service search at the top of the page. For more information, see [Microsoft EntraID Groups](https://docs.microsoft.com/windows/security/identity-protection/access-control/active-directory-security-groups) documentation. If left empty, a user will **not** be placed in a Entra ID security group. |
-|**Confirm_user_as_risky**| Boolean parameter to determine if a user should be confirmed as risky. **Requires** Microsoft Entra ID P1 or P2 license to function properly. For more information about the Azure AD Identity Protection, click here |
-| **entra_id_domain** | (Optional, can be left empty) - in case your Microsoft EntraID domain is different from your organization domain, this parameter will be used to transform compromised credentials to find corresponding user in your Microsoft EntraID (ex. Compromised email: leaked@mycompany.com), your Microsoft EntraID domain: `@mycompany.onmicrosoft.com`, so you set parameter `entra_id_domain = mycompany.onmicrosoft.com` (**just domain, without "@"**), and search playbooks will replace the domain from the leaked email with the provided domain from the entra_id_domain parameter, before searching for the corresponding user in your Microsoft EntraID: `leaked@mycompany.com -> leaked@mycompany.onmicrosoft.com`. (Lookup playbook - will still use the original email to Lookup the data). |
-| **save_to_log_analytics_workspace** |(Optional, requires Log Analytics Workspace) - Boolean parameter to determine if the playbook should save the detailed Playbook Alert information to Log Analytics Workspace (LAW)|
-| **create_incident** | **DEPRECATED** - (Optional, requires Microsoft Sentinel) - Boolean parameter to determine if the playbook should create a incident in Microsoft Sentinel|
-|**playbook_alert_log_analytics_custom_log_name**| (Optional, requires Log Analytics Workspace) - Name of custom log where detailed Playbook Alert lookup information will be stored. Defaults to `RecordedFutureIdentity_PlaybookAlertResults_CL`|
-|**log_analytics_workspace_name**| (Optional, required for Log Analytics Workspace) - Name of the workspace where the logs should be saved.|
+
+### Accessing Log Analytics Custom Logs
-
-
-
-## How to access Log Analytics Custom Logs
-
-To see Log Analytics Custom Logs:
-- From then Azure Portal, navigate to the `Log Analytics workspaces` service
-- There, select the Log Analytic Workspace in which you have deployed the Solution
-- There, in the left-side menu click on Logs, and expand second left side menu, and select Custom Logs
-
-
## Customization
-Recorded Future Identity Solution is a baseline solution, there are ways to customize it to your preferred workflow.
-#### Automatic remediation of identity exposures
-The default configuration for this playbook provides remediation in the form of placing a user in a security group and confirming a user as risky (requires Microsoft Entra ID P1 or P2 license). Based on this there is other remediation actions that can be done, either manual or automatic. The various ways to configure automatic remediation are based on organizational needs and knowledge of the Azure environment to find a appropriate remediation path.
+### Automatic remediation
+The default configuration remediates exposed users by placing them in an Entra ID security group and optionally confirming them as risky. Depending on your Entra ID license level, additional automated remediation options are available:
-Depending of Entra ID licensing levels, some solutions available are:
- - Conditional Access Policies (requires Microsoft Entra ID P1 or P2 license) - More information here
- - Microsoft Entra ID Protection (requires Microsoft Entra ID P1 or P2 license) - More information here
- - Microsoft Graph API - Powerful, no license requirements but requires extensive configuration - More information here. For advanced guidance, please contact your Recorded Future Customer Success Manager.
+- [Conditional Access Policies](https://learn.microsoft.com/en-us/entra/identity/conditional-access/overview) — requires P1 or P2. Allows blocking sign-ins for users in the risky group.
+- [Entra ID Protection](https://learn.microsoft.com/en-us/entra/id-protection/overview-identity-protection) — requires P1 or P2. Allows forcing password resets for risky users.
+- [Microsoft Graph API](https://learn.microsoft.com/en-us/graph/identity-network-access-overview) — no license requirement, but requires additional configuration. Contact your Recorded Future Customer Success Manager for guidance.
-#### Recorded Future Playbook Alert Onward Actions
-Onward Actions is a way to keep the Recorded Future Playbook Alert up to date with actions taken in regards to a specific alert, to get a overview of actions taken on alerts.
-By default the Playbook Alert Update steps have been configured with `added_actions_taken` set to `identity_novel_exposures.placed_in_risky_group`, if the solution is extended with actions such as blocking users or forcing password resets, you can submit this information to Recorded Future. Currently the following actions are supported:
-| Action |
-|-|
-|identity_novel_exposures.enforced_password_reset|
-|identity_novel_exposures.placed_in_risky_group|
-|identity_novel_exposures.reviewed_incident_report|
-|identity_novel_exposures.account_disabled_or_terminated|
-|identity_novel_exposures.account_remediated|
-|identity_novel_exposures.other|
+### Onward Actions
-To change/add actions, modify the items under `added_actions_taken` parameter in the Playbook Alerts Update step:
+The playbook reports back to Recorded Future which remediation actions were taken on each alert, keeping the Playbook Alert status in the Recorded Future portal up to date. By default the playbook reports `identity_novel_exposures.placed_in_risky_group`. To add or change reported actions, modify the `added_actions_taken` field in the Playbook Alert Update step in the Logic App designer.

-### Incident creation
+Supported values:
-Following changes made by Microsoft, removing the possibility to create incidents via Logic Apps, we now provide the following analytic rules. For these to work out of the box, it's important that the `Custom Log Names` in the corresponding Logic Apps are used.
-
-It's important that the logic app has at least one run ___before___ deploying the analytic rule, since the analytic rule **requires** that the custom log table with **all** used fields are created. This is done at the first run of the `RFI-Playbook-Alert-Importer-LAW` playbook.
-
-There is a general limitation of ***3*** fields in the alert description. More information is available in Log Analytics Workspace.
-
-|Use Case|Analytic Rule|Custom Log Name
-|-|-|-|
-|Identity|RecordedFutureIdentityExposure|RecordedFutureIdentity_PlaybookAlertResults_CL
+| Action |
+|-|
+| `identity_novel_exposures.enforced_password_reset` |
+| `identity_novel_exposures.placed_in_risky_group` |
+| `identity_novel_exposures.reviewed_incident_report` |
+| `identity_novel_exposures.account_disabled_or_terminated` |
+| `identity_novel_exposures.account_remediated` |
+| `identity_novel_exposures.other` |
-These analytic are be available under `Microsoft Sentinel -> Configuration -> Analytics -> Rule Templates`.
+---
## Known Issues
@@ -446,9 +368,19 @@ Microsoft Entra ID Protection is a premium feature. You need an Microsoft Entra
#### Playbook Alert set to resolved but not added to Security Group
When the user that authorizes the Entra ID connector can search for a user in Entra ID, but lacks sufficient privileges to add the user to a group (e.g, same organization, but no permissions to modify users) there can be a scenario where the Logic App does not fail, and the Playbook Alert is incorrectly set to resolve, even if no remediation action has been done. A possible remediation can be that the user which authorizes the Entra ID connector has sufficient privileges to modify all users in a organization.
+---
+
+## Deprecated: RFI-Playbook-Alert-Importer-LAW-Sentinel
-#### Custom log table RecordedFutureIdentity_PlaybookAlertResults_CL is not created
-This can occur when the user authorizing the **azureloganalyticsdatacollector** connection in the playbook does not have sufficient permissions. Unfortunately the action will display `Success` even though the table never was created. If this happens, please review permissions. See [API connector authorization](readme#api-connector-authorization) for more information.
+> [!WARNING]
+> This playbook is deprecated and should not be used for new deployments. Incidents created via the Azure Sentinel Logic Apps connector do not appear in the unified Microsoft Defender portal. Use `RFI-Playbook-Alert-Importer-LAW` with an Analytics Rule instead — see **Option B** above.
+
+The deploy button below is provided for reference only.
+
+
+
+
+---
## Useful Azure documentation
@@ -461,11 +393,11 @@ Permissions / Roles:
- [Log Analytics](https://docs.microsoft.com/azure/role-based-access-control/built-in-roles#log-analytics-contributor)
- [Logic Apps](https://docs.microsoft.com/azure/role-based-access-control/built-in-roles#logic-app-contributor)
+---
+
+## Support & API Token
-
-## How to contact Recorded Future
-
-If you are already a Recorded Future client and wish to learn more about using Recorded Future’s Microsoft integrations, including how to obtain an API Token to enable an integration contact us at **support@recordedfuture.com**.
+You can issue a Recorded Future Identity API token yourself by visiting the Integration Center within the [Recorded Future Portal](https://app.recordedfuture.com).
-If you not a current Recorded Future client and wish to become one, contact **sales@recordedfuture.com** to setup a discussion with one of our business development associates.
\ No newline at end of file
+For questions or support, contact **support@recordedfuture.com**.