Dude, Where’s My Audit Logs?

Audit logs can provide all sorts of wonderful points of data. In the interest of identity security, we have historically seen that we can glean rich sets of information around what’s happening in a directory service with some properly functioning audit logging. For many identity practitioners, there is the expectation that while we may not always look at the audit logs or their details, if or when we need them, they’ll be there to help us understand whatever it is we are investigating. Same goes for compliance and auditing as well.

Considering that customers have no ability to impact what or how auditing happens in Entra ID, in the shared responsibility model, it’s on Microsoft to ensure all events are audited.

Shared responsiblity model, courtesy Microsoft, with identity and directory infrastructure highlighted.

Microsoft documents what is audited in Entra ID, which you can find here, Azure Active Directory (Azure AD) audit activity reference – Microsoft Entra | Microsoft Learn.

The Problem

I’ve recently been down the rabbit hole part time picking apart Entra ID audit logs, and in my analysis of the audit log data for Entra ID, some audit logs slot into one of two buckets:

  • Data is missing
  • Data is inconsistent/poor quality
Or perhaps in our case, what has been unseen cannot be seen.

To be fair, a broad set of changes are auditing in Entra ID, but at the same time I found it rather surprising that most SSPR configuration changes are not properly audited, which, if you look at the document above, Microsoft does not seem to argue. Considering recent events that surface what is logged in Entra ID and the M365 ecosystem, in this persons opinion Microsoft should be continually striving to audit 100% of all configuration changes in Entra ID.

Missing Log Data

These are instances where Entra ID log data is incomplete, usually in that the modified properties data is null.

Self-service Group Management

Neither of these settings are exposed via the Graph API, so the reference point for their control is under Entra ID -> Groups -> Group settings

The Audit Data

Note an absence of the actual change data, as highlighted in the audit event:

{
        "activityDateTime": "2023-08-07T20:04:39.1390262+00:00",
        "activityDisplayName": "Update authorization policy",
        "additionalDetails": [
            {
                "key": "User-Agent",
                "value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/116.0"
            }
        ],
        "category": "AuthorizationPolicy",
        "correlationId": "1349713e-116b-4246-9c64-60b394884488",
        "id": "Directory_1349713e-116b-4246-9c64-60b394884488_NANEA_29121908",
        "initiatedBy": {
            "user": {
                "displayName": null,
                "homeTenantId": null,
                "homeTenantName": null,
                "id": "d7148226-7444-4884-aef7-b5fe693a6798",
                "ipAddress": "X.X.X.X",
                "userPrincipalName": "ga-x@x.onmicrosoft.com"
            }
        },
        "loggedByService": "Core Directory",
        "result": "success",
        "resultReason": "",
        "targetResources": [
            {
                "displayName": "Authorization Policy",
                "groupType": null,
                "id": "4bb7b039-71e4-474e-a7fc-5fe0bbf86fcc",
                "modifiedProperties": [
                    {
                        "displayName": "Included Updated Properties",
                        "newValue": "\"\"",
                        "oldValue": null
                    }
                ],
                "type": "Other",
                "userPrincipalName": null
            }
        ],
        "userAgent": null
    },

Group Lifecycle Policy Changes

More commonly known as the group expiration settings, the controls for these in the portal can be found under Groups -> Group settings -> Expiration.

These are also exposed through Graph, https://graph.microsoft.com/beta/groupLifecyclePolicies/.

The Audit Data

Note the absence of any change data, as highlighted in the audit event:

{
        "activityDateTime": "2023-08-07T20:09:38.6970558+00:00",
        "activityDisplayName": "Update lifecycle management policy",
        "additionalDetails": [
        ],
        "category": "GroupManagement",
        "correlationId": "8883b045-774b-4107-b85a-04df5252b5ad",
        "id": "SSGM_8883b045-774b-4107-b85a-04df5252b5ad_KLKOT_36197055",
        "initiatedBy": {
            "user": {
                "displayName": null,
                "homeTenantId": null,
                "homeTenantName": null,
                "id": "d7148226-7444-4884-aef7-b5fe693a6798",
                "ipAddress": "X.X.X.x",
                "userPrincipalName": "ga-x@x.onmicrosoft.com"
            }
        },
        "loggedByService": "Self-service Group Management",
        "result": "success",
        "resultReason": "OK",
        "targetResources": [
            {
                "displayName": null,
                "groupType": null,
                "id": "57126178-623b-4468-a96e-be2ee1611cc4",
                "modifiedProperties": [
                ],
                "type": "Policy",
                "userPrincipalName": null
            }
        ],
        "userAgent": null
    },

