top of page

Mastering Microsoft Entra Authentication Contexts - Part 4: Monitoring and Reporting with KQL & M365IdentityPosture

  • Writer: Sebastian F. Markdanner
    Sebastian F. Markdanner
  • 6 hours ago
  • 8 min read

We’ve covered what Authentication Contexts are, why they matter, and how they help us strengthen access and data security in Microsoft 365.

Now it’s time to answer the next question - how do we monitor and report on their usage?

Woman analyzing data on a computer with a security shield icon. Text: "Monitoring Microsoft Entra Authentication Contexts (Part 4)." Night sky backdrop.

Unfortunately, there’s no built-in way to gain that visibility today. Neither Entra ID nor Microsoft 365 provides a simple method to inventory or audit Authentication Contexts across our estate including Conditional Access, PIM and Sensitivity labels.


To close that gap, I built a small PowerShell module called M365IdentityPosture.

A project aimed at becoming a unified reporting toolkit for Microsoft Cloud identity and security. Its first feature focuses specifically on Authentication Context reporting, giving you a clear view of which contexts exist, where they’re used, and what they're configured for.


In this post, we’ll explore how to report on and monitor authentication use across our environments, including using the module to generate an Authentication Context Inventory Report, and how to gain (limited) insights using KQL.


Let's jump in!


Table of Contents

  1. Why Monitor Microsoft Entra Authentication Contexts?

  2. Documenting Deployed Microsoft Entra Authentication Contexts

  3. Monitoring Usage of Authentication Contexts Using KQL

  4. Conclusion: From Configuration to Clarity


Why Monitor Microsoft Entra Authentication Contexts?

As with anything in our environment, there are many reasons to monitor authentication contexts.

These include tracking configuration drift, maintaining documentation, meeting compliance or regulatory requirements, simplifying administrative tasks, and monitoring license utilization.


With Microsoft Cloud’s growing support for authentication contexts, it’s becoming increasingly important to track where they’re deployed and to keep documentation up to date, helping prevent unexpected or breaking changes.


Additionally, by using KQL, we can query sign-in logs to see how often users are prompted to meet the authentication requirements defined by these contexts.



Microsoft Entra Authentication Context Report & Monitor Use-Case

Let’s take a look at a few real-world examples.


Example 1

Contoso hires a new administrator, John Smith.

John is tasked with documenting the deployment and usage of the company’s 32 authentication contexts to meet regulatory compliance requirements that mandate full documentation of all IAM configurations.


Over the years, these authentication contexts were created by multiple admins - some current, some long gone - with no consistent naming conventions, descriptions, or documentation.


To complete the task, John faces digging through various logs, policies, and admin portals, a process that could take hours or even days just to understand how each context is used and by whom.



Example 2

Over time, Contoso’s Conditional Access landscape has evolved.

New authentication contexts have been created and added to policies to support various business needs - some temporary, some experimental - but not all were properly documented or reviewed afterward.


The security team begins to notice inconsistencies between what’s believed to be configured and what’s actually in use. Some authentication contexts appear linked to no active policy, while others are enforced in unexpected scenarios.


Without centralized reporting, identifying which contexts are still relevant, duplicated, or orphaned becomes a slow and tedious manual process.



Documenting Deployed Microsoft Entra Authentication Contexts

As mentioned earlier, documentation and reporting on where each authentication context is deployed can be a pain point for many organizations.


To help ease that pain, I’m introducing the first capability of M365IdentityPosture - the Authentication Context Inventory Report.

This interactive HTML report provides a clear overview of all existing authentication contexts within a tenant, including where they’re used.


Before we dive into the actual report, there’s one caveat to keep in mind:

It’s currently not possible to programmatically collect Microsoft Defender for Cloud Apps (MDCA) Session Policies that use the Require step-up authentication (Auth context) setting. Because of that limitation, these policies aren’t included in the current version of the report.


With that said, let’s take a look at what the report.



Introducing M365IdentityPosture

The (future) one-stop shop for PowerShell M365 Security reports!


What Is M365IdentityPosture?

At its core, M365IdentityPosture is a PowerShell module designed to become a unified reporting toolkit for Microsoft Cloud identity and security.

It’s a living, community-driven project still in its early stages, but with big ambitions.


The current version fills a crucial gap in visibility around Authentication Contexts by providing a comprehensive report that pulls data from all programmatically accessible features that support them.


The inventory report includes:

  • Authentication Contexts

  • Conditional Access Policies

  • PIM Policies for Entra, Groups, and Azure resources

  • Protected Actions

  • Sensitivity Labels

  • Security Groups & Teams

  • SharePoint Sites


