{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "workspace": {
      "type": "String"
    }
  },
  "resources": [
    {
      "apiVersion": "2024-01-01-preview",
      "id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/90bacdf4-e35b-47cb-92d1-29d8397eb4a0')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/90bacdf4-e35b-47cb-92d1-29d8397eb4a0')]",
      "properties": {
        "alertDetailsOverride": {
          "alertDynamicProperties": []
        },
        "alertRuleTemplateName": "90bacdf4-e35b-47cb-92d1-29d8397eb4a0",
        "customDetails": null,
        "description": "Detects an application receiving administrator permissions and then using them to assign a role. This pattern can indicate rapid privilege escalation through app consent abuse.\n",
        "displayName": "[Entra ID] Application Assigned Administrator Permissions Immediately After Obtaining Role Management Permissions",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "Source_Identity_FullName",
                "identifier": "FullName"
              }
            ]
          },
          {
            "entityType": "CloudApplication",
            "fieldMappings": [
              {
                "columnName": "Target_Identity_FullName",
                "identifier": "Name"
              }
            ]
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/eDCRule/Analytic%20Rules/%5BEntra%20ID%5D%20Application%20Assigned%20Administrator%20Permissions%20Immediately%20After%20Obtaining%20Role%20Management%20Permissions.yaml",
        "query": "let query_frequency = 1h;\nlet query_period = 2h;\nAuditLogs\n| where TimeGenerated > ago(query_period)\n| where Category =~ \"ApplicationManagement\" and LoggedByService =~ \"Core Directory\"\n| where OperationName =~ \"Add app role assignment to service principal\"\n| mv-expand TargetResource = TargetResources\n| mv-expand modifiedProperty = TargetResource[\"modifiedProperties\"]\n| where tostring(modifiedProperty[\"displayName\"]) == \"AppRole.Value\"\n| extend PermissionGrant = tostring(modifiedProperty[\"newValue\"])\n| where PermissionGrant has \"RoleManagement.ReadWrite.Directory\"\n| mv-apply modifiedProperty = TargetResource[\"modifiedProperties\"] on (\n    summarize modifiedProperties = make_bag(\n                                   bag_pack(\n    tostring(modifiedProperty[\"displayName\"]),\n    bag_pack(\n    \"oldValue\",\n    trim(@'[\\\"\\s]+', tostring(modifiedProperty[\"oldValue\"])),\n    \"newValue\",\n    trim(@'[\\\"\\s]+', tostring(modifiedProperty[\"newValue\"]))\n)\n),\n                                   100\n                               )\n    )\n| project\n    PermissionGrant_TimeGenerated = TimeGenerated,\n    PermissionGrant_OperationName = OperationName,\n    PermissionGrant_Result = Result,\n    PermissionGrant,\n    AppDisplayName = tostring(modifiedProperties[\"ServicePrincipal.DisplayName\"][\"newValue\"]),\n    AppServicePrincipalId = tostring(modifiedProperties[\"ServicePrincipal.ObjectID\"][\"newValue\"]),\n    PermissionGrant_InitiatedBy = InitiatedBy,\n    PermissionGrant_TargetResources = TargetResources,\n    PermissionGrant_AdditionalDetails = AdditionalDetails,\n    PermissionGrant_CorrelationId = CorrelationId\n| join kind=inner (\n    AuditLogs\n    | where TimeGenerated > ago(query_frequency)\n    | where Category =~ \"RoleManagement\"\n        and LoggedByService =~ \"Core Directory\"\n        and AADOperationType =~ \"Assign\"\n    | where isnotempty(InitiatedBy[\"app\"])\n    | mv-expand TargetResource = TargetResources\n    | mv-expand modifiedProperty = TargetResource[\"modifiedProperties\"]\n    | where tostring(modifiedProperty[\"displayName\"]) in (\"Role.DisplayName\", \"RoleDefinition.DisplayName\")\n    | extend RoleAssignment = tostring(modifiedProperty[\"newValue\"])\n    | where RoleAssignment contains \"Admin\"\n    | project\n        RoleAssignment_TimeGenerated = TimeGenerated,\n        RoleAssignment_OperationName = OperationName,\n        RoleAssignment_Result = Result,\n        RoleAssignment,\n        TargetType = tostring(TargetResources[0][\"type\"]),\n        Target = iff(isnotempty(TargetResources[0][\"displayName\"]), tostring(TargetResources[0][\"displayName\"]), tolower(TargetResources[0][\"userPrincipalName\"])),\n        TargetId = tostring(TargetResources[0][\"id\"]),\n        RoleAssignment_InitiatedBy = InitiatedBy,\n        RoleAssignment_TargetResources = TargetResources,\n        RoleAssignment_AdditionalDetails = AdditionalDetails,\n        RoleAssignment_CorrelationId = CorrelationId,\n        AppServicePrincipalId = tostring(InitiatedBy[\"app\"][\"servicePrincipalId\"])\n    )\n    on AppServicePrincipalId\n| where PermissionGrant_TimeGenerated < RoleAssignment_TimeGenerated\n| extend\n    TargetName = tostring(split(Target, \"@\")[0]),\n    TargetUPNSuffix = tostring(split(Target, \"@\")[1])\n| project\n        Alert_Category_en = \"Entra ID\",\n    Alert_SubCategory_en = \"Anomaly Identity Privilege Modification\",\n    Alert_Name_en = \"Application Assigned Administrator Permissions Immediately After Obtaining Role Management Permissions\",\n    Alert_Description_en = strcat(\n                           \"At Taiwan time\",\n                           format_datetime(datetime_utc_to_local(RoleAssignment_TimeGenerated, \"Asia/Taipei\"), \"yyyy-MM-dd HH:mm:ss\"),\n                           \". \",\n                           \"EntraID:\",\n                           \"\",\n                           \". \",\n                           \"detected initiator: \",\n                           tostring(PermissionGrant_InitiatedBy.user.userPrincipalName),\n                           \" granted application: \",\n                           AppDisplayName,\n                           \" permission: \",\n                           PermissionGrant,\n                           \"afterward, the application immediately assigned a role to target: \",\n                           Target,\n                           \"role assignment: \",\n                           RoleAssignment\n                       ),\n    Alert_TriageStep_en = strcat(\n                          \"1. Confirm initiator: \",\n                          tostring(PermissionGrant_InitiatedBy.user.userPrincipalName),\n                          \"IP:\",\n                          tostring(PermissionGrant_InitiatedBy.ipAddress),\n                          \", and review the authorized application: \",\n                          AppDisplayName,\n                          \", obtained permission: \",\n                          PermissionGrant,\n                          \", to determine whether it is expected behavior/automation. \",\n                          \"2. Review application: \",\n                          AppDisplayName,\n                          \" for target: \",\n                          Target,\n                          \" role assignment content: \",\n                          RoleAssignment,\n                          \", to determine whether it is expected behavior/automation. \"\n                      ),\n    Alert_Containment_en = strcat(\n                           \"1. If determined to be unauthorized behavior, immediately disable initiator: \",\n                           tostring(PermissionGrant_InitiatedBy.user.userPrincipalName),\n                           \" and application: \",\n                           AppDisplayName,\n                           \", and revoke its Directory/RoleManagement-related permissions. \",\n                           \"2. Immediately revert/remove the improper administrator role assignment: \",\n                           Target,\n                           \", and review whether other role/group/application assignments were changed.\"\n                       ),\n    Alert_Remediation_en =\n    \"1. Strengthen Conditional Access and account governance: enforce MFA/managed device and named location restrictions for administrator accounts, and block abnormal IPs. \"\n    \"2. Implement least privilege and PIM: use Just-In-Time (JIT) activation with approval for administrator roles to reduce the risk of immediate abuse after account compromise. \"\n    \"3. Strengthen detection and automation: establish automated response SOAR (notification/revoke authorization/disable application/revert role/block source).\",\n            Alert_Time_TW = datetime_utc_to_local(RoleAssignment_TimeGenerated, \"Asia/Taipei\"),\n    Alert_Time_UTC0 = RoleAssignment_TimeGenerated,\n    Event_Action = RoleAssignment_OperationName,\n    Event_Status = RoleAssignment_Result,\n    Event_Description = strcat(\"initiator: \", tostring(PermissionGrant_InitiatedBy.user.userPrincipalName), \" to application: \", AppDisplayName, \", \", PermissionGrant_OperationName, \". Subsequently, application: \", AppDisplayName, \" for target \", Target, \", \", RoleAssignment_OperationName),\n    Source_Identity_FullName = AppDisplayName,\n    Source_Identity_ID = AppServicePrincipalId,\n    Source_Identity_Type = \"Service\",\n    Target_Identity_FullName = Target,\n    Target_Identity_ID = TargetId,\n    Target_Identity_Name = TargetName,\n    Target_Identity_Type = iff(TargetType has \"User\", \"User\", \"Service\"),\n    Target_Resource_ID = \"\",\n    Target_Resource_Name = \"Microsoft Entra ID\",\n    Target_Resource_Type = \"Microsoft Entra ID\"\n",
        "queryFrequency": "PT1H",
        "queryPeriod": "PT2H",
        "severity": "High",
        "status": "Available",
        "subTechniques": [
          "T1078.004",
          "T1098.003"
        ],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "DefenseEvasion",
          "InitialAccess",
          "Persistence",
          "PrivilegeEscalation"
        ],
        "techniques": [
          "T1078",
          "T1098"
        ],
        "templateVersion": "1.0.0",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}
