Detection rules › Kusto
Power Platform - Account added to privileged Microsoft Entra roles
Identifies changes to privileged directory roles impacting Power Platform: - Dynamics 365 Admins - Power Platform Admins - Fabric Admins
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Privilege Escalation | T1068 Exploitation for Privilege Escalation, T1078 Valid Accounts, T1548 Abuse Elevation Control Mechanism |
Event coverage
| Provider | Event | Title |
|---|---|---|
| Entra-AuditLogs | _catch_all | Entra ID audit event (any operation) |
Rules detecting the same action
Other rules on this platform that filter on the same API call or operation.
- Admin promotion after Role Management Application Permission Grant (Kusto)
- Bulk Changes to Privileged Account Permissions (Kusto)
- Changes to PIM Settings (Kusto)
- Detect PIM Alert Disabling activity (Kusto)
- Multiple admin membership removals from newly created admin. (Kusto)
- New External User Granted Admin Role (Kusto)
- NRT Privileged Role Assigned Outside PIM (Kusto)
- NRT User added to Microsoft Entra ID Privileged Groups (Kusto)
Rule body kusto
id: 71d829d6-eb50-4a17-8a64-655fae8d71e1
kind: Scheduled
name: Power Platform - Account added to privileged Microsoft Entra roles
description: |
Identifies changes to privileged directory roles impacting Power Platform:
- Dynamics 365 Admins
- Power Platform Admins
- Fabric Admins
severity: Low
status: Available
requiredDataConnectors:
- connectorId: AzureActiveDirectory
dataTypes:
- AuditLogs
queryFrequency: 1h
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
tactics:
- PrivilegeEscalation
relevantTechniques:
- T1078
- T1068
- T1548
query: |
// 44367163-eba1-44c3-98af-f5787879f96a = Dynamics 365 Administrator
// 11648597-926c-4cf3-9c36-bcebb0ba8dcc = Power Platform Administrator
// a9ea8996-122f-4c74-9520-8edcd192826c = Fabric Administrator
let query_frequency = 1h;
let role_template_ids = dynamic(["44367163-eba1-44c3-98af-f5787879f96a", "11648597-926c-4cf3-9c36-bcebb0ba8dcc", "a9ea8996-122f-4c74-9520-8edcd192826c"]);
let monitored_activities = dynamic(["Assign", "AssignGrantedRole", "AssignPermanentGrantedRole", "AssignPermanentEligibleRole", "RoleElevatedOutsidePimAlert"]);
AuditLogs
| where TimeGenerated >= ago(query_frequency)
| where Category == "RoleManagement"
and TargetResources has_any (role_template_ids)
and AADOperationType in (monitored_activities)
and Identity != "MS-PIM" and Identity != "MS-PIM-Fairfax"
| extend
UserPrincipalName = tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName),
AadUserId = tostring(parse_json(tostring(InitiatedBy.user)).id),
IPAddress = tostring(parse_json(tostring(InitiatedBy.user)).ipAddress),
RoleName = tostring(TargetResources[0].displayName),
UserAdded = tostring(TargetResources[2].userPrincipalName)
| extend
RoleName = iif(isempty(RoleName), tostring(parse_json(tostring(TargetResources[0].modifiedProperties))[1].newValue), RoleName),
UserAdded = iif(isempty(UserAdded), tostring(parse_json(tostring(TargetResources[0].userPrincipalName))), UserAdded),
CloudAppId = int(32780),
AccountName = tostring(split(UserPrincipalName, '@')[0]),
UPNSuffix = tostring(split(UserPrincipalName, '@')[1])
| project
TimeGenerated,
Identity,
UserPrincipalName,
AadUserId,
RoleName,
OperationName,
UserAdded,
TargetResources,
CloudAppId,
AccountName,
UPNSuffix
eventGroupingSettings:
aggregationKind: SingleAlert
entityMappings:
- entityType: CloudApplication
fieldMappings:
- identifier: AppId
columnName: CloudAppId
- entityType: Account
fieldMappings:
- identifier: Name
columnName: AccountName
- identifier: UPNSuffix
columnName: UPNSuffix
alertDetailsOverride:
alertDisplayNameFormat: Power Platform - Account added to privileged role {{RoleName}}
alertDescriptionFormat: 'A user {{UserAdded}} was added to one of the Power Platform
administrative roles: {{{RoleName}}'
version: 3.2.1
Stages and Predicates
Parameters
let query_frequency = 1h;
let role_template_ids = dynamic(["44367163-eba1-44c3-98af-f5787879f96a", "11648597-926c-4cf3-9c36-bcebb0ba8dcc", "a9ea8996-122f-4c74-9520-8edcd192826c"]);
let monitored_activities = dynamic(["Assign", "AssignGrantedRole", "AssignPermanentGrantedRole", "AssignPermanentEligibleRole", "RoleElevatedOutsidePimAlert"]);
Stage 1: source
AuditLogs
Stage 2: where
| where TimeGenerated >= ago(query_frequency)
Stage 3: where
| where Category == "RoleManagement"
and TargetResources has_any (role_template_ids)
and AADOperationType in (monitored_activities)
and Identity != "MS-PIM" and Identity != "MS-PIM-Fairfax"
Stage 4: extend
| extend
UserPrincipalName = tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName),
AadUserId = tostring(parse_json(tostring(InitiatedBy.user)).id),
IPAddress = tostring(parse_json(tostring(InitiatedBy.user)).ipAddress),
RoleName = tostring(TargetResources[0].displayName),
UserAdded = tostring(TargetResources[2].userPrincipalName)
Stage 5: extend
| extend
RoleName = iif(isempty(RoleName), tostring(parse_json(tostring(TargetResources[0].modifiedProperties))[1].newValue), RoleName),
UserAdded = iif(isempty(UserAdded), tostring(parse_json(tostring(TargetResources[0].userPrincipalName))), UserAdded),
CloudAppId = int(32780),
AccountName = tostring(split(UserPrincipalName, '@')[0]),
UPNSuffix = tostring(split(UserPrincipalName, '@')[1])
Stage 6: project
| project
TimeGenerated,
Identity,
UserPrincipalName,
AadUserId,
RoleName,
OperationName,
UserAdded,
TargetResources,
CloudAppId,
AccountName,
UPNSuffix
Indicators
Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.
| Field | Kind | Values |
|---|---|---|
AADOperationType | in |
|
Category | eq |
|
Identity | ne |
|
TargetResources | match |
|
Output fields
Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.
| Field | Source |
|---|---|
AadUserId | project |
AccountName | project |
CloudAppId | project |
Identity | project |
OperationName | project |
RoleName | project |
TargetResources | project |
TimeGenerated | project |
UPNSuffix | project |
UserAdded | project |
UserPrincipalName | project |