I am thinking of allowing users to login using passkeys. As far as I understand it a login flow of a user logging in with passkeys typically works like this:
If a login is allowed like this, doesn't this allow for user enumeration attacks? After entering the user-id of an existing user with passkeys enabled, I get a different second page compared to using a non-existent user-id. How do I prevent this?
There is a conditional mediation feature (auto-fill with passkey) to allow for you to accept passkeys and traditional passwords in one screen. So, you can leverage that feature by returning empty allow credential for the passkey authentication for all users without checking whether the users are protected by passkeys or not.
In this case, the attacker cannot know whether the user accounts are protected by passkeys or not since there is no differences regarding the screen and response from the service. The browsers will handle the user device has passkeys for the site instead of the service (relying party) or ask customers to use another devices (cross device authentication with passkey or secret keys). Or, the browser might auto-fill the users' passwords or users simply put their passwords in the password field if the service allows to do so.
On the other hand, the service might have some magical way of checking user enumeration attacks by checking cookie or any other information so that it might block such attempts from the attackers.