Conditional Access Custom Controls

Now I get that this is a deprecated public preview, but, it’s also existed for quite a long time, and it’s surprising that changes to the control itself are not audited.

The Audit Data

Note the absence of any change data, as highlighted in the audit event:

{
        "activityDateTime": "2023-08-07T20:18:39.6114596+00:00",
        "activityDisplayName": "Update policy",
        "additionalDetails": [
        ],
        "category": "Policy",
        "correlationId": "21476eae-1b3f-45db-8e3e-e190cd19ad44",
        "id": "Directory_21476eae-1b3f-45db-8e3e-e190cd19ad44_USKAS_28366729",
        "initiatedBy": {
            "user": {
                "displayName": null,
                "homeTenantId": null,
                "homeTenantName": null,
                "id": "d7148226-7444-4884-aef7-b5fe693a6798",
                "ipAddress": "X.X.X.X",
                "userPrincipalName": "ga-x@x.onmicrosoft.com"
            }
        },
        "loggedByService": "Core Directory",
        "result": "success",
        "resultReason": "",
        "targetResources": [
            {
                "displayName": "Default Policy",
                "groupType": null,
                "id": "77a1c6e8-877e-43fe-a4d0-0806472fe4a0",
                "modifiedProperties": [
                    {
                        "displayName": "Included Updated Properties",
                        "newValue": "\"\"",
                        "oldValue": null
                    }
                ],
                "type": "Policy",
                "userPrincipalName": null
            }
        ],
        "userAgent": null
    },

SSPR/Password Reset Settings

Microsoft documents that most changes to SSPR are not audited, and in my analysis found that the following settings do not properly reflect any data in the audit logs, including a few that Microsoft seems to indicate should, such as enabling/disabling on-premises integration.

Considering that these changes impact tenant-wide security controls around SSPR, it’s surprising this service has existed for so long with what is effectively non-existent auditing. These logs don’t even indicate who initiated the change.

Yes, some of these are being overhauled/changed as authentication methods is an area of focus for Microsoft right now, but not all of these settings are encompassed in that.

  • Registration, Days before users are asked to re-confirm their settings
  • Notification settings
  • Customizations
  • On-premises integration
  • Self-service password reset enablement/scoping
  • Authentication methods (legacy methods)

The Audit Data

In testing, there isn’t even a direct audit event logged for changes, but simply an update to the Microsoft password reset service service principle. The update provides no information on the actual change.

{
        "activityDateTime": "2023-08-07T20:28:04.2244435+00:00",
        "activityDisplayName": "Update service principal",
        "additionalDetails": [
            {
                "key": "AppId",
                "value": "93625bc8-bfe2-437a-97e0-3d0060024faa"
            }
        ],
        "category": "ApplicationManagement",
        "correlationId": "aae6519f-15d9-4dec-9d12-a03b2639c60e",
        "id": "Directory_aae6519f-15d9-4dec-9d12-a03b2639c60e_F0I2G_33925192",
        "initiatedBy": {
            "app": {
                "appId": null,
                "displayName": "Microsoft password reset service",
                "servicePrincipalId": "a96c060c-dd1c-4229-9089-72aed43d85db",
                "servicePrincipalName": null
            }
        },
        "loggedByService": "Core Directory",
        "result": "success",
        "resultReason": "",
        "targetResources": [
            {
                "displayName": "Microsoft password reset service",
                "groupType": null,
                "id": "a96c060c-dd1c-4229-9089-72aed43d85db",
                "modifiedProperties": [
                    {
                        "displayName": "TargetId.ServicePrincipalNames",
                        "newValue": "\"https://passwordreset.microsoftonline.com;https://passwordreset.microsoftonline.com/;93625bc8-bfe2-437a-97e0-3d0060024faa\"",
                        "oldValue": null
                    }
                ],
                "type": "ServicePrincipal",
                "userPrincipalName": null
            }
        ],
        "userAgent": null
    },

External Identities Linked Subscriptions

Microsoft has been pushing the migration of B2B guests/External Identities to use a linked subscription where organizations will receive 50,000 MAU for guests as far as licensing goes, compared to the prior model of a 1:5 user: guest license ratio.

In order to implement this change, an organization must link their Entra ID tenant with an Azure subscription for billing purposes.

