I previously asked about the authentication methods.
The user_handle parameter in the request payload is not intended to be set by the client. Auth0 generates this value automatically when an authentication method is created, ensuring each method has a unique, immutable identifier within the system. Any value you pass in the request is ignored by design, and Auth0 always returns its own generated handle in the response.
Let’s imagine that a user wants to create a passkey.
a) The system first needs to create PublicKeyCredentialCreationOptions. This option data is created in our system / master system.
As far as I understand, the user.id field in these options should refer to the master system’s user ID, rather than to a user ID from an external system such as Auth0.
At this point, the Auth0 user_handle is not even known because the authentication method has not yet been created. Is my understanding correct?
b) The user then creates a credential (passkey) based on the previously generated PublicKeyCredentialCreationOptions.
The credential data is sent to our backend (the master system). Once the passkey data has been successfully inserted into our database, we create the corresponding authentication method via the Auth0 Management API.
Our requirement is that, regardless of what happens with Auth0 or any other external identity provider, we must always be able to recreate or provision all passkeys in another provider’s system if necessary—for example, in an emergency or migration scenario.
I am not a WebAuthn expert, but this seems rather problematic if we cannot use the user_handle that is already used by our master database. I also just don’t understand why the Auth0 documentation presents user_handle as part of the POST authentication-method request:
Auth0 — POST /api/v2/users/{id}/authentication-methods
How Auth0 internally find correct public key when requesting token? Using userHandle and credential id?
POST /oauth/token
Here, our problem is that we can’t get the login flow to work or retrieve the token data. The API returns an unauthorized response. My best guess is that the user_handle doesn’t match.