Re: Coming back to CREDENTIAL.

Hi Mike,

Great to pick this up again. A point of clarity, I am a member of the
Credentials CG but have not a particularly active one and I have only a
very shallow understanding of the technical work the group is doing so
please consider my input as mine and not a voice of the CG.

Comments inline:

On 31 July 2015 at 11:00, Mike West <mkwst@google.com> wrote:

> I've let the credential management API discussion go fallow over the last
> month or so; let's pick it back up.
>
> timeless provided some excellent feedback at [1] that I really appreciate.
> I'll work through that in the near future. Likewise, I owe the Credentials
> CG more detailed responses to the thread that I let die at [2]. Let me pick
> that back up in the hopes of coming to something like resolution. I'll go
> through the "discussion points" from [3] line-by-line below, but first I'll
> back up a second to discuss the problems I actually want to solve, as I
> think that will help reframe the discussion:
>
> 1. I want to make it easy for users to use password managers, as they have
> significant advantage over other methods. Likewise, I want it to be easy
> for password managers to help users sign in.
>

This scope may be a good place to stop. This is a quick win and solves the
biggest issue, passwords. Perhaps federation can be dealt with in v2?


>
> 2. I want to encourage usage of federated sign in mechanisms, as they have
> interesting properties in relation to passwords. They're certainly not
> perfect, but in various cases they can be a big step up in terms of
> security. The first baby step is giving the browser an understanding of
> what's going on by allowing a site to store federated credentials. The next
> obvious step would be to natively support some set of protocols (OpenID,
> etc).
>

Question 1: Origin bound federated credentials

The fundamental question here is whether these credentials should be
origin-bound. In my opinion making them so renders this part of the spec
fairly pointless because I still need to login (using my federated
credential) on each relying-party site and only then can the RP site store
the federated credential (or at least link it to the new origin that it is
now useful for).

Suggestion:

When a user establishes a session at an identity provider that identity
provider already has knowledge of which RP sites the user has authorised
with the IdP. So when the IdP stores the federated credential why can't it
also specify the origins that the credential is valid for? This could even
be a user-mediated step.

Example:

In the past I visited example.com (a RP that supports facebook.com as an
IdP) and select to "Login with Facebook". I am redirected to facebook.com
and login (if not already logged in) and authorise facebook to provide some
credentials of mine to example.com. Example.com stores the access token
provided by facebook.com under a unique user identifier provided by
facebook.com and will re-use this the next time I login to get delegated
access to facebook.com.

All standard OAuth stuff so far.

Now, I am using a different computer and a browser with the Credential
Management API when I visit anothersite.com (a RP that also supports
facebook.com as an IdP) and select to "Login with Facebook". I am
redirected to facebook.com and login and authorise facebook to provide some
credentials of mine to anothersite.com.

At this point facebook.com stores a FederatedCredential via the Credential
Management API with the origins facebook.com, example.com and
anothersite.com listed as authorised origins. (Note that example.com is
also in that list)

Later, I visit example.com again (for the first time on this other
computer) and example.com uses the Credential Management API get() function
to test if I have a federated credential for facebook.com. Because this
credential was stored by facebook.com with example.com as a
supported/authorised origin that same credential is returned.

Example.com is able to automatically log me in via the facebook.com API
using the same token it received the first time I setup the federated login
relationship between example.com because the FederatedCredential holds my
unique user identifier for facebook.com (as set by facebook.com).

Question 2:

How will we address getting credentials for federation protocols (like
OpenID Connect) as opposed to for named IdPs? A standard should promote the
use of other standards. If IdPs are using their own flavours of federated
login protocols then support for them should not be baked into this
standard at the expense of support for an open standard or protocol.

