RE: PR #384 CredMan Integration

Thanks Mike for the thorough reply!  I'll try to follow up with comments
tomorrow.

I've started, but failed to finish the promised PR.  I'll try to finish it
in the early am.

On Apr 11, 2017 4:06 PM, "Vijay Bharadwaj" <vijaybh@microsoft.com> wrote:

My 2c on this: I whole-heartedly agree with the approach you advocate at
the end of your email, of pulling out the pieces that we all agree on and
merging those in first. I would rather debate a small and contained set of
known unknowns than large philosophical issues.



My response to Alexei’s proposal was also in this vein: let us lock in our
gains where we can, so we can better quantify the risks and open questions
remaining. We may realize in the future that our present consensus was a
horrible mistake, but even in that unlikely event we are more likely to
reach a well-understood conclusion to the debate sooner. If we can capture
these consensus items in a PR now, we may have time for a more focused
iteration of debate in tomorrow’s call and during the following week.



*From:* Mike West [mailto:mkwst@google.com]
*Sent:* Tuesday, April 11, 2017 3:37 PM
*To:* Alexei Czeskis <aczeskis@google.com>
*Cc:* Anthony Nadalin <tonynad@microsoft.com>; Hodges, Jeff <
jeff.hodges@paypal.com>; public-webauthn@w3.org

*Subject:* Re: PR #384 CredMan Integration



Hey Alexei! Thanks for your feedback, I'm glad we're continuing the
conversation. Apologies for the ridiculous length, but it's midnight, my
brain is shutting down, and I'm giving up on making this shorter or more
coherent. :P



On Tue, Apr 11, 2017 at 6:05 PM, Alexei Czeskis <aczeskis@google.com> wrote:

I'm all for getting the spec done fast, for getting implementations out
fast, and for making the world a better place faster.  If we want to speed
things up, I'm not convinced that the PR as it is right now is the right
move.  I'm not simply arguing for making fast progress and accepting a
messy API landscape in return.  I'm arguing for not venturing into the
unknown to find the perfect -- in effect passing on the known-good.



I appreciate the time and consideration y'all are giving the proposal I put
forward in #384. I agree wholeheartedly with the admonition against putting
the perfect ahead of the good, and while I hope you'll accept a little more
discussion (and, unfortunately, probably a few long emails), I don't want
to hold you up unreasonably.



That said, I'd suggest that "the unknown" isn't as scary and dark as
it might look. Chrome is shipping the credential management API,
developers are using it today, and building up expectations about its use
that I think we would be well-served to consider and align with. You're
entirely correct to suggest that there are interesting questions to
consider, but, in my opinion, they're managable in a timeframe that I hope
y'all can support.



I believe that in its current form, the merge will cause questions that
will take a while to iron out.  I would suggest an alternate approach: hold
off on the merge until the proposal does not have as many unknowns.  Maybe
that means waiting until version 2.



I agree that merging #384 right now would be a bad idea, given the
sincere objections you and Dirk have raised. We should continue
conversations like this one to make sure we're on the same page regarding
the concepts we're trying to align.



In my opinion, the big reason to be hesitant about this merge is that it
takes us down the path of one single .makeAuthFactor() and one single
.getAuthFactor() methods.



I suspect you won't be shocked to learn that I think this is a big
reason to be excited about the proposal. :)



While I agree that it would be strange to request both a password and a
yubico-style security key assertion in a single call to `get()`, the single
entry-point approach seems like an essential component of the story for
more complicated authenticators that folks might trust as an authentication
vector in and of themselves. I tried to sketch this out in more detail at
the end of my response to Dirk's email earlier this week:
https://lists.w3.org/Archives/Public/public-webauthn/2017Apr/0147.html
<https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.w3.org%2FArchives%2FPublic%2Fpublic-webauthn%2F2017Apr%2F0147.html&data=02%7C01%7Cvijaybh%40microsoft.com%7Ce8c9319e12f24c03caf308d4812b7cae%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636275471156232104&sdata=Nq4e31ax22lPKqAnI7Nanj4Ei52YkjDDsC1wj4kvfKA%3D&reserved=0>



For example, for usernames and password -- the browser manages identities
and shows the UX for selection.  For authenticators such as phones, the
phone does.  I'm not sure what the right way to show UX is there.  Maybe
it's not a problem for Edge that might just call Hello, but I'm not sure
what cross-operating-system browsers such as FF and Chrome would do.



Long term, I think this is a problem we very much need to solve: it
should be possible for a developer to transition from passwords to
something stronger without throwing multiple, disconnected dialogs up in
the user's face.



Shorter-term, I think we have two options:



