Monitoring Entra Auth Methods

Entra ID Jun 25, 2025

Monitoring the details of authentication methods that are present on Entra ID accounts can be really useful. However the native approaches for this have some limitations, the IdentityInfo table doesn't pass any useful information about enabled authentication methods and while monitoring the AuditLogs table does give some information, this still lacks detail such as phone numbers, and won't allow us to hunt retrospectively through existing data.

Scraping the Data

The Graph API contains an endpoint that returns exactly the information that we're looking for here, so I've built a simple logic app which

  1. Pulls a full list of users in the tenant
  2. Queries the API for auth methods for each user
  3. Pushes the output into a custom Sentinel table

You can download a template to deploy this app yourself here: https://github.com/mrrothe/AzLogicApps/blob/main/entra_auth_audit-template.json

You will need to give the app permissions to access the data from your tenant, one way it to assign a system-managed-identity to the logic app, however this requires assigning entra ID roles with a lot of privilege. A better alternative is to create a new app registration and configure the app to authenticate to the Graph API using OAuth. The app registration needs the following graph API permissions:

  • UserAuthenticationMethod.Read.All
  • User.Read.All

Using the Data

Once the data is in Sentinel, it's straightforward to parse out the various fields from the JSON

To summarize the number of users with each type of auth method

userAuthMethods_CL 
| extend
    username=url_decode(extract(@"users\('(.+)'\)/authentication/", 1, _odata_context_s))
| summarize arg_max(TimeGenerated, *) by username
| mv-expand todynamic(value_s)
| extend method=tostring(value_s["@odata.type"])
| summarize count() by method

To lookup the country name for each registered phone number

let dialingCodes=externaldata(callingCode:string, countryName:string)
    [@'https://raw.githubusercontent.com/karani-gk/Country-Calling-Codes/refs/heads/main/Countries.csv'] with(format="csv");
userAuthMethods_CL 
| extend
    username=url_decode(extract(@"users\('(.+)'\)/authentication/", 1, _odata_context_s))
| summarize arg_max(TimeGenerated, *) by username
| mv-expand todynamic(value_s)
| extend method=tostring(value_s["@odata.type"])
| where method == "#microsoft.graph.phoneAuthenticationMethod"
| extend phoneNumber_ = tostring(value_s.phoneNumber)
| extend countryCode=substring(phoneNumber_, 0, 3)
| lookup (dialingCodes) on $left.countryCode==$right.callingCode

To list the models of Fido2 security keys in use

userAuthMethods_CL 
| extend
    username=url_decode(extract(@"users\('(.+)'\)/authentication/", 1, _odata_context_s))
| summarize arg_max(TimeGenerated, *) by username
| mv-expand todynamic(value_s)
| extend method=tostring(value_s["@odata.type"])
| where method =='#microsoft.graph.fido2AuthenticationMethod'
|  summarize count() by Model=tostring(value_s.model)

Tags