- From: Jeffrey Yasskin <jyasskin@google.com>
- Date: Thu, 6 Apr 2017 09:46:45 -0700
- 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>
- Message-ID: <CANh-dX=J8ysTSmJnCs=qFZR_zkShj9J4xynWxDhnaKXfxzWOeA@mail.gmail.com>
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