1.  We enforce a disconnect between the credential types that the user

    agent knows about a priori, and those that require an external

    service for discovery (this might boil down to rejecting calls like

    `get({ password: true, scoped: { ... })`).



2.  We launch something strange to support these kinds of requests, and

    iterate on it. The credential management spec currently suggests

    something like displaying the known credentials in a

    user-agent-controlled chooser, along with a friendly name for the

    type of credentials that could be discovered. That is, given the

    above call to `get()`, the chooser might render:



    *  User/Password 1

    *  User/Password 2

    *  Use a Security Key



    And clicking the last item would nicely push you off to the

    authenticator for the real decision (and, presumably, make all

    your security keys flash).



The second option doesn't seem terrible to me, and the first option
leaves obvious room for future improvement.



Or for example, consider during the create account phase when acme.com
<https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Facme.com&data=02%7C01%7Cvijaybh%40microsoft.com%7Ce8c9319e12f24c03caf308d4812b7cae%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636275471156232104&sdata=bo%2BZ6%2Fh07jMvaTTho7rnmZqN5IecCq%2B9CxLGcBMUVZ8%3D&reserved=0>
tells the browser that it'll accept a username/password/oauth token from
Google or Facebook or an Authenticator -- what does the browser draw then?
How does the user choose?



I think this boils down to the same question as above, with the
slight twist that we're talking about sign-up rather than sign-in. Here, I
agree with you that punting is a pretty reasonable option, as I don't
think we've worked out a good story for sign-up with the existing
credential types, much less new ones.



https://github.com/w3c/webappsec-credential-management/pull/72
<https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fw3c%2Fwebappsec-credential-management%2Fpull%2F72&data=02%7C01%7Cvijaybh%40microsoft.com%7Ce8c9319e12f24c03caf308d4812b7cae%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636275471156242112&sdata=AyRXhzuY2M3YrDekd2p2BhZd4YElzk4oqaYOqevLghU%3D&reserved=0>
is
something of a first step in this direction; aligning `Credential` object
creation under a single, async constructor gives us a lot of room for
future improvements.



We haven't figured out what it means to not require user mediation for
webauthn, because there are lots of details.



The top of that response to Dirk's email that I mentioned earlier
addresses some of his concern with `requireUserMediation()`, and tries to
explain how I see it fitting into the story we'd tell developers around the
various kinds of user-presence semantics y'all are discussing. Do my claims
there make sense?



The relationships between user accounts and passwords is 1:1 -- but that's
not the case for users and authenticators.



