Microsoft Graph v1.0 passkey creationOptions returns WebAuthn parameters rejected by Chromium

Eka Lin 0 Reputation points
2026-08-10T09:16:48.5933333+00:00

Hello, we are implementing programmatic passkey registration for a Microsoft Entra External ID tenant.

To obtain WebAuthn creation options, our backend uses an app-only access token and Microsoft Graph Java SDK 6.65.0 with the following SDK call:

final WebauthnCredentialCreationOptions creationOptions = graphClient.users()
    .byUserId(userId)
    .authentication()
    .fido2Methods()
    .creationOptions()
    .get();

The GraphServiceClient uses the SDK's default Microsoft Graph v1.0 service target and default Graph service root. We do not use the beta SDK, a beta request builder, or a custom Graph base URL.

This SDK operation corresponds to the Microsoft Graph v1.0 creationOptions API documented as: GET /users/{user-id}/authentication/fido2Methods/creationOptions

The SDK returns the following relevant, sanitized creation options from Microsoft Graph:

{
  "publicKey": {
    "pubKeyCredParams": [
      {
        "type": "public-key",
        "alg": -7
      },
      {
        "type": "public-key",
        "alg": -257
      }
    ],
    "timeout": 0,
    "excludeCredentials": [],
    "authenticatorSelection": {
      "authenticatorAttachment": "cross-platform",
      "requireResidentKey": true,
      "userVerification": "required"
    },
    "attestation": "direct",
    "extensions": {
      "enforceCredentialProtectionPolicy": true,
      "credentialProtectionPolicy": "userVerificationOptional",
      "hmacCreateSecret": true
    }
  }
}
  • The WebAuthn values shown above are returned by Microsoft Graph and are forwarded by our application without changing their values. Only Microsoft Graph metadata fields, such as @odata.*, are omitted.
  • Our effective Passkey (FIDO2) policy allows both device-bound and synced passkeys. However, Graph returns authenticatorAttachment: cross-platform, and we would like to understand how this value is determined.
  • When the returned options are converted to WebAuthn creation options and passed to navigator.credentials.create(), Chrome rejects the request with the following error:
NotSupportedError:

Requested protection policy is inconsistent or incongruent with other requested parameters.

It seems Chromium maps credentialProtectionPolicy: "userVerificationOptional" to its internal ProtectionPolicy::NONE value and rejects this policy when enforceCredentialProtectionPolicy is enabled.

Relevant Chromium implementation references:

We also noticed that, although the request is made through the Microsoft Graph Java SDK's v1.0 service target, the returned values closely match the Microsoft Graph beta documentation example, including:

  • authenticatorAttachment: "cross-platform"
  • extensions.hmacCreateSecret: true
  • extensions.enforceCredentialProtectionPolicy: true
  • extensions.credentialProtectionPolicy: "userVerificationOptional"

Beta documentation:

By contrast, the current Microsoft Graph v1.0 documentation example shows:

"authenticatorSelection": {
  "authenticatorAttachment": "platform",
  "requireResidentKey": true,
  "userVerification": "required"
}

and does not show the above credential-protection extension values.

v1.0 documentation:

Could you please clarify the following?

  1. Is the returned { "credentialProtectionPolicy": "userVerificationOptional", "enforceCredentialProtectionPolicy": true } configuration expected from the Microsoft Graph v1.0 creationOptions operation for a Microsoft Entra External ID tenant? Chromium rejects this combination before authenticator selection.
  2. Why is authenticatorAttachment returned as "cross-platform" when the effective Passkey profile permits both device-bound and synced passkeys?
  3. Are clients expected to pass the returned creation options to navigator.credentials.create() without modifying them? If clients are expected or permitted to modify the returned creation options, could you please clarify which fields may be modified or removed and where this behavior is documented?
  4. Does Microsoft Entra External ID support registering a synced passkey using Google Password Manager in Chrome on Linux through this programmatic registration flow?

The Graph request is made server-to-server and contains no browser, operating-system, or authenticator context, so the returned "cross-platform" restriction does not appear to be based on the client environment.

At this stage, we have intentionally not modified or removed any of the returned WebAuthn parameters because we have not found Microsoft documentation indicating that clients should alter the creation options generated by Microsoft Entra.

We can provide the complete sanitized Graph response if required. Thank you.

Microsoft Security | Microsoft Graph
0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.