Troubleshooting Conditional Access policy changes

The Azure Active Directory (Azure AD) audit log is a valuable source of information when troubleshooting why and how Conditional Access policy changes happened in your environment.

Audit log data is only kept for 30 days by default, which may not be long enough for every organization. Organizations can store data for longer periods by changing diagnostic settings in Azure AD to:

  • Send data to a Log Analytics workspace
  • Archive data to a storage account
  • Stream data to Event Hubs
  • Send data to a partner solution

Find these options in the Azure portal > Azure Active Directory, Diagnostic settings > Edit setting. If you don't have a diagnostic setting, follow the instructions in the article Create diagnostic settings to send platform logs and metrics to different destinations to create one.

Use the audit log

  1. Sign in to the Azure portal as a Conditional Access Administrator, Security Administrator, or Global Administrator.

  2. Browse to Azure Active Directory > Audit logs.

  3. Select the Date range you want to query.

  4. From the Service filter, select Conditional Access and select the Apply button.

    The audit logs display all activities, by default. Open the Activity filter to narrow down the activities. For a full list of the audit log activities for Conditional Access, see the Audit log activities.

  5. Select a row to view the details. The Modified Properties tab lists the modified JSON values for the selected audit activity.

Audit log entry showing old and new JSON values for Conditional Access policy

Use Log Analytics

Log Analytics allows organizations to query data using built in queries or custom created Kusto queries, for more information, see Get started with log queries in Azure Monitor.

Log Analytics query for updates to Conditional Access policies showing new and old value location

Once enabled find access to Log Analytics in the Azure portal > Azure AD > Log Analytics. The table of most interest to Conditional Access administrators is AuditLogs.

AuditLogs 
| where OperationName == "Update conditional access policy"

Changes can be found under TargetResources > modifiedProperties.

Reading the values

The old and new values from the audit log and Log Analytics are in JSON format. Compare the two values to see the changes to the policy.

Old policy example:

{
    "conditions": {
        "applications": {
            "applicationFilter": null,
            "excludeApplications": [
            ],
            "includeApplications": [
                "797f4846-ba00-4fd7-ba43-dac1f8f63013"
            ],
            "includeAuthenticationContextClassReferences": [
            ],
            "includeUserActions": [
            ]
        },
        "clientAppTypes": [
            "browser",
            "mobileAppsAndDesktopClients"
        ],
        "servicePrincipalRiskLevels": [
        ],
        "signInRiskLevels": [
        ],
        "userRiskLevels": [
        ],
        "users": {
            "excludeGroups": [
                "eedad040-3722-4bcb-bde5-bc7c857f4983"
            ],
            "excludeRoles": [
            ],
            "excludeUsers": [
            ],
            "includeGroups": [
            ],
            "includeRoles": [
            ],
            "includeUsers": [
                "All"
            ]
        }
    },
    "displayName": "Common Policy - Require MFA for Azure management",
    "grantControls": {
        "builtInControls": [
            "mfa"
        ],
        "customAuthenticationFactors": [
        ],
        "operator": "OR",
        "termsOfUse": [
            "a0d3eb5b-6cbe-472b-a960-0baacbd02b51"
        ]
    },
    "id": "334e26e9-9622-4e0a-a424-102ed4b185b3",
    "modifiedDateTime": "2021-08-09T17:52:40.781994+00:00",
    "state": "enabled"
}

Updated policy example:

{
    "conditions": {
        "applications": {
            "applicationFilter": null,
            "excludeApplications": [
            ],
            "includeApplications": [
                "797f4846-ba00-4fd7-ba43-dac1f8f63013"
            ],
            "includeAuthenticationContextClassReferences": [
            ],
            "includeUserActions": [
            ]
        },
        "clientAppTypes": [
            "browser",
            "mobileAppsAndDesktopClients"
        ],
        "servicePrincipalRiskLevels": [
        ],
        "signInRiskLevels": [
        ],
        "userRiskLevels": [
        ],
        "users": {
            "excludeGroups": [
                "eedad040-3722-4bcb-bde5-bc7c857f4983"
            ],
            "excludeRoles": [
            ],
            "excludeUsers": [
            ],
            "includeGroups": [
            ],
            "includeRoles": [
            ],
            "includeUsers": [
                "All"
            ]
        }
    },
    "displayName": "Common Policy - Require MFA for Azure management",
    "grantControls": {
        "builtInControls": [
            "mfa"
        ],
        "customAuthenticationFactors": [
        ],
        "operator": "OR",
        "termsOfUse": [
        ]
    },
    "id": "334e26e9-9622-4e0a-a424-102ed4b185b3",
    "modifiedDateTime": "2021-08-09T17:52:54.9739405+00:00",
    "state": "enabled"
}

In the example above, the updated policy doesn't include terms of use in grant controls.

Restoring Conditional Access policies

For more information about programmatically updating your Conditional Access policies using the Microsoft Graph API, see the article Conditional Access: Programmatic access.

Next steps