Query Details

Workload Identity Info Enriched By Entra Ops

Query

id: 1225bb11-96d0-40f0-9ad7-b460042e0a52
Function:
  Title: Parser for WorkloadIdentityInfo with enriched classification of EntraOps
  Version: '1.0.0'
  LastUpdated: '2023-11-11'
Category: Microsoft Sentinel Parser
FunctionName: PrivilegedWorkloadIdentityInfo
FunctionAlias: PrivilegedWorkloadIdentityInfo
FunctionQuery: |
        let SensitiveMsGraphPermissions = externaldata(EAMTierLevelName: string, Category: string, AppRoleDisplayName: string)["https://raw.githubusercontent.com/Cloud-Architekt/AzurePrivilegedIAM/main/Classification/Classification_AppRoles.json"] with(format='multijson');
        let SensitiveAadDirectoryRoles = externaldata(Classification: string, RolePermissions: string, Category: string, RoleId: string)["https://raw.githubusercontent.com/Cloud-Architekt/AzurePrivilegedIAM/main/Classification/Classification_EntraIdDirectoryRoles.json"] with(format='multijson') | mv-expand parse_json(RolePermissions)
        | summarize Category = make_list(RolePermissions.Category) by AadDirectoryRoleId = RoleId, AadDirectoryRoleTierLevel = tostring(parse_json(Classification).EAMTierLevelName);
        let SpWithAppRole = _GetWatchlist('WorkloadIdentityInfo')
        | mv-expand parse_json(AssignedAppRoles)
        | extend AppRoleDisplayName = tostring(AssignedAppRoles.AppRoleDisplayName)
        | extend ResourceDisplayName = tostring(AssignedAppRoles.ResourceDisplayName)
        | join kind=leftouter(
            SensitiveMsGraphPermissions | project AppRolePermissionTierLevel = EAMTierLevelName, Category, AppRoleDisplayName, ResourceDisplayName = "Microsoft Graph"
            ) on AppRoleDisplayName, ResourceDisplayName
        | where isnotempty(AppRoleDisplayName)    
        | summarize AppRolePermissions = make_set(AppRoleDisplayName), AppRolePermissionTierLevels = make_set(AppRolePermissionTierLevel) by ServicePrincipalObjectId;
        let SpWithDirectoryRole = _GetWatchlist('WorkloadIdentityInfo')
        | mv-expand parse_json(AssignedRoles)
        | extend AadDirectoryRoleId = tostring(AssignedRoles.RoleDefinitionId)
        | extend AadDirectoryRoleName = tostring(AssignedRoles.RoleDefinitionName)
        | join kind=leftouter(
            SensitiveAadDirectoryRoles
            ) on AadDirectoryRoleId
        | where isnotempty(AadDirectoryRoleName)    
        | summarize AadDirectoryRoles = make_set(AadDirectoryRoleName), AadDirectoryRoleTierLevels = make_set(AadDirectoryRoleTierLevel) by ServicePrincipalObjectId;
        _GetWatchlist('WorkloadIdentityInfo')
        | join kind=leftouter (
            union SpWithAppRole, SpWithDirectoryRole
            | summarize AppRolePermissions = make_set(AppRolePermissions), AppRolePermissionTierLevels = make_set(AppRolePermissionTierLevels), AadDirectoryRoles = make_set(AadDirectoryRoles), AadDirectoryRoleTierLevels = make_set(AadDirectoryRoleTierLevels) by ServicePrincipalObjectId
            ) on ServicePrincipalObjectId
        | extend Classification = iif((AppRolePermissionTierLevels contains "ControlPlane" or AadDirectoryRoleTierLevels contains "ControlPlane"), "ControlPlane", "Unclassified")
        | extend Classification = iif((Classification == "Unclassified" and (AppRolePermissionTierLevels contains "ManagementPlane" or AadDirectoryRoleTierLevels contains "ManagementPlane")), "ManagementPlane", Classification)
        | extend Classification = iif((Classification == "Unclassified" and (AppRolePermissionTierLevels contains "WorkloadPlane" or AadDirectoryRoleTierLevels contains "WorkloadPlane")), "WorkloadPlane", Classification)
        | extend Classification = iif((Classification == "Unclassified" and (AppRolePermissionTierLevels contains "UserAccess" or AadDirectoryRoleTierLevels contains "UserAccess")), "UserAccess", Classification)
        | project 
            WorkloadIdentityName = AppDisplayName,
            WorkloadIdentityType = ServicePrincipalType,
            IsFirstPartyApp,
            SignInAudience,
            UserAssignmentRequired,
            ServicePrincipalObjectId,
            ApplicationObjectId = tostring(AppObjectId),
            ApplicationId = AppId,
            EntraIdRoles = AadDirectoryRoles,
            AppRolePermissions,
            EnterpriseAccessModelTiering = Classification

Explanation

The query is a parser for workload identity information with enriched classification of EntraOps. It retrieves sensitive Microsoft Graph permissions and sensitive Azure AD directory roles from external data sources. It then joins this data with the workload identity information to determine the classification of the workload identity. The classification is based on the permissions and roles assigned to the workload identity, and it is categorized into ControlPlane, ManagementPlane, WorkloadPlane, or UserAccess. The query also projects various attributes of the workload identity, such as its name, type, first-party status, sign-in audience, user assignment requirement, and enterprise access model tiering.

Details

Thomas Naunheim profile picture

Thomas Naunheim

Released: November 11, 2023

Tables

SensitiveMsGraphPermissionsSensitiveAadDirectoryRoles

Keywords

Devices,Intune,User,MicrosoftSentinelParser

Operators

letexternaldatawithformatmv-expandsummarizeextendjoinprojectisnotemptymake_listtostringparse_jsonmake_setiifcontainsunioniif=="ControlPlane""Unclassified""ManagementPlane""WorkloadPlane""UserAccess""AppDisplayName""ServicePrincipalType""IsFirstPartyApp""SignInAudience""UserAssignmentRequired""ServicePrincipalObjectId""AppObjectId""AppId""AadDirectoryRoles""AppRolePermissions""Classification"

Actions