W3C home > Mailing lists > Public > public-webappsec@w3.org > April 2017

Re: Splitting "Credential Management"?

From: Jeffrey Yasskin <jyasskin@google.com>
Date: Thu, 6 Apr 2017 09:46:45 -0700
Message-ID: <CANh-dX=J8ysTSmJnCs=qFZR_zkShj9J4xynWxDhnaKXfxzWOeA@mail.gmail.com>
To: Mike West <mkwst@google.com>
Cc: Jake Archibald <jakearchibald@google.com>, "public-webappsec@w3.org" <public-webappsec@w3.org>, Dominic Battre <battre@google.com>, Václav Brožek <vabr@google.com>, Angelo Liao <huliao@microsoft.com>, Peter Dolanjski <pdolanjski@mozilla.com>, Daniel Bates <dbates@webkit.org>
On Wed, Apr 5, 2017 at 2:42 AM, Mike West <mkwst@google.com> wrote:

> On Tue, Apr 4, 2017 at 5:23 PM, Jeffrey Yasskin <jyasskin@google.com>
> wrote:
>>
>> 1) I'd like to start coming up with terms to distinguish "concept 1", the
>>>> thing you possess that gives you the right to do something, say, log in as
>>>> User X; and "concept 2", the proof that you have that thing. We're going to
>>>> need this for full federated credentials, SMS auth, and WebAuthn. Some
>>>> options: "credential"/"credential proof", "credential"/"attestation",
>>>> "credential generator"/"credential", "identity"/"credential". I lean toward
>>>> the first pair and will use those here, but I'm happy to take anything that
>>>> avoids conflating them.
>>>>
>>>
>>> I agree with you that "concept 1" and "concept 2" are different, but
>>> it's not clear to me that a developer would care. That is, if I'm
>>> understanding the distinction you're drawing, websites are always looking
>>> for a "concept 2", and it just happens to be identical to the "concept 1"
>>> in the case of passwords.
>>>
>>
>> I can buy that, in which case using "Credential" for the only concept the
>> page needs would be really nice. I'd still like to have the spec *talk*
>> about the distinction between the concepts so that devs and implementers
>> reading it easily understand that passing around your webauthn credential
>> isn't intended to hand out the private key.
>>
>
> Which spec?
>

https://w3c.github.io/webappsec-credential-management/#core.


> The current draft of the Credential Management spec says "From a
> developer’s perspective, a _credential_ is an object which allows a
> developer to make an authentication decision for a particular action." (
> https://w3c.github.io/webappsec-credential-management/#core). What would
> you like it to say instead? Should we call that a "credential proof"
> instead? If so, should we call the `Credential` object `CredentialProof`? I
> guess I'm ok with that if y'all think there's value in the distinction.
>

Given that we're only exposing concept 2 to Javascript, I prefer giving it
the shorter name, "Credential", even though that forces a more awkward name
onto concept 1. I think your definition of "credential" is fine, but that
we need to be clear in some other places, like https://w3c.github.io/
webappsec-credential-management/#concept-credential-store, that credentials
aren't just stored and retrieved verbatim: for non-passwords they'll
usually need to be re-generated from some secret (WebAuthn's private keys)
or capability (receiving SMSes/emails).

  a) Does store() merely record that a particular CredentialProof worked
>>>> for a site, or does it save a whole Credential? The first is consistent
>>>> with the current behavior for "federated", and would imply that a WebAuthn
>>>> CredentialProof could be stored too. If the second, we'd change store()'s
>>>> parameter to be Credential, and passwords might be the only valid argument.
>>>>
>>>
>>> `store()` delegates to an internal method on the interface, so it can do
>>> whatever makes sense for a particular credential type.
>>>
>>
>> While that's true
>>
>
> Technically correct is best correct. :)
>
>
>> it'd be nice if we had a consistent story for the meaning instead of a
>> bunch of one-off behaviors. I'm getting more comfortable with "this proof
>> worked for this site", and then we can figure out how to implement that for
>> each credential type.
>>
>
> I think that's a reasonable summary, yes.
>

