Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Supply an “intention" member in PublicKeyCredentialCreationOptions dictionary #1292

Closed
alanwaketan opened this issue Sep 4, 2019 · 16 comments

Comments

@alanwaketan
Copy link
Contributor

a) Proposed changes to the spec:

dictionary PublicKeyCredentialCreationOptions {
    …
    CredentialCreationIntention intention;
};

intention, of type CredentialCreationIntention
    This OPTIONAL member contains the purpose of the relying party to create the public key credential. This allows the user agent to better describe the intention in its own UI.

enum CredentialCreationIntention  {
    “sole-first-factor”,
    “alternative-first-factor”,
    “second-factor"
};

A public key credential created by this API can be used for various different purposes. This enumeration defines intentions as to how the about-to-create credential will be used.

sole-first-factor
    Indicates the intention is to use the public key credential as the only factor for authentication. If a password is used previously, this indicates the about-to-create credential will replace that password.
alternative-first-factor
    Indicates the intention is to use the public key credential as an alternative method for authentication. If a password is used previously, this indicates that either the password or the about-to-create credential could be used for any given authentication.
second-factor
    Indicates the intention is to use the public key credential as a second factor together with other factors for authentication. If a password is used previously, this indicates the about-to-create credential will be used together with that password.

b) Reasons:

The “intension" member is to describe the purpose of the relying party to create the public key credential, for example, a password alternative, a password replacement or a second factor. Such string is useful for user agents that provide a dedicated UI for instructing users to use WebAuthn, so that user agents can provide more context to their users of what this operation is intended to do instead of providing a generic string. For example, instead of “Use your security key with example.com”, user agents now could suggest “Do you want to create a second factor using your security key with example.com?”. From the user perspective, users can now reason what the user agent asks for instead of guessing. Even though relying parties could have already explained the intention to users before calling WebAuthn API, it is still very useful to channel this intention all the way to the screen where users are actually taking the final action.

@lgarron
Copy link
Contributor

lgarron commented Sep 4, 2019

While there are lots of knobs in the spec (user verification, platform auth, resident key), this kind of intention is definitely a useful level abstraction from a website implementation — we spent quite some time at GitHub trying to map the knobs onto recommended values for this "intention" abstraction.

One additional thought I have is that I've heard "passwordless" used to describe "usernameless" (used for both identification and auth) as well as "only replacing password/MFA" (used for auth but not identification). It would be useful if the spec made it easier to navigate those two possibilities.

@Kieun
Copy link
Member

Kieun commented Sep 5, 2019

Is this hint for the user agent to display appropriate messages to users during creation?
I think it's great to have such way to express the intention. Also, it would be better for us to have the same thing for get operation.

@alanwaketan
Copy link
Contributor Author

Yes, that's the purpose. As a generic message doesn't really help users to understand what's going on. We would like to say something more expressive.

@ve7jtb
Copy link
Contributor

ve7jtb commented Sep 6, 2019

I am OK with this if the UI people can wordsmith something that makes sense to users.
Something to discuss in Japan

@equalsJeffH
Copy link
Contributor

this would be duplicative of the meaning of certain groups of options' settings. we'd prefer to approach it differently and wil submit a PR to that effect in before the tpac session

@othermaciej
Copy link
Member

@equalsJeffH Could you explain in brief how you prefer to approach it differently? Seems like it would be good to decide between different approaches for a similar purpose before going to PR. Is there an issue or explainer that describes your approach, or at least what problem or use case motivated it?

agl added a commit to agl/webauthn that referenced this issue Sep 12, 2019
The aims of this PR (which is currently incomplete) are, firstly, to
provide more specific guideance for RPs about how to configure the
several options in WebAuthns and, secondly, to provide a reserve mapping
of options back to intents.

On the first motive: the feedback that we're getting from several RPs is
that the WebAuthn spec is dauntingly complex. They go into it with a
certain user experience in mind but the translation of that intent to
concrete options is extremely challenging. While third-party
documentation can also help address this, the spec should stand alone.

On the second motive: w3c#1292 contains a request from a browser to add an
extra option to translate the other options into a higher-level motive.
The hope is that, in defining a mapping fro high-level intent to
specific options, we also implicitly define the reverse mapping and so
browsers can also extract the intent from the options.

It is unlikely that the reverse mapping will be total, rather some
combinations of options will not map to any higher-level intent.
Considering that set is hoped to be useful.

This PR is not yet complete and is being submitted in its current form
ahead of TPAC to help inform the discussion around w3c#1292.
agl added a commit to agl/webauthn that referenced this issue Sep 12, 2019
The aims of this PR (which is currently incomplete) are, firstly, to
provide more specific guidance for RPs about how to configure the
several options in WebAuthns and, secondly, to provide a reserve mapping
of options back to intents.

On the first motive: the feedback that we're getting from several RPs is
that the WebAuthn spec is dauntingly complex. They go into it with a
certain user experience in mind but the translation of that intent to
concrete options is extremely challenging. While third-party
documentation can also help address this, the spec should stand alone.

