w3c / webappsec-credential-management

WebAppSec Credential Management
https://w3c.github.io/webappsec-credential-management/
Other
49 stars 36 forks source link

Extensibility via "Credential Handlers" #99

Open dlongley opened 7 years ago

dlongley commented 7 years ago

I'm exploring how to structure a Credentials API for the Credentials Community Group using lessons learned from the Web Payments Working Group.

I'm hoping to model this so-called Credential Handler API after both the Payment Handler API and the Credential Management API.

To set the stage for the idea -- here's some information on the Web Payments work:

The Payment Handler API is essentially provides an additional feature to the Payment Request API whereby third party Web apps may provide code (payment handlers) that users may install and use to handle payments for them when they buy things on various sites on the Web.

When a user visits a website that is able to provide a payment handler, the site may ask the user to grant paymenthandler permission to the origin. Once this permission is granted, the site may then register "payment instruments" -- which, for our purposes here, can actually just be thought of as names and icons that will be presented to the user when the user next visits a website that requests payment. A payment instrument is registered via a service worker's registration.

When a user clicks "Buy" on some website, if that website is using the Payment Request API (and some other matching conditions are met), then the browser will show the user the names and icons (and the origin that registered them) as an option for handling the payment. Upon selection of one of these items, the item information and the payment request information are transmitted to the associated payment handler via a service worker event. This causes the service worker (the "payment handler") to wake up, receive the event -- and then do something with it.

Typically, the payment handler will show its own UI to help the user make whatever additional choices/confirmations are necessary and then return the user's payment credential (in the case of a simple credit card payment) to the browser in the form of a promise:

self.addEventListener('paymentrequest', event => {
  event.respondWith(new Promise((resolve, reject) => {
    // do something with the payment request data in the event

    // open a window for the user to interact with
    const windowClient = event.openClientWindow(...);
    // use `postMessage` to communicate with the window... etc

    // eventually get the user's payment credential and ...
    resolve(...);
  });
});

I'm exploring if this same model could be applied to the Credential Management API to provide extensibility features the Credentials Community Group needs. I've looked into the discovery mechanism that's in the spec today but found it a little too limiting.

The main problem is that it will only be triggered when a particular credential type is selected -- which, I believe, is unnecessarily restrictive, at least for our use case.

I would rather see selectable items show up in the credential chooser that map to a "credential handler" that can fulfill the request more quickly based on what the user selects.

Giving a bit more background may help show why this is desirable:

Imagine a scenario where people have N digital wallets. These digital wallets contain credentials or are capable of dynamically generating them based on certain requests. These credentials contain "verifiable claims" or statements made by third parties attesting certain statements are true about particular subjects. These wallets are provided as Web applications. People are able to visit websites that need these credentials for certain purposes, for example:

  1. Know-your-customer process for onboarding at bank websites.
  2. Proving educational degrees/training certificates for job application websites.
  3. Showing professional licenses for plumber/electrician/doctor/whatever to meet regulations/create prescriptions/so on.

The number of these types of credentials is unbounded -- and people may use different digital wallets to contain various different types.

Now, suppose a user could visit a digital wallet website and the website could ask them to grant the origin "credentialhandler" permission. Upon doing so, the website could then register names and icons for particular "profiles". These profiles are defined by the wallet provider however they see fit -- in whatever way helps them help a user manage their credentials.

Note: These credentials may be correlated with one another via some common identifier or not -- they may be generated on the fly by contacting credential issuers (the authorities that make the claims about a particular subject) via some protocol(s) that appropriately blind information and so on. No particular approach is prohibited or encouraged by this "credential handler" feature. A "profile" just sets the context for the user. It helps them both pick the digital wallet they want to use for the particular credential request and it tells the digital wallet that too. If the user needs to authenticate at the digital wallet before they can complete the request, it also tells the digital wallet "who" they are trying to do that as (and the digital wallet site may, in turn, use a local Credential to authenticate them).

Now, when the user visits a website that requires credentials that depend on a "credential handler", the previously registered "profiles" would show in the credential chooser like any other choice. But, upon their selection, they would not be immediately returned as Credentials themselves, but rather, the specific CredentialRequestOptions and the choice that the user selected would be sent, as an event, to the service worker (the credential handler) associated with the selection. The service worker's code would then process the request and respond to the event with a Credential, opening a custom UI as needed.

This approach allows a user to have as many digital wallets as they desire -- aggregating their "verifiable claims" credentials as they see fit. It also allows those digital wallets to innovate at the edges, implementing whatever mechanisms they see fit. All the while, providing a simple way for relying parties to request these sorts of credentials in one common way -- not caring about the specific digital wallet or protocols employed.

The Credentials Community Group is building a polyfill with this approach and would like any feedback on the concept -- any potential improvements, snags, thoughts on feasibility/security, ideas/collaboration on other areas where this approach may also help, and on likelihood in getting native browser adoption at some point in the future, should the polyfill prove successful.

dlongley commented 6 years ago

A rough demo of this approach can now be found here:

https://credential-repository.demo.digitalbazaar.com

dlongley commented 6 years ago

Forgot to mention that -- at TPAC -- it was briefly discussed that this approach may help with some of the federation/oauth use cases, e.g. sites providing oauth or similar credentials could implement credential handlers.

dlongley commented 6 years ago

Link to the Credential Handler API repo:

https://github.com/w3c-ccg/credential-handler-api

And the spec (largely mirrors Payment Handler):

https://w3c-ccg.github.io/credential-handler-api/