↳ Source GitHubRègle analytiqueMedium
Power Apps - Bulk sharing of Power Apps to newly created guest users
Description
Identifies unusual bulk sharing, based on a predefined threshold in the query, of Power Apps to newly created Microsoft Entra guest users.
- Type de règle
- Scheduled
- Version
- 3.2.0
- Statut déclaré
- Available
- Fréquence
- 1h
- Période analysée
- 14d
- Déclenchement
- gt 0
Couverture MITRE déclarée
Sources déclarées
Métadonnées du fichier source. Aucune dépendance déduite du KQL.
Connecteurs
Types de données
Requête KQL
Requête originale, sans modification.
////////////
// threshold = If the number of unique accounts that a power app is shared with is greater than
// threshold than it'll trigger an alert. A threshold of 5 is good to start with.
// However, if this is giving too many false positives, please adjust the threshold.
////////////
let threshold = 5;
////////////
// Please replace the allowed_domains with a list of domains of your partners/sibling orgs
// with whom you generally share power apps with. This will allow us to filter
// legitimate bulk sharing attempts. Avoid using domains such as gmail, outlook, etc.
///////////
let allowed_domains = pack_array("contoso.com");
let query_frequency = 1h;
let query_lookback = 14d;
PowerPlatformAdminActivity
| where TimeGenerated >= ago(query_frequency)
| where EventOriginalType == "PowerAppPermissionEdited"
| extend Properties = tostring(PropertyCollection)
| extend AppId = extract(@'"powerplatform.analytics.resource.power_app.id","Value":"([^"]+)"', 1, Properties)
| extend AppId = tolower(replace_string(AppId, '/providers/Microsoft.PowerApps/apps/', ''))
| extend TargetPrincipalId = extract(@'"targetuser.id","Value":"([^"]+)"', 1, Properties)
| join kind=leftouter (
AuditLogs
| where ActivityDateTime >= ago(query_lookback)
| where SourceSystem =~ "Azure AD" and OperationName == "Invite external user"
| where Result =~ "success"
| extend InvitedOrgEmail = tostring(parse_json(AdditionalDetails[5])['value'])
| extend InvitedOrgDomain = tostring(split(InvitedOrgEmail, "@")[1])
| where not(InvitedOrgDomain has_any(allowed_domains))
| extend
InvitedById = tostring(parse_json(InitiatedBy)['user']['id']),
InvitedByUPN = tostring(parse_json(InitiatedBy)['user']['userPrincipalName']),
InvitedEmail = tostring(parse_json(TargetResources[0])['userPrincipalName']),
InvitedId = tostring(parse_json(TargetResources[0])['id'])
| summarize by InvitedById, InvitedByUPN, InvitedEmail, InvitedId, InvitedOrgDomain)
on $left.TargetPrincipalId == $right.InvitedId
| where isnotempty(InvitedId)
| summarize
StartTime = min(TimeGenerated),
EndTime = max(TimeGenerated),
TargetedUsersCount=dcount(TargetPrincipalId),
TargetedObjectIds = make_set(TargetPrincipalId, 1000),
InvitedDomains = make_set(InvitedOrgDomain, 1000),
InvitedEmailAddresses = make_set(InvitedEmail, 1000)
by AppId, InvitedById, InvitedByUPN
| extend
PowerAppsEntityId = 27593,
AccountName = tostring(split(InvitedByUPN, '@')[0]),
UPNSuffix = tostring(split(InvitedByUPN, '@')[1])
| project
StartTime,
EndTime,
InvitedByUPN,
InvitedById,
InvitedDomains,
InvitedEmailAddresses,
TargetedUsersCount,
TargetedObjectIds,
AppId,
PowerAppsEntityId,
AccountName,
UPNSuffix
Entités déclarées
Contenus associés
Liens établis à partir des identifiants déclarés et des manifests des solutions.
Traçabilité de la source
GitHubLes valeurs affichées proviennent des fichiers du dépôt Azure/Azure-Sentinel. Elles décrivent le modèle publié, pas la configuration de votre workspace.
- Commit
7ca9800↗- Identifiant source
943acfa0-9285-4eb0-a9c0-42e36177ef19
GSTEP / SUIVI DU CATALOGUE
Ajouté au catalogue : 16 sept. 2026 · 05:49 UTC
Dernier changement observé : 16 sept. 2026 · 05:49 UTC