On the second motive: w3c#1292 contains a request from a browser to add an
extra option to translate the other options into a higher-level motive.
The hope is that, in defining a mapping fro high-level intent to
specific options, we also implicitly define the reverse mapping and so
browsers can also extract the intent from the options.

It is unlikely that the reverse mapping will be total, rather some
combinations of options will not map to any higher-level intent.
Considering that set is hoped to be useful.

This PR is not yet complete and is being submitted in its current form
ahead of TPAC to help inform the discussion around w3c#1292.
@agl
Copy link
Contributor

agl commented Sep 13, 2019

We've heard from sites that the number of options in WebAuthn is confusing and that they have issues mapping from a user experience that they have in mind, to a concrete set of options.

This issue strikes me as the same thing in reverse: a platform having issues mapping from a set of options to a concrete intent.

While we could add an extra option to make the mapping to the intent explicit, really it should be encoded in the existing options if we nail down the translation. At that point, an extra "intent" option would, at best, be duplicative and could be contradictory, begging the question of what to do when there's a mismatch.

#1300 contains the start of an update to section 1.2 of the spec that seeks (although it is currently incomplete) to provide an explicit mapping from intent to options, and thus also define an implicit mapping in the other direction. I needs a lot more fleshing out, but we're hoping that it could satisfy this need.

@alanwaketan
Copy link
Contributor Author

alanwaketan commented Sep 18, 2019

We think it is a good idea to provide a guideline to map different options into a relatively limited set of high level intents. However, it is very hard to confirm the inferred intent from a set of options. For example, options { Platform, RKPreferred, UVRequired } can be used as either a first factor or second factor. It is up to the RP. And it will be very awkward that the user agent infers the combination as Passwordless* and thus suggests it in the UI to users while the RP itself actually suggests SecondFactor* in its UI. Also, it could be very subtle for RPs to tune the options to display a user agent UI they want.

Thus, we propose instead of deducing those high level intents from an option map, a high level intent member as described above should be provided not just to help user agents to phrase their UI but also to initialize those options. Here is the new proposal.


dictionary PublicKeyCredentialCreationOptions {
    …
    CredentialCreationIntention intention;
};

intention, of type CredentialCreationIntention
    This OPTIONAL member contains the purpose of the relying party to create the public key credential. This initializes authenticatorSelection to values that match the intention and also allows the user agent to better describe the intention in its own UI. Noted, values provided to authenticatorSelection will overwrite values initialized by setting this member.

enum CredentialCreationIntention  {
    “sole-first-factor”,
    “alternative-first-factor”,
    “second-factor”
};

A public key credential created by this API can be used for various different purposes. This enumeration defines intentions as to how the about-to-create credential will be used.

sole-first-factor
    Indicates the intention is to use the public key credential as the only factor for authentication. If a password is used previously, this indicates the about-to-create credential will replace that password. This value initializes authenticatorSelection to { residentKey: “required”, userVerification: “required” }.
alternative-first-factor
    Indicates the intention is to use the public key credential as an alternative method for authentication. If a password is used previously, this indicates that either the password or the about-to-create credential could be used for any given authentication. This value initializes authenticatorSelection to { residentKey: “preferred”, userVerification: “required” }.
second-factor
    Indicates the intention is to use the public key credential as a second factor together with other factors for authentication. If a password is used previously, this indicates the about-to-create credential will be used together with that password. This value initializes authenticatorSelection to { residentKey: “preferred”, userVerification: “preferred” }.

* Terms from #1300.


A few things to clarify:

  1. We have considered to add “re-authentication” to the enum, but we feel like it collapses a lot with “alternative-first-factor”. Also, it doesn’t seem to make any sense to set authenticatorSelection.residentKey to “discouraged" with authenticatorSelection.authenticatorAttachment being set to “platform”.

  2. For “Typing-free”, we think it is a separate topic than what we propose. What we propose is a way to describe the fundamental functionalities of the public key credential and set authenticatorSelection accordingly. “Typing-free” is more of a way of how the authenticatorSelection could affect RPs’ user experience, i.e. whether they would ask users for their username or not. We are very interested to assist RPs to make this relation more clear but not within this proposal.

  3. For getAssertion, we think the intention is very clear and the PublicKeyCredentialRequestOptions is less complex than PublicKeyCredentialCreationOptions, and therefore no further clarifications are needed. Of course, we welcome different thoughts on getAssertion and will like to improve it together.

@akshayku
Copy link
Contributor

akshayku commented Sep 18, 2019

While this is a nice idea, had we started afresh, this brings more confusion and incompatibilities to existing options.

Also, it is restricting the usage over time which can change over time for the RP. For example, if RP which chooses residentKey=preferred, UserVerification=preferred. And for now it uses these resident credentials it as second factor as its customers are hybrid. Some have older U2F keys and some have newer FIDO2 keys. It gives RP an option to migrate over time from second factor to sole first factor over time when all of it's users have such type of credential.

Point is we support these kind of transitions now and consolidating it to only one type of use case has a counter affect.

I am actually confused with definition of "alternate-first-factor" vs "sole-first-factor discussoin here and why does the difference is between residentKeys options above. UserVerification controls whether RP wants 2FA/first factor/alternate-first-factor. Resident keys reflect whether RP is going for usernameless/typing-free experience.