In the next sections, we’ll cover how to install the module and use the Authentication Context Inventory Report.


You can find the full documentation and source code on GitHub: M365IdentityPosture



Installing M365IdentityPosture

As with any tool, let’s start with the prerequisites before diving into installation.


Prerequisites

  • PowerShell version: The module requires PowerShell 7 or later.

  • Operating Systems: Windows 10/11, Windows Server 2019+, macOS or Linux

  • Module Dependencies: The module dynamically loads and unloads these modules during execution, but it does not handle installation automatically. Make sure the following are installed:

    • Microsoft.Graph.Authentication

    • Microsoft.Graph.Groups

    • ExchangeOnlineManagement

    • Microsoft.Online.SharePoint.PowerShell

    • Az.Accounts

    • Az.Resources


Installation Options

You can install M365IdentityPosture either from the PowerShell Gallery or manually from GitHub.


PSGallery installation option
# Install the module via PSGallery
Install-Module -Name M365IdentityPosture

# Import the moddule
Import-Module -Name M365IdentityPosture

Manual installation option
# Download or clone the repository
git clone https://github.com/Noble-Effeciency13/M365IdentityPosture.git

# Copy to user module path
$modulePath = "$HOME\Documents\PowerShell\Modules\M365IdentityPosture"
Copy-Item -Path ".\M365IdentityPosture\*" -Destination $modulePath -Recurse -Force

# Import the module
Import-Module -Name M365IdentityPosture

Running the Authentication Context Inventory Report

Since the report gathers data from across your Microsoft 365 estate, a few permissions are required.


It uses the Microsoft Graph Command Line Tools (formerly Microsoft Graph PowerShell) enterprise application with delegated permissions, all of which must be granted to the user running the report.


Required Microsoft Graph Delegated API permissions:


Required Service-Specific Permissions:

  • Exchange Online: View-Only Organization Management OR Global Reader

  • SharePoint Online: SharePoint Administrator OR Global Reader

  • Azure: Reader role on Subscriptions or Management Groups (for Azure PIM Policy enumeration)


With the module installed and permissions in place, running the report is simple, just invoke it and let the magic happen.

On the first run, you’ll be prompted to grant Graph consent.



Importing M365IdentityPosture & Get-Help Functionality

When you import the module, it displays the current version and available public commands.

Each command includes comment-based help, which you can access with the standard Get-Help command to view parameters and examples.


To view help for the Authentication Context Inventory Report:

Get-Help Invoke-AuthContextInventoryReport -Detailed
Terminal showing M365 Identity & Security Posture v1.0.0 setup. Includes author info and available commands in green and yellow text.


Invoking the Authentication Context Inventory Report

When you run the report without the -Quiet parameter, you’ll see progress updates in the console for each phase, along with a summary at the end.


For large Azure environments, you can skip Azure PIM policy enumeration (which can take time) to speed things up.

Text output on a black screen showing an "Authentication Context Inventory Report" with various steps and connections in green and blue text.
Console output showing PIM policy analysis and report generation. Text includes "HTML report saved" and "Completion Summary" with counts.


Navigating the Authentication Context Inventory Report

Once complete, the report generates an interactive HTML report showing all deployed authentication contexts across your environment, excluding MDCA Session Policies as noted earlier.

Dashboard of "Authentication Context Inventory" with tables showing context names, descriptions, policies, and groups. Blue and white theme.

This report provides an easy, effective way to document and track authentication contexts across your organization, ensuring you stay on top of documentation and change tracking requirements.

And let’s be honest - that’s often the worst part of any technical implementation.



Monitoring Usage of Authentication Contexts Using KQL

As mentioned earlier, there’s currently no built-in way to monitor or report on the utilization of Authentication Contexts, at least not directly.

However, through Microsoft Entra sign-in logs, we can identify when a user’s sign-in is affected by a Conditional Access policy scoped to an authentication context.


That means we can query these events using KQL, whether the data resides in a Log Analytics workspace, Microsoft Sentinel, a Graph-based third-party integration, or Azure Monitor.


The challenge with this approach is that we can’t always determine exactly what triggered the authentication prompt.

But when you combine the M365IdentityPosture report from earlier, with the following KQL query, you can start drawing meaningful connections - who was affected, what was required, and when it happened.


KQL: Identify and Map Authentication Context Usage

The query below searches the last 30 days of sign-in logs for sign-ins requiring an ACR claim (Authentication Context).

It then attempts to identify which Conditional Access policy required that context.

If it can’t find a direct match, it lists all successful Conditional Access policies from the same sign-in to help narrow it down.

