kanidm/webauthn-rs

Discoverable Credentials

Closed this issue · 11 comments

Is your feature request related to a problem? Please describe.
What are the plans around supporting login with discoverable credentials? Specifically a login request with an empty list of allowCredentials. This would allow login for users without them having to enter a username first. Is this a planned feature?

Describe the solution you'd like
Being able to create a login request that is not bound to a specific passkey but allows the user to choose the passkey to use.

** Additional Context **
I'm not sure what the best API for this is. It will require calling start_authentication without having a passkey, but then the PasskeyAuthentication object wouldn't have it, so maybe the passkey could get passed in to finish_authentication then?

We have a conditional UI trigger api that's currently feature gated. I will make it available for conditional UI only.

Otherwise, since this library doesn't guarantee all credentials are discoverable, you need to always send the allowed Credential ID's in non-conditional UI flows.

Worth pointing out though, that conditional UI workflows are ... actually pretty bad today and may do more harm to users than good. So you may end up not really wanting this 😅

Thanks. The start/identify/finish flow looks like a good API solution.

The native app experience for Google Passkeys on Android is actually good. But I haven't tested in-browser UIs. What concerns did you have with the UIs?

@smessmer you should give it to people who aren't involved in tech day to day. It breaks down pretty fast. I saw one person read the registration prompt android poped and though "omg I've been hacked".

There are also lots of reports of phones that fail to make keys at all without a full device reset.

The native app flow (on all platforms, not just Android) is very different to web. We care about web flows more, because that's got a larger audience.

Digging some more, there are at least three Android platform "Webauthn" APIs, so the experience will differ there too. Last time I looked, Chromium still uses the FIDO2 GMS API.

Based on your requests, I presume you're targetting the Android Credential Manager APIs. Its migration guide from the FIDO2 GMS API currently states (emphasis added):

Note: If your app requires non-discoverable FIDO credentials or uses physical security keys, you should continue to use FIDO at this time.

Because of that limitation, I wouldn't call Android Credential Manager a true Webauthn API: it's really a wrapper which allows Android apps to use a subset of Webauthn features exclusively with synchronised credential stores (ie: Google Passkeys in Google Password Manager).

While it's nice that Android 14 will allow integration with third-party credential managers, it really doubles down on the authentication selection problems in the FIDO2 GMS API.

Android's platform limitations aren't for us to fix. Android Credential Manager could implement the Webauthn spec properly, as Apple, Chromium (on non-Android), Microsoft and Mozilla did.

For context: the main reason we don't like RKs for the general case is because they consume (very limited) storage space on security keys, and FIDO 2.0 keys support RKs but don't support storage management (except for factory reset), so an RP's registration attempt (as the RP could reject it) can prevent that key being used for further RK registrations. Nothing in the APIs or the CTAP 2.0 protocol lets you handle this case – it's only in CTAP 2.1-PRE that you might get this feature (it is not mandatory).

If a user must have a credential manager available to access a synchronised credential store on a device with some sort of input device (keyboard, mouse, touchscreen, etc.), then that could also save the contents of a username field. That's been a browser feature for decades, and there's no reason to force RKs.

An example of a good use case for RKs is where it is physically impossible to enter a username, such as a door access control system which only has an NFC / contactless interface, as long as the credential and authenticator do not require user verification.

Unfortunately, a vocal minority of the Webauthn community continue to promote RKs (and cloud-synchronised non-attested credential stores) as the only case, and Android's APIs paint developers into a corner, making it harder for them to provide users a choice of authenticator.

I went and took the axum example and adapted it for discoverable passkeys (not rk) with the (unreleased) conditional-ui feature. The resulting auth.js.

For anyone interested in the user experience of discocoverable passkeys you can try it here: https://axum-solid-playground.fly.dev/

Is there a reason why discoverable credentials are gated under the conditional-ui feature?

I don't need conditional UI, but I still want discoverable credentials where the user doesn't need to type in their username/email and can just choose the appropriate passkey.

Thanks for the link, that's a very interesting read and I see the concern about security keys, that definitely has me rethinking whether I need discoverable keys. Although I would have thought that should be up to the application to decide, instead of the library telling applications they're only allowed to use discoverable keys together with Conditional UI...

Thanks for the link, that's a very interesting read and I see the concern about security keys, that definitely has me rethinking whether I need discoverable keys. Although I would have thought that should be up to the application to decide, instead of the library telling applications they're only allowed to use discoverable keys together with Conditional UI...

Resident Keys are opportunistic, not required. Our library already works in this way.