Query Details

Audit Logs Application URI Added

Query

AuditLogs
| where Category == "ApplicationManagement" and AADOperationType == "Update" //and OperationName == "Update Application" and Result == "success"
| mv-expand modifiedProperty = TargetResources[0]["modifiedProperties"]
| extend ModifiedProperty = tostring(modifiedProperty["displayName"])
| where ModifiedProperty in ("AppIdentifierUri", "AppAddress")
| extend
    NewAddresses = iff(ModifiedProperty == "AppIdentifierUri", todynamic(tostring(modifiedProperty["newValue"])), extract_all(@'\"Address\"\:\"([^"]+)\"', tostring(modifiedProperty["newValue"]))),
    OldAddresses = iff(ModifiedProperty == "AppIdentifierUri", todynamic(tostring(modifiedProperty["oldValue"])), extract_all(@'\"Address\"\:\"([^"]+)\"', tostring(modifiedProperty["oldValue"])))
| where isnotempty(NewAddresses)
| extend AddedAddresses = set_difference(NewAddresses, OldAddresses)
| where array_length(AddedAddresses) > 0
| extend AppDisplayName = tostring(TargetResources[0]["displayName"])
| summarize
    TimeGenerated = min(TimeGenerated),
    AddedAddresses = array_sort_asc(make_set(AddedAddresses)),
    NewAddresses = array_sort_asc(make_set(NewAddresses)),
    OldAddresses = array_sort_asc(make_set(OldAddresses)),
    OperationNames = array_sort_asc(make_set(OperationName)),
    TargetResources = make_bag(bag_pack(Id, TargetResources)),
    OperationIds = make_list(Id),
    take_any(*)
    by CorrelationId, AppDisplayName, Result
| extend
    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"])
| mv-expand AddedAddress = AddedAddresses to typeof(string)
| project
    TimeGenerated,
    LoggedByService,
    Category,
    AADOperationType,
    Initiator = coalesce(Initiator, Identity),
    IPAddress,
    OperationNames,
    Result,
    AppDisplayName,
    AddedAddress,
    AddedAddresses,
    OldAddresses,
    NewAddresses,
    AdditionalDetails,
    InitiatedBy,
    InitiatorId,
    TargetResources,
    OperationIds,
    CorrelationId

Explanation

This KQL query is designed to analyze audit logs related to application management updates in Azure Active Directory (AAD). Here's a simplified breakdown of what the query does:

  1. Filter Logs: It starts by filtering the AuditLogs table to include only entries where the category is "ApplicationManagement" and the operation type is "Update".

  2. Expand Modified Properties: It expands the modifiedProperties of the first target resource to examine changes made to specific properties.

  3. Identify Relevant Changes: The query focuses on changes to the "AppIdentifierUri" and "AppAddress" properties.

  4. Extract New and Old Values: It extracts the new and old values of these properties, specifically looking for changes in addresses.

  5. Find Added Addresses: It identifies any new addresses that were added by comparing the new and old values.

  6. Filter for Changes: It filters the results to include only those entries where new addresses were added.

  7. Summarize Data: The query summarizes the data by correlation ID, application display name, and result, collecting various details such as the earliest time the change was generated, the added, new, and old addresses, operation names, and target resources.

  8. Identify Initiator: It determines who initiated the change, whether it was an application or a user, and captures their ID and IP address.

  9. Expand and Project Results: Finally, it expands the list of added addresses and projects a set of relevant columns, including the time the log was generated, the service that logged it, the category, operation type, initiator details, and the addresses involved in the change.

Overall, this query helps identify and analyze updates to application identifiers and addresses, highlighting any new addresses added during these updates.

Details

Jose Sebastián Canós profile picture

Jose Sebastián Canós

Released: August 8, 2025

Tables

AuditLogs

Keywords

AuditLogsApplicationManagementAppIdentifierUriAppAddressAppDisplayNameInitiatorInitiatorIdIPAddressOperationNamesResultTargetResourcesOperationIdsCorrelationId

Operators

AuditLogswhereandmv-expandextendtostringinifftodynamicextract_allisnotemptyset_differencearray_lengthsummarizeminarray_sort_ascmake_setmake_bagbag_packmake_listtake_anybyiifbag_keysprojectcoalesce

Actions

GitHub