SigninLogs
| where TimeGenerated between (ago(30d) .. now())
| where isnotempty(AuthenticationContextClassReferences)
| extend ACR = todynamic(AuthenticationContextClassReferences)
| mv-expand ac = ACR
| extend d = todynamic(ac)
| extend AuthContextId = coalesce(tostring(d.id), tostring(ac)),
         AuthContextDetail = tolower(tostring(d.detail))
| where AuthContextDetail == "required" and isnotempty(AuthContextId)
| extend AppliedCAPs = todynamic(coalesce(column_ifexists("AppliedConditionalAccessPolicies", dynamic(null)),
                                          column_ifexists("AppliedConditionalAccessPolicies_dynamic", dynamic(null)), dynamic([]))),
         ConfigCAPs  = todynamic(coalesce(column_ifexists("ConditionalAccessPolicies", dynamic(null)),
                                          column_ifexists("ConditionalAccessPolicies_dynamic", dynamic(null)), dynamic([])))
| extend PoliciesAll = array_concat(AppliedCAPs, ConfigCAPs)
| mv-apply pol = PoliciesAll on (
    extend polId   = tostring(coalesce(pol.policyId, pol.id)),
           polName = tostring(coalesce(pol.displayName, pol.policyName)),
           polRes  = tostring(pol.result),
           polAcrs = todynamic(pol["conditions"]["applications"]["authenticationContextClassReferences"]),
           polJson = tostring(pol)
    | extend matched = iif(isnotempty(polAcrs) and array_index_of(polAcrs, AuthContextId) >= 0, 1,
                           iif(polJson has_cs "\"authenticationContextClassReferences\"" and polJson has_cs strcat("\"", AuthContextId, "\""), 1, 0))
    | project polId, polName, polRes, matched
)
| summarize
    RequiringPolicyIds   = make_set_if(polId,   matched == 1, 50),
    RequiringPolicyNames = make_set_if(polName, matched == 1, 50),
    CandidatePolicyIds   = make_set_if(polId,   polRes =~ "success", 50),
    CandidatePolicyNames = make_set_if(polName, polRes =~ "success", 50)
  by TimeGenerated, Id, UserPrincipalName, UserId,
     AppDisplayName, ResourceDisplayName, ClientAppUsed,
     AuthContextId, IPAddress, SessionId
| project
    SignInTime = TimeGenerated,
    UserPrincipalName, UserId,
    AppDisplayName, ResourceDisplayName, ClientAppUsed,
    AuthContextId,
    RequiringPolicyIds, RequiringPolicyNames,
    CandidatePolicyIds, CandidatePolicyNames,IPAddress, SessionId
| order by SignInTime desc

Example Output – Authentication Context Usage Query

The KQL query returns detailed sign-in activity where authentication contexts were applied.

In this example, we can see a sign-in to Microsoft Graph Command Line Tools that required the authentication context c1. While no directly linked Requiring Policies were identified, several Candidate Policies appear helping to narrow down which Conditional Access policies may have triggered the requirement.

Table showing Microsoft Graph login details, including UserPrincipalName, AppDisplayName, ClientAppUsed, and policy IDs, with data redacted.

This query helps visualize authentication context activity across your environment and connect the dots between configuration and real-world usage.


While it doesn’t reveal the exact trigger behind each authentication prompt, it provides valuable insights into which policies are most active, who’s being challenged, and how authentication contexts are applied in practice.



Conclusion: From Configuration to Clarity

Throughout this mini-series, we’ve taken a deep dive into Microsoft Entra Authentication Contexts, from understanding what they are and how they strengthen access security and data protection, to deploying, documenting, and now monitoring them across your environment.


As we’ve seen, authentication contexts can easily multiply and drift over time, especially in large or long-lived tenants. Without proper visibility, that complexity can quickly turn into a compliance or operational headache.


By combining structured documentation through the M365IdentityPosture module with data-driven monitoring using KQL, we gain both perspectives:

  • The static view of how contexts are configured

  • The dynamic view of how they’re actually used


Together, they create the foundation for effective governance, cleaner IAM hygiene, and stronger audit readiness.


With better visibility, ongoing documentation, and consistent monitoring in place, managing authentication contexts stops being a guessing game and becomes a structured, repeatable process — one that scales as your organization grows.


You can find the full Mastering Microsoft Entra Authentication Contexts series below, and the M365IdentityPosture source code on my GitHub.


And now, to close out the series - the mandatory bad joke


Yesterday my son came home and asked me,

“Dad, my teacher told me never to name a boat after anything cloud related — why not?”

I told him,

“Oh, that’s because there’s a much higher chance of it syncing.”😎



🔗 Authentication Context Series Index

bottom of page