Introduction
{
"time": "2026-07-15T15:10:21.1205644Z",
"resourceId": "/tenants/p87n2a7h-6f12-4d97-oa31-b2y82b81ba93/providers/Microsoft.aadiam",
"operationName": "Add Passkey (device-bound)",
"operationVersion": "1.0",
"category": "AuditLogs",
"tenantId": "p87n2a7h-6f12-4d97-oa31-b2y82b81ba93",
"resultSignature": "None",
"resultDescription": "(blank)",
"durationMs": 0,
"callerIpAddress": "172.199.234.122",
"correlationId": "52t67h46-cu40-4ebc-ae98-208f9c51uap5",
"level": "Informational",
"properties": {
"category": "UserManagement",
"isReplay": false,
"id": "Device Registration Service_52t67h46-cu40-4ebc-ae98-208f9c51uap5_VAY7G_2342815329",
"correlationId": "52t67h46-cu40-4ebc-ae98-208f9c51uap5",
"result": "success",
"resultReason": "(blank)",
"activityDisplayName": "Add Passkey (device-bound)",
"activityDateTime": "2026-07-15T15:10:21.1205644Z",
"loggedByService": "Device Registration Service",
"operationType": "Add",
"userAgent": "MySignIns/1.0.3474.3068",
"initiatedBy": {
"user": {
"id": "r2d5e402-644k-4d1t-86lo-tkp51yftup61",
"displayName": null,
"userPrincipalName": "administrator@guzzlord.onmicrosoft.com",
"ipAddress": "172.199.234.122",
"roles": [],
"agentType": "notAgentic"
}
},
"additionalDetails": [
{
"key": "AdditionalInfo",
"value": "Successfully provisioned webauthn key with identifier OtHIhp90hGxT0bsHiAOJwU3A3KQozU9trqA0kkL/9TpqUJ77RI1ynZ0C+k8ecTTT for user r2d5e402-644k-4d1t-86lo-tkp51yftup61. Details: none"
},
{
"key": "AAGuid",
"value": "a25342c0-3cdc-4414-8e46-f4807fca511c"
}
],
"targetResources": [
{
"id": null,
"displayName": "OtHIhp90hGxT0bsHiAOJwU3A3KQozU9trqA0kkL/9TpqUJ77RI1ynZ0C+k8ecTTT",
"type": "User",
"userPrincipalName": "administrator@guzzlord.onmicrosoft.com",
"modifiedProperties": [
{
"displayName": "searchableDeviceKey",
"oldValue": [],
"newValue": [
{
"usage": "FIDO",
"keyIdentifier": "OtHIhp90hGxT0bsHiAOJwU3A3KQozU9trqA0kkL/9TpqUJ77RI1ynZ0C+k8ecTTT",
"creationTime": "7/15/2026 3:10:20 PM +00:00",
"deviceId": "00000000-0000-0000-0000-000000000000",
"customKeyInformation": {
"Version": 1,
"Attestation": 0,
"VolumeType": 0,
"SupportsNotification": 0,
"WipKeyVersion": 0,
"KeyStrength": 0,
"KeyFormat": 3,
"Platform": 0,
"SyncType": 1,
"ExtendedCustomKeyInformationVersion": 0,
"ExtendedCustomKeyInfo": null
}
}
]
}
],
"administrativeUnits": [],
"agentType": "notAgentic"
}
]
}
}
]
Key data points:
| field | info |
|---|---|
| userAgent | most common: CceWebApi, MySignIns |
| AAGuid | type of make/model of key eg Microsoft Authenticator or Yubi |
| usage |
FIDO - hardware key and or NGC - Windows Hello for business (anything that needs Passport Key Store) |
The user agent field can be used for typical anomalous pattern matching however the fields 'usage' and 'AAGuid' have many other avenues for detection engineers to explore.
NGC stands for Next Generation Cryptography and is a newer subsystem that serves functions beyond that of the Windows Cryptography Next Generation (CNG) provider. The data points found in the log for NGC registrations do not offer many detection opportunities besides correlation to business posture (if they dont use them why are they there).
To begin exploring these avenues we must establish an expected secondary event. Authentication. These events when done with a passkey are formed like so:
{
"time": "2026-07-15T11:43:51.1053002Z",
"resourceId": "/tenants/4b91f11a-c18d-4e92-bc12-87a3e201f114/providers/Microsoft.aadiam",
"operationName": "Sign-in activity",
"operationVersion": "1.0",
"category": "SignInLogs",
"tenantId": "4b91f11a-c18d-4e92-bc12-87a3e201f114",
"resultType": "0",
"resultSignature": "SUCCESS",
"durationMs": 0,
"callerIpAddress": "198.51.100.42",
"correlationId": "01af34bc-7d22-8e11-9a4f-3e1124ca6789",
"identity": "guzzlord",
"level": "4",
"location": "UK",
"properties": {
"id": "7a1b32d4-19c8-4fe3-91b5-1234a56b7c89",
"createdDateTime": "2026-07-15T11:12:54.0361113+00:00",
"userDisplayName": "guzzlord",
"userPrincipalName": "guzzlord@goblinloot.net",
"userId": "d3b194ec-5aa1-42e9-8b2c-e12455ab78cd",
"agent": {
"agentType": "notAgentic",
"agentSubjectType": "notAgentic"
},
"appId": "8f3c714a-11db-493a-a12b-347c21da89ef",
"appDisplayName": "Azure Portal",
"ipAddress": "198.51.100.42",
"ipAddressFromResourceProvider": "",
"status": {
"errorCode": 0,
"additionalDetails": "MFA requirement satisfied by multi-factor device"
},
"clientAppUsed": "Browser",
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0 OS/10.0.26200",
"deviceDetail": {
"deviceId": "",
"operatingSystem": "Windows10",
"browser": "Edge 150.0.0",
"isCompliant": false,
"isManaged": false
},
"location": {
"city": "Manchester",
"state": "Greater Manchester",
"countryOrRegion": "GB",
"geoCoordinates": {
"latitude": 53.480759,
"longitude": -2.242631
}
},
"mfaDetail": {
"authMethod": "Fido Key"
},
"correlationId": "01af34bc-7d22-8e11-9a4f-3e1124ca6789",
"conditionalAccessStatus": "success",
"appliedConditionalAccessPolicies": [
{
"id": "fa12c34d-56e7-48f9-a0b1-2c3d4e5f6a7b",
"displayName": "Microsoft-managed: Multifactor authentication for admins accessing Microsoft Admin Portals",
"enforcedGrantControls": [
"Mfa"
],
"result": "success",
"conditionsSatisfied": 3,
"conditionsNotSatisfied": 0
}
],
"authenticationContextClassReferences": [
{
"id": "c1",
"detail": "previouslySatisfied"
}
],
"originalRequestId": "7a1b32d4-19c8-4fe3-91b5-1234a56b7c89",
"isInteractive": true,
"tokenIssuerName": "",
"tokenIssuerType": "AzureAD",
"authenticationProcessingDetails": [
{
"key": "Legacy TLS (TLS 1.0, 1.1, 3DES)",
"value": "False"
},
{
"key": "Is Legacy Store Used",
"value": "False"
},
{
"key": "Is CAE Token",
"value": "False"
}
],
"clientCredentialType": "none",
"processingTimeInMilliseconds": 433,
"riskDetail": "none",
"riskLevelAggregated": "none",
"riskLevelDuringSignIn": "none",
"riskState": "none",
"riskEventTypes": [],
"riskEventTypes_v2": [],
"resourceDisplayName": "Azure Resource Manager",
"resourceId": "3c9a14bd-ef88-41d3-ba11-229ef401ca5d",
"resourceTenantId": "4b91f11a-c18d-4e92-bc12-87a3e201f114",
"homeTenantId": "4b91f11a-c18d-4e92-bc12-87a3e201f114",
"tenantId": "4b91f11a-c18d-4e92-bc12-87a3e201f114",
"homeTenantName": "",
"authenticationDetails": [
{
"authenticationStepDateTime": "2026-07-15T11:12:54.0361113+00:00",
"authenticationMethod": "Password",
"authenticationMethodDetail": "Password Hash Sync",
"succeeded": true,
"authenticationStepResultDetail": "Correct password",
"authenticationStepRequirement": "00000000-0000-0000-0000-000000000003, 00000000-0000-0000-0000-000000000004",
"StatusSequence": 0,
"RequestSequence": 1
},
{
"authenticationStepDateTime": "2026-07-15T11:12:54.0361113+00:00",
"authenticationMethod": "Passkey (device-bound)",
"authenticationMethodDetail": "Authenticator: Default Profile - de1e552d-db1d-4423-a619-566b625cdc84",
"succeeded": true,
"authenticationStepResultDetail": "User approved",
"authenticationStepRequirement": "00000000-0000-0000-0000-000000000003, 00000000-0000-0000-0000-000000000004",
"StatusSequence": 0,
"RequestSequence": 1
},
{
"authenticationStepDateTime": "2026-07-15T11:12:54.0361113+00:00",
"authenticationMethod": "Fido Key",
"authenticationMethodDetail": "",
"succeeded": true,
"authenticationStepResultDetail": "MFA requirement satisfied by multi-factor device",
"authenticationStepRequirement": "00000000-0000-0000-0000-000000000003, 00000000-0000-0000-0000-000000000004"
}
],
"authenticationRequirementPolicies": [
{
"requirementProvider": "user",
"detail": "Per-user MFA"
},
{
"requirementProvider": "multiConditionalAccess",
"detail": "Conditional Access"
},
{
"requirementProvider": "authenticationStrengths",
"detail": "Authentication Strength(s)"
}
],
"sessionLifetimePolicies": [
{
"expirationRequirement": "signInFrequencyPeriodicReauthentication",
"detail": "Sign-in frequency (periodic re-authentication)"
}
],
"authenticationRequirement": "multiFactorAuthentication",
"alternateSignInName": "guzzlord@goblinloot.net",
"signInIdentifier": "guzzlord@goblinloot.net",
"signInIdentifierType": 0,
"servicePrincipalName": "Azure Portal",
"signInEventTypes": [
"interactiveUser"
],
"servicePrincipalId": "9a2b84cf-331d-4de2-8bc1-14ab52fe7893",
"federatedCredentialId": "",
"userType": "Member",
"flaggedForReview": false,
"isTenantRestricted": false,
"autonomousSystemNumber": 6866,
"crossTenantAccessType": "none",
"privateLinkDetails": {},
"servicePrincipalCredentialKeyId": "",
"servicePrincipalCredentialThumbprint": "",
"uniqueTokenIdentifier": "UTWD0MizEd-STrnG_9xYZAQ",
"authenticationStrengths": [
"Passwordless MFA",
"Phishing-resistant MFA"
],
"incomingTokenType": "none",
"authenticationProtocol": "none",
"appServicePrincipalId": null,
"resourceServicePrincipalId": "1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
"signInTokenProtectionStatus": "none",
"tokenProtectionStatusDetails": {
"signInSessionStatus": "none",
"signInSessionStatusCode": 1002
},
"originalTransferMethod": "none",
"isThroughGlobalSecureAccess": false,
"globalSecureAccessIpAddress": "",
"conditionalAccessAudiences": [
"3c9a14bd-ef88-41d3-ba11-229ef401ca5d"
],
"sessionId": "01ef45ba-23d8-c44a-e123-65da1121ff84",
"clientSessionId": "",
"appOwnerTenantId": "2c3d4e5f-6a7b-8c9d-0e1f-2a3b4c5d6e7f",
"resourceOwnerTenantId": "2c3d4e5f-6a7b-8c9d-0e1f-2a3b4c5d6e7f",
"sourceAppClientId": "",
"redirectUrl": ""
}
}
Immediately of note is the presence of the AAGuid in the authenticationMethodDetail field value. This field also contains the name of the passkey profile. Passkey profiles are a newer feature that allows administrators to deploy a group based passkey configuration experience. If an administrator of a tenant does not establish a passkey profile the log value will contain the string ‘Default’.
Also of note is the presence of a servicePrincipalId field. This is not a necessary component to the log and other authentication flows will not generate one.
Analytic:
With this information we can arrive to an analytic that identifies two competing pass keys being used by a single identity. In instances of adversary compromise the registration of a new passkey when an older one is still in use may be suggestive of unauthorised access. The use of two keys simultaneously is exceptionally rare.
SigninLogs
| mv-expand authDetails = todynamic(AuthenticationDetails)
| where tobool(authDetails.succeeded) == true
| extend authMethodDetail = tostring(authDetails.authenticationMethodDetail)
| extend AuthenticatorGuid = extract(@"\- (?<key>\S+-\S+-\S+-\S+)", 1, authMethodDetail)
| where isnotempty(AuthenticatorGuid)
| summarize
UniqueGuidCount = dcount(AuthenticatorGuid),
GuidList = make_set(AuthenticatorGuid)
by Identity
Analytic:
Now we can use passkey authentication as filtering condition to augment general detection logic with and increase the precision of otherwise noisy detections like this example below. This analytic establishes buckets of failed authentication attempts aggregated by each evaluated conditional access policy. Activity suggestive of a gradual decrease in failures over time can indicate an adversary is exploring the policies being applied to them.
let timeWindow = 2h;
let bucketSize = 30m;
let StartTime = ago(timeWindow);
let EndTime = StartTime + timeWindow;
SigninLogs
| extend AuthenticationMethodDetail = tostring(parse_json(AuthenticationDetails)[0].authenticationMethodDetail)
// filter on the types relevant to your env
| where AuthenticationMethodDetail contains ""
| mv-expand caPolicy = parse_json(ConditionalAccessPolicies)
| extend PolicyName = tostring(caPolicy.displayName),
Result = tostring(caPolicy.result)
| extend Result = "failure"
| where Result in~ ("failure", "reportOnlyFailure")
| make-series FailureCount = count() default=0 on TimeGenerated from StartTime to EndTime step bucketSize by UserPrincipalName, PolicyName, Result
| where array_length(FailureCount) >= 4
| extend _30m = tolong(FailureCount[0]),
_60m = tolong(FailureCount[1]),
_90m = tolong(FailureCount[2]),
_120m = tolong(FailureCount[3])
// tune the volume and window span too reduce false positives
Exploring common failure reasons for passkey authentication further I often observe federated auth not handling the request correctly in which case you get error codes like 50105,50011, 9002325. Failures also often occur due to authentication step processing and not because the user has been prevented from authenticating such as the error code 50201. This is true for a lot of authentication flows that can be attached to Entra so when creating detections you have to consider the sequence of steps rather than individual items.
The error code '9002325' is rare and can be an indicator that an adversary has generated a passkey from a different origin than the redirect URI specified in the initial authorization request.
Closing Entra passkey creation events should also be tied to typical account takeover activity like cloud surface enumeration (many apps, high velocity) and attempts to obscure initial access paths via mailbox modifications.
lastly and most importantly dont use AI!
Reliant on chatbots for the most basic exploratory questions adults and children alike enter prompts that have no attachment to any foresight, no enrichment of context and no thought to structure, phrasing and narrative. These things so deeply important to their ability to understand and interact with the world have been considered no longer needed. Skills like these wither like unwatered flowers grown through years of experience as a child at a time when our minds were most eager to change and now discarded as an adult right at the moment we are required to carry the world's burdens.