webauthn
webauthn copied to clipboard
Cleanup when creating discoverable credentials with attestations
When a relying party wishes to use attestations, the flow is one where the site presents the UX on what is acceptable, the user gestures an authenticator to create a credential, and then the site verifies the attestation, possibly showing an error ("no we're serious, use that authenticator we mailed you").
However, on this attestation failure the user will continue to have the 'orphaned' credential on an authenticator, potentially presented to them as a valid option in a selector. The credential record itself does not contain information needed to disambiguate which credential is the correct one, which could potentially make use of a credential management UX into a game of Russian roulette.
This could also potentially happen multiple times on a single unacceptable authenticator if credential creation happens during a registration process. The user (not understanding the correct response to a site-given error) may try different browsers or clearing their history to troubleshoot the issue. The user likely doesn't have a user handle value yet (as they do not have an account), and authenticators are allowed to store multiple credentials per (user handle, rpid).
Hi David (@dwaite)
Technically, this is an issue for Authenticator manufacturers who focus on CTAP and may be better off addressed at the FIDO-DEV mailing list on https://fidoalliance.org.
Once a credential is created on an Authenticator, the Authenticator does not need to know whether the RP accepted or rejected the registration. Some manufacturers provide tools to help manage those credentials, but there's no standard or guidelines (to the best of my knowledge) on what manufacturers should do about that.
I think this is a worthwhile initiative for browser manufacturers to create a Service Provider Interface (SPI) that allows Authenticator manufacturers to plug into it; so any browser that has the SPI can help manage those credentials much as browsers manage Username/Passwords for sites today. But, bringing it to the attention of Authenticator manufacturers in the FIDO-DEV forum might be worthwhile as the FIDO Alliance could also initiate such an effort outside the purview of browser manufacturers.
Good luck.
But, bringing it to the attention of Authenticator manufacturers in the FIDO-DEV forum might be worthwhile as the FIDO Alliance could also initiate such an effort outside the purview of browser manufacturers.
If protocol changes are warranted to solve this problem, I would expect both groups to be involved with WebAuthn being more focused on the browser and website behavior needed for the UX. Since I consider this primarily a UX issue (and don't see a way this could be improved without browser/platform involvement), I surmised it was best to talk about it here.
While the UX is definitely important, David, the W3C group may choose not to prioritize it since it does require new APIs to be defined to interact with the Authenticator - which is in the CTAP domain and outside the scope of the WebAuthn group. Given that CTAP also supports non-browser interactions with the Authenticator (for Windows Login, managing HMAC keys that aren't used by WebAuthn), there is likely to be broader interest for such an SPI at the FIDO Alliance.
However, once such an SPI is defined, there is no reason to believe that the WebAuthn group might not standardize a subset of that SPI in JavaScript APIs to support the same functions. It would benefit the ecosystem to have the Authenticator manufacturers create the SPI to support all necessary functions for Authenticator Key Management, while allowing the W3C and/or others to standardize the UX for browsers and elsewhere.
CTAP2.1 provides an authenticatorCredentialManagement facility with which client platforms can provide users the ability to manage the set of discoverable credentials on a CTAP2.1-capable authenticator.
on 2021-02-10 call: @akshayku notes that there is food for thought here, ie, if RP rejects the cred created during registration, perhaps it could be auto-cleaned up or something....food for thought here.
This is not something we will address in L2, yes? If so, we ought to go ahead and assign it to L3 or Futures milestone.
This seems like a fair idea to me. So what would we imagine the API could look like? Here's one attempt:
function cleanUpPublicKeyCredentials({
matching: optional PublicKeyCredentialDescriptor[],
notMatching: optional PublicKeyCredentialDescriptor[],
}) -> void
Where for example:
-
cleanUpPublicKeyCredentials({})
would throw an exception. -
cleanUpPublicKeyCredentials({ matching: [{ id: "credIdA" }] })
would request to delete the credential with IDcredIdA
, if present on any present authenticator and scoped to the calling RP. -
cleanUpPublicKeyCredentials({ notMatching: [{ id: "credIdA" }] })
would request to delete all credentials exceptcredIdA
present on any present authenticator and scoped to the calling RP. -
cleanUpPublicKeyCredentials({ matching: [{ id: "credIdA" }], notMatching: [{ id: "credIdA" }] })
would effectively resolve to a no-op, but could also be an error.
In all cases, the call would return immediately so as not to reveal whether any of the listed credentials are present. No success or failure result is communicated back to the RP.
The client would check which available authenticators, if any, support credential management and compile a list of to-be-deleted credentials found. If that list turns out non-empty, the client would prompt the user for confirmation before applying the change.
If any authenticator requires UV to query credential management state, I guess the client would first of all prompt the user like "this website wants to do credential management" and ask for PINs or whatever if the user agrees. Though I guess that's likely to lead to a very messy user experience. But yeah, identifying issues like that is the primary purpose of the exercise. :slightly_smiling_face:
Yes, what I was thinking was something similar to this:
- best-effort cleanup of credentials the site does not understand
- eliminating edge cases that create spurious credentials when possible.
A delete/cleanup hint mechanism could be added directly to CredMan, I believe the only WebAuthn specific part is that non-resident credentials will always silently ignore cleanup. But since everything is a hint and the result is silent, who knows? 😄
e.g. a slightly different color bikeshed
navigator.credentials.cleanup({
type: "public-key",
action: "retain",
matching: [
{id: "credhandle1"},
{id: "credhandle2"}
]})
Summarizing toward a L3 go/no-go decision:
When creation returns an attestation, there is a chance the RP will reject that credential. This creates a problem of distributed state that affects UX - the passkey manager continues to have the record, so the client will present that credential to the end-user as an option in the future, even if the RP has no intention of ever accepting it. The UX for the end-user to remove the credential manually is also likely non-intuitive.
There is also the opportunity for this same sort of behavior to happen at a later point, e.g. policy changes or data loss may cause the RP to no longer recognize an established credential on get assertion. This would also be the case for credentials removed from the relying party's self-service authentication management interface (e.g. editable list of registered and accepted passkeys).
It would be useful for the RP to hint via the credential object, or via an interface on CredMan, that a credential is invalid. The mechanism would need a way for a relying party to indicate a desired change, in the face of not having visibility into the client-side state.
One possibility is a method on PublicKeyCredential
to remove the credential, present if the feature is supported.
Another possibility is a new method in CredMan itself, which might remove various types of credentials beyond PublicKeyCredential
.
If added to CredMan, a decision would need to be made as to whether the operation takes credential identifier/handles or credential objects.
I would imagine both of these would need to be promise-based if they have a result, or fire-and-forget hints otherwise. The client may wish to get consent for removal outside of creation, or removal may require network or near-field access which add delays/user action.
Credential objects may be useful if we want to only allow deletion after a create/get request. @emlun proposed earlier an interface which acted a bit more as a filter, which might enable removal of credentials outside of get/create, and enable opportunistic broadcast of changes. As an example, this may be useful to indicate edits from a relying party self-service page at submission time, and to continue to inform clients in the future since availability of authenticators may be transient (usb, nfc) and be client-specific (platform authenticators).
As a relying party, this would be a very useful feature if it allowed for cleaning up credentials from UX such as conditionally mediated UI. I imagine viability for L3 would be based on feedback from browser/platform clients, and from CredMan (@nsatragno ?) on ergonomics.
We've asked for this before with the ability to "filter" aaguids on the browser that would not meet the attestation requirements, as we identified this problem a long time ago.
closing to consolidate discussions on this topic. please continue discussions here: https://github.com/w3c/webauthn/issues/1967