When implementing this change, there is a proper audit even in the subscriptions activity log, however, a change like this should also be reflected in Entra ID audit logs. Instead, we get a series of useless audit log entries.

The Audit Data

When looking at the data in either entry for Create or update a Guest Usages resource, there is no data of value for the change.

{
        "activityDateTime": "2023-08-07T20:38:06.5858394+00:00",
        "activityDisplayName": "Create or update a Guest Usages resource",
        "additionalDetails": [
            {
                "key": "targetTenant",
                "value": "Undefined tenant"
            },
            {
                "key": "targetEntityType",
                "value": "Resource"
            },
            {
                "key": "actorIdentityType",
                "value": "UPN"
            }
        ],
        "category": "ResourceManagement",
        "correlationId": "dda8b5c0-125d-4fc6-b8aa-971e9cb27f9a",
        "id": "B2C_dda8b5c0-125d-4fc6-b8aa-971e9cb27f9a_VUR48_6835487",
        "initiatedBy": {
            "user": {
                "displayName": "ga-x@x.onmicrosoft.com",
                "homeTenantId": null,
                "homeTenantName": null,
                "id": null,
                "ipAddress": "X.X.X.X",
                "userPrincipalName": "ga-x@x.onmicrosoft.com"
            }
        },
        "loggedByService": "B2C",
        "result": "success",
        "resultReason": null,
        "targetResources": [
            {
                "displayName": "NotSet",
                "groupType": null,
                "id": null,
                "modifiedProperties": [
                ],
                "type": "Directory",
                "userPrincipalName": null
            }
        ],
        "userAgent": null
    },

External Collaboration Settings Guest Self-service sing up via user flows

Guest self-service sign-up (SSSU) is what one could consider a grey area in the B2B/B2C space, allowing users to self-register as guests in your tenant and access designated resources. While a somewhat niche feature, it’s something that is rather powerful for controlling access to enterprise applications.

This setting can also be adjusted via Graph at https://graph.microsoft.com/v1.0/policies/authenticationFlowsPolicy.

Surprisingly, changes that enable/disable this setting are not audited effectively.

The Audit Data

Toggling this on/off results in a long series of audit events from the B2C service, however, none of them actually indicate the change.

For all of these, the Modified Properties is null

{
        "activityDateTime": "2023-08-07T20:49:50.9366119+00:00",
        "activityDisplayName": "Update authentication flows policy",
        "additionalDetails": [
            {
                "key": "targetTenant",
                "value": "Undefined tenant"
            },
            {
                "key": "targetEntityType",
                "value": "None"
            },
            {
                "key": "actorIdentityType",
                "value": "UPN"
            }
        ],
        "category": "ResourceManagement",
        "correlationId": "923307cf-b8ac-4e26-bd47-53650a88e9fb",
        "id": "B2C_923307cf-b8ac-4e26-bd47-53650a88e9fb_VUR48_6870123",
        "initiatedBy": {
            "user": {
                "displayName": "ga-x@x.onmicrosoft.com",
                "homeTenantId": null,
                "homeTenantName": null,
                "id": null,
                "ipAddress": "X.X.X.X",
                "userPrincipalName": "ga-x@x.onmicrosoft.com"
            }
        },
        "loggedByService": "B2C",
        "result": "success",
        "resultReason": null,
        "targetResources": [
            {
                "displayName": null,
                "groupType": null,
                "id": "NotSet",
                "modifiedProperties": [
                ],
                "type": "Other",
                "userPrincipalName": null
            }
        ],
        "userAgent": null
    },

Inconsistent Log Data

These are instances where changes are audited, however, they seem to disregard any sort of schema or consistency of auditing in Entra ID.

Entra ID Protection

Entra ID Protection heavily offenses the senses with it’s audit logging of changes to the following policies:

  • User risk policy
  • Sign-in risk policy
  • Multifactor authentication registration policy

We could argue that you shouldn’t be using the MFA registration policy at this point, as MFA should be an account day zero requirement. And while Microsoft wants you to move your ID Protection policies into Conditional Access, until they are gone, the changes really break the audit mold.

The Audit Data

