Query Details

Audit Logs Changesto Application Ownership

Query

AuditLogs
| where LoggedByService == "Core Directory" and Category == "ApplicationManagement" and OperationName has "owner"
| mv-apply modifiedProperty = TargetResources[0]["modifiedProperties"] on (
    summarize modifiedProperties = make_bag(bag_pack(tostring(modifiedProperty["displayName"]), bag_pack("oldValue", trim(@'[\"\s]+', tostring(modifiedProperty["oldValue"])), "newValue", trim(@'[\"\s]+', tostring(modifiedProperty["newValue"])))))
    )
| extend
    OwnerId = TargetResources[0]["id"],
    Owner = TargetResources[0]["userPrincipalName"],
    AppDisplayName = tostring(modifiedProperties[case(OperationName has "application", "Application.DisplayName", OperationName has "service principal", "ServicePrincipal.DisplayName", "")][case(AADOperationType == "Assign", "newValue", AADOperationType == "Unassign", "oldValue", "")]),
    AppId = tostring(modifiedProperties[case(OperationName has "application", "Application.AppId", OperationName has "service principal", "ServicePrincipal.AppId", "")]["newValue"]),
    Initiator = iif(isnotempty(InitiatedBy["app"]), tostring(InitiatedBy["app"]["displayName"]), tostring(InitiatedBy["user"]["userPrincipalName"])),
    InitiatorId = iif(isnotempty(InitiatedBy["app"]), tostring(InitiatedBy["app"]["servicePrincipalId"]), tostring(InitiatedBy["user"]["id"])),
    IPAddress = tostring(InitiatedBy[tostring(bag_keys(InitiatedBy)[0])]["ipAddress"])
| project
    TimeGenerated,
    LoggedByService,
    Category,
    AADOperationType,
    Initiator,
    IPAddress,
    OperationName,
    Result,
    Owner,
    AppDisplayName,
    InitiatedBy,
    AdditionalDetails,
    TargetResources,
    InitiatorId,
    OwnerId,
    AppId,
    CorrelationId

Explanation

This KQL query is designed to analyze audit logs related to changes in application ownership within a directory service. Here's a simplified breakdown of what the query does:

  1. Filter Logs: It starts by filtering audit logs to include only those entries where the service that logged the event is "Core Directory," the category is "ApplicationManagement," and the operation name contains the word "owner."

  2. Extract and Summarize Changes: For each log entry, it examines the modified properties of the target resources. It creates a summary of these changes, focusing on the display name, old value, and new value of the modified properties.

  3. Extend Information: The query then extracts additional details from the logs:

    • OwnerId and Owner: Identifies the ID and user principal name of the owner.
    • AppDisplayName and AppId: Determines the display name and ID of the application or service principal involved, based on the operation type (assign or unassign).
    • Initiator and InitiatorId: Identifies who initiated the change, whether it's an application or a user, and captures their display name and ID.
    • IPAddress: Captures the IP address from which the change was initiated.
  4. Project Relevant Fields: Finally, it selects and displays a set of relevant fields from the logs, including:

    • TimeGenerated: When the log entry was created.
    • LoggedByService, Category, AADOperationType, OperationName, Result: Basic details about the log entry.
    • Initiator, IPAddress, Owner, AppDisplayName: Information about the change and the entities involved.
    • AdditionalDetails, TargetResources, InitiatedBy, InitiatorId, OwnerId, AppId, CorrelationId: Additional context and identifiers related to the log entry.

Overall, this query is used to track and analyze changes in application ownership, providing insights into who made the changes, what was changed, and when it happened.

Details

Jose Sebastián Canós profile picture

Jose Sebastián Canós

Released: August 8, 2025

Tables

AuditLogs

Keywords

AuditLogsCoreDirectoryApplicationManagementOwnerApplicationServicePrincipalDisplayNameAppIdUserPrincipalNameInitiatedByIPAddressTargetResourcesCorrelationId

Operators

AuditLogswhereandhasmv-applysummarizemake_bagbag_packtostringtrim@extendcaseiifisnotemptyprojectbag_keys

Actions

GitHub