Status: Draft; May be totally wrong! Last changed $Date: 2020/06/08 14:45:34 $ Questions? Ian or Adrian. Problem statement: - User has an identity with a relying party such as an issuing bank. - As part of a decision to re-authenticate a user during a transaction with Web Authentication, the relying party needs to know that identity (e.g., via a username) - Having to retype a username at each transaction is a bad user experience. Confirming a browser prompt to use a stored identity is an acceptable user experience. - The relying party could use cookies to store the username, but changes in browsers are likely to make this less effective, especially as the user visits different merchant sites. - If the relying party can easily store identifying information (through cookies or other means) that could enable tracking. We'd like this proposal to work for a large set of authenticators. To that end, the proposal does not rely on: - Resident credentials [1]. - isUserVerifyingPlatformAuthenticatorAvailable() [2] Proposal: * A new method: getIfYouCan(). - Like get() without (all or part of) allowCredentials. - Requests that the browser find a user credential for this origin, call get() with it, and return the assertion, otherwise return null without any user experience. - Thus: 1) if the user has no stored id, it returns null. 2) if the user has one stored it, call Web Authentication with it 3) otherwise, prompt the user to select and id, then call WebAuthn with it. Benefits: * Enables an RP to pursue re-authentication path with confidence that re-authentication is available. There is no disruption to the user journey if re-authentication is not possible. If re-auth is not available, the RP can choose a bootstrap authentication path. * Does not reveal any information about the user environment to the RP before authentication EXCEPT one bit, which is "re-authentication not possible." * User can clear information, but it is stickier than cookies. * User does not have to re-type username. * Requires no changes to authenticators, and should work with any type of authenticator. [1] https://auth0.com/blog/a-look-at-webauthn-resident-credentials/ [2] https://w3c.github.io/webauthn/#sctn-isUserVerifyingPlatformAuthenticatorAvailable ========================= OLDER PROPOSAL Left here for historical purposes. The above proposal is simpler. Can we enable a relying party to store an identifier for a user such that: 1) The relying party can easily access the identifier as part of determining whether to pursue a WebAuthn re-authentication. 2) The relying party can access this stored information from within a payment handler used to make payments across different merchant origins. 3) The user does not have to re-type a username. 4) The user can clear this information, but it is stickier than cookies. 5) The mechanism does not rely on cookies. Proposal: 1) Create a new subclass of Credential. This subclass defines an object with data that corresponds to allowCredentials data in Web Authentication. That data is obfuscated to prevent the RP from using it to track the user. For example, the data might consist of a key seeded by the browser from the public key, and stored by the browser. 2) When the user is first authenticated, the payment app stores an instance of the credential: navigator.credentials.store(new DerivedPublicKeyCredential({data_for_webauthn})); 3) When the user returns for a future transaction, the payment app checks to see if the user has 0, 1, or more than one stored DerivedPublicKey: wait navigator.credentials.get({"derivedpublickey": true}) If the user has no such credentials, the call returns "null" without notifying the user. The payment app can pursue a bootstrap sign-in at that point. If the user has one such credential, the call returns it and the browser notifies the user (but no user action is required). If the user has more than one, the user chooses an identity and that one is returned to the payment app. 4) The payment app can call Web Authentication get() with DerivedPublicKeyCredential.allowCredentials as the WebAuthn allowCredentials value. Benefits: * Enables re-authentication decision making in a way that does not rely on cookies. * Does not enable user tracking. * The user can clear data (but it is stickier than cookies). * The user experience before authentication involves minimal user gestures (namely, identity selection when there is more than one). Notes: 1) Question: Does the payment app have access to the credentials across merchant origins? 2) The high-level goal is to give the RP some information to make a decision, but also to limit the ability to track. The proposal refers to obfuscating the "allowCredentials" data. Is that the right piece of data? Who obfuscates the data and who undoes this when Web Authn is called later?). 3) We'd like this proposal to work for a large set of authenticators. To that end, the proposal does not rely on: - Resident credentials [1]. - isUserVerifyingPlatformAuthenticatorAvailable() [2] 4) The proposal also intends to support authentication from a cross-origin iframe within the payment app. In that situation, the browser still stores information available to the payment app origin. How the payment app origin communicates with other origins is an implementation detail. 5) It's also possible to abstract requirements away from CM API: - Persistent storage that is not cookie-based. - Does not suport user tracking (but does reveal one bit to the RP, namely the user has previously authenticated). - Available to third parties cross-origin.