Oddly the user risk policy and MFA registration policy indicate an update if either is changed, and updates to the sign-in risk policy appear separate. But for all three, two events are logged, a core directory change that contains no data, and secondary policy change, that oddly describes the change data under Status reason, which is highlighted in blue below. Where one should/would expect the change to appear is highlighted in yellow.

    {
        "activityDateTime": "2023-08-30T03:00:57.8173676+00:00",
        "activityDisplayName": "Update Sign-In Risk Policy",
        "additionalDetails": [
        ],
        "category": "Policy",
        "correlationId": "bcda8418-f5f0-42f4-a8c1-cc809be64050",
        "id": "ADIbizaUX_bcda8418-f5f0-42f4-a8c1-cc809be64050_MZXCC_6463221",
        "initiatedBy": {
            "user": {
                "displayName": null,
                "homeTenantId": null,
                "homeTenantName": null,
                "id": "d7148226-7444-4884-aef7-b5fe693a6798",
                "ipAddress": "X.X.X.X",
                "userPrincipalName": "ga-x@x.onmicrosoft.com"
            }
        },
        "loggedByService": "AAD Management UX",
        "result": "success",
        "resultReason": "Set sign-in risk policy successful. Enabled: True. Risk level for MFA: Never. Risk level for block: High. Include All Users: False. Include Users: 788aff42-e628-4ff9-8e17-a207350ed80b. Include Groups: . Exclude All Users: False. Exclude Users . Exclude Groups ",
        "targetResources": [
            {
                "displayName": "Sign-In Risk Policy",
                "groupType": null,
                "id": "5bf6637e-056a-4f1c-b887-6c7e99ed5ac6",
                "modifiedProperties": [
                ],
                "type": "Policy",
                "userPrincipalName": null
            }
        ],
        "userAgent": ""
    },
    {
        "activityDateTime": "2023-08-30T03:00:57.181057+00:00",
        "activityDisplayName": "Update policy",
        "additionalDetails": [
            {
                "key": "User-Agent",
                "value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/116.0"
            }
        ],
        "category": "Policy",
        "correlationId": "b06b42f1-4723-45bb-b205-59eae5ab7da3",
        "id": "Directory_b06b42f1-4723-45bb-b205-59eae5ab7da3_FYNFV_398999217",
        "initiatedBy": {
            "user": {
                "displayName": null,
                "homeTenantId": null,
                "homeTenantName": null,
                "id": "d7148226-7444-4884-aef7-b5fe693a6798",
                "ipAddress": "X.X.X.X",
                "userPrincipalName": "ga-x@x.onmicrosoft.com"
            }
        },
        "loggedByService": "Core Directory",
        "result": "success",
        "resultReason": "",
        "targetResources": [
            {
                "displayName": "Sign-In Risk Policy",
                "groupType": null,
                "id": "5bf6637e-056a-4f1c-b887-6c7e99ed5ac6",
                "modifiedProperties": [
                    {
                        "displayName": "Included Updated Properties",
                        "newValue": "\"\"",
                        "oldValue": null
                    }
                ],
                "type": "Policy",
                "userPrincipalName": null
            }
        ],
        "userAgent": null
    },

Responsible Disclosure

After consideration and reading of what constitutes a security vulnerability at the Microsoft Security Response Center (MSRC), I do not believe that these deficiencies in auditing would be considered a security vulnerability, as the absense of audit data itself is not a vulnerability.

On July 26th, 2023, through an MVP channel in the Customer Connected Program Entra Advisors, I reached out to the Microsoft Entra Product Group wanting to provide feedback on what I believe are audit gaps in Entra ID.

After some exchanges to coordinate whom to send the feedback to, on August 7th I provided an email to the responsible parties in the PG covering audit logging. Microsoft did reply that they will investigate in response. Considering that this is not a security vulnerability, I do not believe there is harm in publishing this material prior to any (if any) changes occur on the part of Microsoft.

A case with Microsoft support has not been opened on this subject to this point, on which I would open one if directed by the PG.

Regarding Audit Log Analysis

In my endeavors to this point, I have not analyzed all audit log events in Entra ID, so there may still be additional gaps in what one might find to be acceptable auditing. While Microsoft may contend that they indicate in their own docs that some of these changes are not listed as being audited, I would counter that with the stances that every single configuration change in Entra ID should be audited and adhere to some sort of audit log schema for consistency.

About This Posts Featured Image

The chosen photo is the work of David Clode, used under the Unsplash license.

Eric Woodruff
Eric Woodruff

Leave a Reply

Your email address will not be published. Required fields are marked *

Author picture

Writing about all things identity and identity adjacent in the Microsoft ecosystem of Azure AD and Active Directory.

Read More
Mailing List

Subscribe to posts here

Categories