i.e. Support for get({protocols : ["openidconnect", "saml2"]}) or similar
should be prioritized over get({providers : ["facebook.com", "google.com
"]});

>
>
> 3. I want to provide a framework which is extensible enough to support
> device-level (but origin-bound) things like FIDO in the future. That is,
> you could imagine a `FidoCredential` subclass of `Credential`, with methods
> allowing a website to ask for assertions of various kinds.
>
> I'm certainly interested in cooperating with the Credentials CG and others
> where possible, insofar as those use cases overlap with these use cases I
> care about. As I'll note in #5 below, I think there's some amount of
> overlap with #2 above that's worth exploring. That said, I'm also very
> interested in deferring a detailed specification of grabbing data from
> third parties until after we've determined whether there's
> implementer/developer interest in the core functionality.
>
> In short, I'd like to ship the kinds of improvements to Chrome's password
> manager that we've been talking about for almost a year now. I hope we can
> reach agreement on that portion of the API relatively quickly, even if
> questions about future extensibility remain open.
>
> With that in mind, let's look at the discussion points from [3]:
>
> ## 1. Composability of Credentials:
>
> This seems like an aesthetic problem more than anything else, and I think
> the current document does a pretty good job addressing it. That is,
> something like the following seems like a fairly reasonable way of
> presenting an "Identity" credential to developers:
>
>     navigator.credentials.get({
>       "identity": {
>         "filter-key": "value",
>         "filter-key1": "value1",
>         ...
>       }
>     });
>
> That might return an IdentityCredential object with a number of properties
> hanging off of it, based on the various filters that were passed in.
> Technically, this gives you what you need, though I understand that you'd
> rather call the properties "credentials".
>
> I don't really understand the caching concern you're expressing here.
> Perhaps you could elaborate?
>
> ## 2. Remote Storage of Credentials
>
> I don't honestly know how the kinds of credentials that the Credentials CG
> wants to represent would be stored in the browser. Structured data is
> simpler to work with than free-form data, but we certainly have free-form
> storage mechanisms like IndexedDB whose backends we could repurpose. What
> data do you need to store? Does the browser need to store it, or can the
> requesting origin simply rely on its own Indexed DB or localStorage to
> persist the data it requires while offline?
>
> Let's push the workflow questions to #5 below, as I think they all fold in
> there.
>
> ## 3. Using our definitions, an IdentityCredential is just an identity
> that is composed of credentials. It is not a credential itself
>
> I think this is addressed in #1. This sounds like an aesthetic problem
> rather than a technical one: assuming you had a set of credentials bundled
> up in an object, storing that object (and therefore the credentials it
> contains) seems quite possible.
>
> As Brad noted in an earlier email, renaming things might be the right way
> to address these concerns. Suggestions for words other than "credential"
> for the top-level concept are welcome.
>
> ## 4. IdentityCredential can be locally or remotely stored, does that mean
> it has to inherit from LocallyStoredCredential?
>
> LocallyStoredCredential is probably unnecessary. I had hoped it would
> simplify the query process, but it probably introduces more complexity than
> it needs to. I'll drop it, and just move its properties to the subclasses.
>
>
> ## 5. Promises that resolve to navigations:
>
> I don't think we need this.
>
> In particular, if I strip away most of the detail regarding signatures and
> queries, it seems to me that the workflow discussed in [3] is very similar
> to the three-legged auth flows in OAuth: the user begins on A, is taken to
> B to perform some ceremony, and is brought back to A with additional data.
> I imagine this taking place in some sort of auxiliary browser UI, as
> opposed to navigating the current browsing context.
>
> That has a number of advantages, actually, as it would be quite possible
> to treat this kind of authorization window in a way that would make it more
> clear to users what was being asked of them. In an ideal world, this could
> also mitigate some kinds of phishing attacks, as something like
> SafeBrowsing would have more context when examining the page's content
> (e.g. "This page is declaring itself to be an auth endpoint. Why does it
> look so much like Facebook when it's being served from evil.com?")
>
> Doing the auth work in a separate context means that we can keep a simple,
> async, promise-based API for the relying party; it will simply wait until
> the user has walked through the auth steps in the auxiliary context, and
> the browser will hand it back some data.
>
> This certainly requires either that the browser understand the protocol
> (which is possible in the case of OpenID/OAuth), or that we provide an API
> which would allow the third-party to pass data back to the initial browsing
> context to resolve the Promise.
>
> Either way, this mechanism seems more reasonable than persisting or
> recreating data after/during navigation.
>
> ## 6. How does query matching work?
> https://github.com/w3c/webappsec/pull/292
>
> I think we're closer to resolution in the current document, as I've
> adopted most of what Adrian proposed for `get()`.
>
> ## 7. Can the origin property for an IdentityCredential refer to the
> origin that you have authorized its transmission to rather than where it
> originated?
>
> This worries me for reasons I've expressed in other threads. You'd be
> free, of course, to define your extension however you like, so if that ends
> up making sense for the use cases you care about, you can certainly specify
> it that way.
>
> ---
>
> This got long. Thanks for reading this far. Hopefully we can get this
> conversation spun up again quickly, and resolved equally quickly. :)
>
> [1]:
> https://lists.w3.org/Archives/Public/public-webappsec/2015Jun/0066.html
> [2]:
> https://lists.w3.org/Archives/Public/public-webappsec/2015Jun/0001.html
> [3]:
> https://docs.google.com/document/d/1tI0CJ4wAKKPQacrxOmTtl_GQUBeVtbg8e1ZSXs2SWag/edit?usp=sharing
>
> --
> Mike West <mkwst@google.com>, @mikewest
>
> Google Germany GmbH, Dienerstrasse 12, 80331 München,
> Germany, Registergericht und -nummer: Hamburg, HRB 86891, Sitz der
> Gesellschaft: Hamburg, Geschäftsführer: Graham Law, Christine Elizabeth
> Flores
> (Sorry; I'm legally required to add this exciting detail to emails. Bleh.)
>

Received on Friday, 31 July 2015 10:35:40 UTC