Re: Coming back to CREDENTIAL.

Before diving too deeply into the line-by-line, allow me to criticize my
proposal. :)

I think the layering is wrong. Putting a `protocols` item on
`PasswordCredential` basically binds that implementation to
`FederatedCredential` in a way that I'm not sure makes any sense. Perhaps a
static method on `FederatedCredential`
(`FederatedCredential::registerAsProvider()`?) would be better from a
conceptual standpoint.

On Wed, Sep 2, 2015 at 10:58 PM, Dave Longley <dlongley@digitalbazaar.com>
wrote:

>
> 1. Bob signs into IDP.com. 2. IDP calls
>> `navigator.credentials.store(new PasswordCredential({ id:  'Bob',
>> password: 'hunter2', protocols: ['X', 'Y', 'Z'] }));`
>> 3. Bob accepts the user agent's kind offer to store this credential  for
>> him.
>>
>> Then:
>>
>> 4. Bob visits every-idp.com.
>>
> > 5. every-idp.com calls `navigator.credentials.get({ 'federated': {
> 'protocols': [ 'X' ] } } )`
>
>> 6. The UA helpfully offers Bob IDP.com.
>>
>
> I don't understand how the browser knows to offer "IDP.com" to Bob.
>

I don't think it's possible to have a generic mechanism here, given the
differences in behavior between things like federations and things like the
IdentityCredently concept you've outlined. You'd need to define your own
synthesis mechanism for whatever kinds of credentials you care about adding
to the platform.

That said, the flow for origin-based federation is spelled out here:
https://w3c.github.io/webappsec/specs/credentialmanagement/#synthesis.
Adding a step 2.1.2 that checked `protocol` seems pretty straightforward.


> What piece of information does the browser use to determine that? Does
> the use of "protocols" imply that a credential can be used to
> fulfill credential requests at other domains? Does the browser simply
> look for a matching protocol string and then allow the selection of any
> credential that happens to list that protocol?
>

Yes, pretty much. I think we'll need to lock down the protocol names in
some way (e.g. is "OpenID Connect" the same as "OpenID" and "openid" and
"openidconnect" and etc?). Maybe an enum backed by a registry?


> What if the protocol isn't a cross-origin type of protocol ... or does
> this API assume that they all are?


It assumes that anyone claiming to support a protocol is doing so
cross-origin. Is there a use case for the opposite case?


> Should, instead, IDP.com be required to specify an additional flag that
> their credential should be made available to fulfill queries for
> matching protocols at other sites?
>

Isn't that what this is?


> Don't get me wrong, I'm all for something like this approach. With respect
> to the Credentials CG work, we have been asking for something just like
> this type of "cross origin" credential. We'd like RPs to be able to ask for
> credentials that aren't from the RP origin. Instead, they'd be obtained
> from an IdP (with the browser blinding the request).
>

Yes. I think our disagreements about the Credentials CG work are less
conceptual with regard to "getting stuff from somewhere else", and more
practical with regard to the properties of the data that's being sent.

The Credentials CG flow could look like this:
>
> 1. Bob creates an account at IDP.com.
> 2. IDP calls `navigator.credentials.store(new IdentityCredential({ ...
> }))`.
> 3. Bob's UA guides him through a UI for registering a
> decentralized identity associated with IDP.com (and a keypair for his
> device).
> 4. Bob accepts the user agent's offer to store this credential.
>
> Then:
>
> 5. Bob visits rp.com.
> 6. rp.com calls `navigator.credentials.get({ 'identity': { query:
> {email: '', favoriteCat: '', ...} });`
> 7. The UA offers Bob his decentralized identity, linked to IDP.com, which
> he selects.
> 8. The UA takes Bob to IDP.com, in a secure context, where Bob selects
> credentials that assert property values to fulfill the rp.com's query.
> 9. IDP.com calls `navigator.credentials.transmit({ Bob's selection })`.
> 10. The UA asks Bob to confirm sending his selection to rp.com.
> 11. The UA uses Bob's IdentityCredential (with a credentials property
> containing his selection) to fulfill rp.com's query. (The Promise
> returned by the `navigator.credentials.get` call gets resolved to this
> constructed IdentityCredential instance).
>

Assuming that step 8 through 11 take place in another browsing context,
this sounds superficially similar to what we'd need to do for
OpenID/OAuth/Whatever. Step 9 in particular needs to be worked out, but I'm
quite explicitly punting that discussion to v2 in this document. :)


> Does this seem like it would work to you? How do you suggest we go about
> building a polyfill for this on top of the polyfill you've got here?:
>
> https://github.com/mikewest/credentialmanagement/tree/master/polyfill


That polyfill is pretty much limited to accountchooser (and is seriously
out of date by now, sorry about that).

I think a polyfill for IdentityCredential would need to do something
vaguely similar (iframe (or pop up a window if you need user interaction) a
shim, and communicate with that shim via `postMessage`), but I don't have a
ton of input about exactly how that ought to work.

-mike

Received on Thursday, 3 September 2015 11:12:10 UTC