residentKeys=required, userverification=required -> mainlyl usernameless passwordless flows. Or sole-first-factor definition here. However, it can be used in second factor initially if RP wants to transition smoothly for its mixed variety of users.

residentKeys=preferred, userverification=required -> I am confused with this choice. Either you put residentkeys=discouraged/userverification=required if you don't want usernameless flows or RP puts above residentKeys=required, userverification=required for usernameless flows. I would love to understand more about this choice.

Now the other point that @agl mentioned was around what happens when there is a mismatch between options passed explicitly between this option and all other options. Which one takes precedence and why. And how to tell the RP that browser interpreted the mismatch it this way.

I am worried about these options are only narrowly defining some use cases are and not as flexible as specifying individual options as available and deployed by many parties.

I would put these clarifications and use cases to options mapping for an RP to understand. As it is attempted in #1300.

@Kieun
Copy link
Member

Kieun commented Sep 19, 2019

I agree with all of intentions to provide the way for RPs to set the intention more cleary. We might add very high level option like @alanwaketan suggested. Also, we can add recommendation (or guideline) in the spec for RPs to understand such options better like #1300.

But the issue is originated from the current defined terms or keywords for such options.
For example, existing options can be,
requireResidentKey : requireTypelessAuthentication.
userVerification : requireMultiFactorAuthentication.

So, rather than introducing very high-level describing options (mixed combination of existing options), it's better for us to introduce new members understandable easily.

@equalsJeffH equalsJeffH added this to the L2-WD-03 milestone Oct 9, 2019
@equalsJeffH
Copy link
Contributor

equalsJeffH commented Oct 9, 2019

From the 20-Sep-2019 TPAC WebAuthn F2F meeting (minutes):

@jcjones suggested:

  • Defining another, higher-level webauthn API (perhaps effectively "wrapping" the present webauthn API) whose methods are along the lines of secondFactorRegistration(), multiFactorTypingFreeRegistration(), etc. I.e., they map to the named use cases described in PR WIP: More explicitly document use cases. #1300.

  • The idea is that the algorithms for these methods will construct the webauthn API's PublicKeyCredentialCreationOptions or PublicKeyCredentialRequestOptions) as appropriate (freeing the web developer from having to determine how to set the options in order to yield the desired use case (which is the crux of this issue)), and call navigator.credentials.create() and navigator.credentials.get() using the appropriate options flavor.

  • @jcjones indicated he's work on a proposal for this approach. It may take the form of another spec referencing and conceptually wrapping the webauthn spec. The question of whether or not we would concoct wrapper functions for both registration and (re-)authentication ceremonies was raised. Intention is to tackle registration initially and evaluate whether also wrapping authn would be a win.

Note: A notion of a "destructive registration" was mentioned in the discussion (would be good to come up with a different name, it seems this is actually converting an account from a given authn mech to another one, rather than being destructive). The description is: an RP may wish to offer existing users the ability to register user-verifying authnrs and during the registration ceremony actually remove users' entries from the RP's password database. Account/deviceLoss recovery figures into this scenario. It was expressed that whatever solution emerges for this issue #1292 ought not impede, and hopefully support, this account-aithn-mech-conversion use case. (perhaps this ought to get added as a comment on issue #334).

@jcjones
Copy link
Contributor

jcjones commented Oct 10, 2019

To clarify, I actually think it would be nicer to define whole interface objects such as AnyPublicKeyCredential (and others) which could then be handled by Credential Management in simplified ways. That also makes API detection cleaner than wrapped functions.

@equalsJeffH
Copy link
Contributor

Hm, ok, thanks, that's an interesting aspect of the idea that I missed in the discussion.

fyi/fwiw, I do not think Credman's handling would itself become simplified or change much if at all. Credman already does not do "the heavy lifting" for any credential type. Such heavy lifting occurs in the Credential interface object's internal methods, whose implementations are supplied on a per-credential type basis.

IIUC, the new "interface objects such as AnyPublicKeyCredential (and others)"'s would need to supply implementations (i.e., algs) for the necessary internal methods ( notably [[Create]]() and [[DiscoverFromExternalSource]]() ). Are you thinking of crafting new standalone algs for the latter methods?

In any case, it would be interesting to examine extant examples of where a "higher level" Web API abstraction was built on, or beside or whatever, another Web API, if anyone knows of such to point to?

@equalsJeffH
Copy link
Contributor

on 2020-01-29 call: @alanwaketan is going to ask internally whether they wish to pursue this or not.

@alanwaketan
Copy link
Contributor Author

We came to a conclusion that we are not going to purse this proposal at this moment. We think this proposal has bundled too many concepts together and would potentially conflict with other options if not being specified clearly. And it would be a very complex job to specify the relations between this proposal and existing options.

Instead, a high level API as discussed above seems a more promising solution. Given the very subtle relationship between this proposal and the high level API, we think it would be better to close the issue at this moment.

We will file a new issue once we have a better idea that can both satisfy our needs and at the mean time narrow down the complexity.

@rmondello
Copy link

We’re OK to close this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests