Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleanup when creating discoverable credentials with attestations #1560

Closed
dwaite opened this issue Feb 4, 2021 · 11 comments
Closed

Cleanup when creating discoverable credentials with attestations #1560

dwaite opened this issue Feb 4, 2021 · 11 comments
Assignees
Labels
@Risk Items that are at risk for L3 stat:Discuss subtype:FeatureProposal subtype:Inquiry Inquiry wrt API and/or protocol capabilities/features, or WG / pub process, or spec editorial stuff

Comments

@dwaite
Copy link
Contributor

dwaite commented Feb 4, 2021

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).

@arshadnoor
Copy link

arshadnoor commented Feb 4, 2021

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.

@dwaite
Copy link
Contributor Author

dwaite commented Feb 4, 2021

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.

@arshadnoor
Copy link

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.

@equalsJeffH
Copy link
Contributor

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.

@equalsJeffH
Copy link
Contributor

equalsJeffH commented Feb 10, 2021

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.

@equalsJeffH
Copy link
Contributor

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.

@equalsJeffH equalsJeffH added stat:Discuss subtype:FeatureProposal subtype:Inquiry Inquiry wrt API and/or protocol capabilities/features, or WG / pub process, or spec editorial stuff labels Feb 17, 2021
@equalsJeffH equalsJeffH added this to the Futures (catch-all) milestone Feb 17, 2021
@emlun
Copy link
Member

emlun commented Mar 15, 2021

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 ID credIdA, if present on any present authenticator and scoped to the calling RP.
  • cleanUpPublicKeyCredentials({ notMatching: [{ id: "credIdA" }] }) would request to delete all credentials except credIdA 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. 🙂

@dwaite
Copy link
Contributor Author

dwaite commented Mar 16, 2021

Yes, what I was thinking was something similar to this:

  1. best-effort cleanup of credentials the site does not understand
  2. 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"}
]})

@nadalin nadalin added the @Risk Items that are at risk for L3 label Jun 27, 2023
@dwaite
Copy link
Contributor Author

dwaite commented Sep 9, 2023

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.

@Firstyear
Copy link
Contributor

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.

@timcappalli
Copy link
Member

closing to consolidate discussions on this topic. please continue discussions here: #1967

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@Risk Items that are at risk for L3 stat:Discuss subtype:FeatureProposal subtype:Inquiry Inquiry wrt API and/or protocol capabilities/features, or WG / pub process, or spec editorial stuff
Projects
None yet
Development

No branches or pull requests

7 participants