I'll send you a PR to clarify that for store(). I don't have time this week
to try to add the rest of the wording about how the credential store might
include: a) things that can generate credentials, b) information about
which credentials the user is able to generate outside of the UA, and c)
which "active" credentials probably caused the current sign-in state. I
might be able to send that next week.

4) I think we'll need the UA to store a notion of:
>>>>   a) Which credentials successfully log into which identities for a
>>>> given site. Call these "known" credentials. An "identity" is just the
>>>> content of CredentialUserData.
>>>>   b) Which credentials have been used successfully since the most
>>>> recent requireUserMediation(). Call these the "active" credentials?
>>>>
>>>>   When get() is called with options that match exactly one "active"
>>>> credential, the UA should try to get a proof for that credential, whether
>>>> it's a password, a federated identity, or a WebAuthn authenticator. Some of
>>>> these will do their own mediation, but the UA shouldn't show an extra
>>>> chooser.
>>>>
>>>
>>> How would a user change accounts in this world? Like, consider Google's
>>> (absurd) multi-login? If `accounts.google.com` wanted to allow you to
>>> sign in as `user2` when you're already signed in as `user1`, we support
>>> that today by forcing a chooser in cases where we don't have a single,
>>> unambigious credential of the type you're asking for.
>>>
>>
>> A user would *change* accounts by having the site call
>> requireUserMediation().
>>
>
> How would the site know to do that? I suppose there would always be a
> "Change account" button or something similar?
>

Yeah, like there is for Google's multi-login.


> *Maybe* an extra argument to get() that forces mediation but doesn't
>> otherwise clear the active set? ....
>>
>
> I was thinking about this as well this morning. It would probably make
> sense (and make things less opaquely-named) to replace the `unmediated`
> flag with something like:
>
> ```
> enum MediationRequirement {
>   "without-user-mediation",
>   "whatever",
>   "with-user-mediation"
> };
>
> dictionary CredentialRequestOptions {
>   MediationRequirement mediation = "whatever";
> }
> ```
>
> Maybe with a better name for that middle one...
>

That works for me. I'll let you know if I think of a better option.

For the name, "if-ambiguous" or "if-necessary"? This'll always be written
as {mediation: "without-user-mediation"}, so we might be able to drop the
"mediation" from the enum-values.


> I was just talking with Jake (CC'd) about this this morning; I think we
> agree that it makes sense to put together a more general controller
> interface from which FetchController can derive (and which we could use
> directly).
>

https://github.com/whatwg/dom/pull/434 == \o/

5) The credential store's different pieces might have different lifetimes:
>>>>   a) Passwords and UA-stored private keys need to survive "clear
>>>> browsing data", and so they need more user approval to be stored.
>>>>   b) Knowledge that the user has a removable WebAuthn authenticator or
>>>> has used SMS auth with a particular site can be cleared with a site's
>>>> cookies, and so maybe doesn't need any user approval to be stored.
>>>>
>>>
>>> What's the relevant distinction between things in a) and b) that would
>>> lead you to treat them differently?
>>>
>>
>> If you delete (a), the user's ability to log into the site completely
>> goes away. If you delete (b), the user might have to do more navigation to
>> get back to the site, but they can still log in.
>>
>
> Ok. So you'd treat the latter as similar to cookies, as they don't in
> themselves constitute the entirety of the credential, and can be easily
> regenerated. I see.
>

I was thinking of them like browsing history, but cookies would work too. I
have more opinions about that choice, but as I believe it doesn't affect
the spec, I'd rather discuss them later.

Jeffrey
Received on Thursday, 6 April 2017 16:47:40 UTC

This archive was generated by hypermail 2.4.0 : Friday, 17 January 2020 18:55:00 UTC