My understanding is that the relationship between users and public keys is
1:N: `mkwst@google.com` on `google.com
<https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fgoogle.com%2F&data=02%7C01%7Cvijaybh%40microsoft.com%7Ce8c9319e12f24c03caf308d4812b7cae%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636275471156242112&sdata=P5lbcK685l4t5X9QzzysYw8j91Ga5OLTHnnUhG8c364%3D&reserved=0>`
has a few security keys, all of which are valid for the account. The
relationship between public keys and users, on the other hand, is 1:1: each
of `mkwst@google.com`'s public keys for `google.com
<https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fgoogle.com%2F&data=02%7C01%7Cvijaybh%40microsoft.com%7Ce8c9319e12f24c03caf308d4812b7cae%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636275471156242112&sdata=P5lbcK685l4t5X9QzzysYw8j91Ga5OLTHnnUhG8c364%3D&reserved=0>`
is unique, and cannot be used to validate any other user.



It's the latter relationship that seems important here: just as
the username/password credential unambiguously identifies a single
relationship, so does the public key/assertion credential.



I can keep going,



Please do! I'd rather have your questions as known unknowns, rather
than leaving the Rumsfeldian specter of unknown unknowns hanging over
the discussion. :)



but the point is that there are questions here -- lots of them.  It will
take a while to iron them out, to play with implementations, to iterate, to
refactor, to make a UX that users understand.  On the other hand, we pretty
much know how to build webauthn in its current form.  It's self-contained
and doesn't depend on any outsides specs.



I agree with you that shipping the current spec is likely going to be
faster than shipping something different than the current spec, if only
because we haven't yet agreed upon what "different" means. :)



That said, I believe that the proposal in #384 is not that far off
from what's in the current spec. The public API surface shifts in a number
of ways, but I don't honestly think that the public API surface is
where implementations are going to find most of the challenge. In Chrome's
terms, I suspect that the Blink layer (IDL, bindings, etc) will be
managable either way you go, while the //content layer changes will be
more substantial. I think this is reflected in the PR: the IDL shifts
quite a bit, while the attestation and assertion algorithms barely change
at all.



Perhaps JC, Anthony, Angelo, etc can weigh in with their thoughts as
vendors with existing (partial?) implementations?



If I understand the proposed merge correctly, it also requires that the
credential management API be changed.  So now, before any webauthn api can
be put out, the credential management API must be refactored and only then
can webauthn be developed.  Also, let's not forget that there are websites
that depend on the current credential management API.



I don't think this is the case. While putting together the PR that
we're discussing, I did rewrite the credential management spec to refine
and improve the extension points and internal algorithms, but the public
API surface remained intact. The only visible change I can think of at
the moment is the removal of the `SiteBoundCredential` intermediate
interface, which seems like a good idea regardless.



The thought exercise of putting the PR together sparked some
good discussion about additions that we could make to the API that would be
good for existing developers (the `create()` proposal above is one), and
clarifications that might likewise be useful in the status quo (the
naming/structure of `unmediated`, for instance). These latter changes would
make it easier to merge webauthn, to be sure, but they seem useful in
themselves, and I expect we'll run with them regardless of the outcome of
this discussion.



The PR is not the only possible credman merge proposal.  Here is another
(if you don't like this one, we've got another):



I'm sorry; Ugh. This is a long email, and I haven't even gotten to your IDL
yet. Rather than going line-by-line through it, I'll throw out some
high-level opinions. At first glance, I think that splitting the top-level
into `navigator.credentials.bearer` and `navigator.credentials.publicKey`
feels a bit like the worst of both worlds. It conjoins two distinct APIs
together through the use of a common noun ("credential"), but that noun
seems to be a homograph: one side of the API uses "credential" to mean "the
thing you give to the website in order to authenticate a user", while the
other side uses "credential" as metadata adorning the actual authentication
bits.



Contrast that with #384, which aims to unify the usage of "credential" by
inverting the relationship between `ScopedCredential` and
`AuthenticatorResponse`. Developers get a `Credential`, whatever API they
call, and can send it up to the server for processing.



Perhaps more foundationally, though, this split makes it quite difficult to
create a single entry-point to obtain credentials for a user, as we
discussed above. Again, I see that as a clear selling point of the proposal
you're countering.



Practically, as you noted above, there are websites that depend on the
current credential management API. There are practical implications to
pulling that API out from under existing users by moving
`navigator.credentials.get()` to `navigator.credentials.bearer.get()`. It's
painful for developers, and I think that kind of change needs more
substantial justification than expedience. Ideally, we could avoid this
kind of churn.



Regarding the claimed advantages:



1.  Size of change to existing APIs: It's not clear to me that this is a
smaller change to webauthn than #384, and it's pretty clearly a
substantially larger change to existing users of `navigator.credentials`.



2.  Store: I discussed `store()` a bit in the response to Dirk earlier this
week: right in the middle of https://lists.w3.org/Archives/Public/public-
webauthn/2017Apr/0147.html
<https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.w3.org%2FArchives%2FPublic%2Fpublic-webauthn%2F2017Apr%2F0147.html&data=02%7C01%7Cvijaybh%40microsoft.com%7Ce8c9319e12f24c03caf308d4812b7cae%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636275471156242112&sdata=kWpycGuw9%2BCQWZzzd3JsgtubSZ1s%2FtaENJCBdP7YBm8%3D&reserved=0>.
I hope that clarifies the way I'm approaching it.



3.  Mediation: Likewise, this is the last piece of that email.



4.  Developers will only have to understand `credential`: This cuts both
ways, as developers familiar with the credential management spec can't
apply that knowledge to the new `publicKey` branch of the API, and in fact
their existing experience will work against them due to the distinctions in
usage of "credential".



5.  New methods can be added to `publicKey` without considering `bearer`:
It's quite possible to hang methods off of a particular credential type if
they only apply to a certain credential type. Moreover, I don't think this
division actually removes the necessity to consider generalizing a given
API, it just punts the question down the road. *shrug* I see this as a
long-term drawback for short-term gain, in other words. :)



All that said, I'd like to pull out some points where I think we agree.
Perhaps we can start with these smaller changes first:



1.  Allowing both attestations and assertions to derive from

    `AuthenticatorResponse` is a good idea. Let's extract this into

    something that we can merge on its own to improve the status quo.



2.  `PublicKeyCredential` is a better name than `ScopedCredential`!



3.  `PublicKeyCredential` inheriting from `Credential` (and therefore

    changing the types of both `id` and `type` properties) seems like

    a good step towards talking about the same thing when we say

    "credential".



All that is a somewhat negative note to end up on. Hrm. So instead, I'll
say again that I appeciate the time y'all are spending on this with me, and
I'm pretty confident that we'll end up with something better and cleaner
than either of the proposals on the table through this discussion.



Thanks for your attention! Apologies for the length... I'll try to more
agressively trim future responses. :)



-mike

Received on Wednesday, 12 April 2017 05:36:24 UTC