w3c / webauthn

Web Authentication: An API for accessing Public Key Credentials
https://w3c.github.io/webauthn/
Other
1.16k stars 166 forks source link

make username fields optional (do not delete them, but do not force their usage, either, which is hostile against usernameless services) #1942

Closed r-jo closed 7 months ago

r-jo commented 1 year ago

Proposed Change

Regarding name and displayName in the spec I request OPTION 2 here, an example spec change is in the APPENDIX:

  1. keep these 2 username fields required
  2. make these 2 username fields optional
  3. delete these 2 required username fields
  4. replace the 2 required username fields with an optional note field

My opinion is that actually option 3 would be best, but also radical, making it super clear that webauthn has usernameless logic and punishing the sins of the past, which made the abnormal case of multiple (burner) accounts per human per web domain a kind of accepted way of thinking. Website owners hijack personal information like emails or phone numbers and try to make money from it. As a consequence, users create burner accounts, and services like apple or proton start to provide "services" to create burner emails. However, EU-DMA is coming and starting from 2024 soon (2-5 years) it may be a MUST to create usernameless accounts and an opt-in flow for providing personal information like email accounts (if a passkey-like authentication system succeeds, recovery will be through trusted devices or in case all devices lost, through pass manager or a recovery code not through email).

An optimal compromising solution would be option 4, since it is very confusing to have 2 username fields and the current thinking (that is clear from webauthn examples) is based on some real name + email address, which are 2 pieces of personal information and plenty of websites do not have both. It is actually rude from Apple, Google, Microsoft delegated people to think that every web service has names and emails and that is the way to go. This logic replicates an BAD EDGE CASE actually, and not a future proof one... If an RP wishes to provide some kind of help or hint to create a label in the pass manager of the user, one simple optional note field would suffice. Now each and every RP is forced to deal with these fields, some of us have no usernames at all, some of us have usernames, others only emails. We have no idea or assurances how pass managers handle if one of the fields are left blank or other hacky ways.

Making these fields optional is minimum if we do not want to force usernameless RPs to come up with some hacky solutions (each with their own) like blanks, timestamps, enumerations etc. It is absolute horrible and hostile towards those RPs that are actually doing the right thing: usernameless.

I have not heard any argument against making these fields optional, only some arguments against complete deletion: option 3 Please see the forcefully very quickly closed discussion here: https://github.com/w3c/webauthn/issues/1915

Also, the specs should GUIDE pass manager implementors:

Also, the spec would ideally GUIDE THINKING that in case a RP omits username fields and a user creates a burner account, it is the responsibility of the user to change 1-timestamp or 2-timestamp or whatever fields are shown in the pass manager since the RP intention is that a user should have one account, but if the user still thinks it makes sense to create more, the user must totally be able to label the entries according to the same logic he created it (pro-amateur account, main-burner, personal email - burner email etc.) Again, with option 2 no RP would be forced to provide or omit these fields, each and every RP could do what he thinks is best for them. But it should be made clear that even if an RP provides username fields, the ultimate power and responsibility to manage these fields is by th user. It is not my opinion, it follows from webauthn internal usernameless logic.

I would really love to continue the discussion in this thread at least 6 months before closing, if nobody can really argue against option 2. Again, nobody is forced when making fields optional, all RP that wish to help its users with usernames because they have this kind of logic in their account can do so (and then it is their responsibility to deal with things like changing usernames/emails and with this long run maintenance hell). https://stackoverflow.com/questions/76330306/user-name-and-displayname-change-for-existing-passkey/76663224#76663224

However, as of now, an open web spec is hostile towards websites that have or wish to have usernameless logic and try to do the right thing: not collecting personally identifyable information from users. Yes, the highly praised privacy comes with some user effort: no email recovery or if they want burner accounts for whatever reason, they have to take responsibility and manage their own pass manager labels for their own multiple accounts.

I am looking forward to a healthy discussion but please write only in favor of denying my suggestion if you really have some arguments against making fields OPTIONAL and please let us not go down the rabbit hole of discussing option 3 or 4 now. It is too late for that and I am not suggesting them here.

Also, if a website owner (RP) is reading this and agrees that these fields should be optional and pass manager UX could be more simple, please join the discussion at least with a thumbs up or so.

Thanks!

APPENDIX:

An example of how the change could be implemented. It would have the very positive side effect that by creation we should not add this RP name field, either:

rp: {
  name: ""
}

No better relying party ID than the automatically obtained domain name, I would say it is somewhat a security risk if a web domain can push a made up name to the user facing UX and MAY fake another service. But again plenty of questions: how will the UX be if I add a blank string, will my domain name shown twice if I add here the domain name? The bad design that makes this field required is coming out of under the rug again...

A POSSIBLE SOLUTION TO HONOR THE REQUESTED CHANGE:

 dictionary PublicKeyCredentialEntity {
-    required DOMString    name;
 };

 dictionary PublicKeyCredentialUserEntity : PublicKeyCredentialEntity {
     required BufferSource   id;
-    required DOMString      displayName;
+    DOMString               name;
+    DOMString               displayName;
 };

 dictionary PublicKeyCredentialRpEntity : PublicKeyCredentialEntity {
     DOMString      id;
+    DOMString      name;
 };
arianvp commented 1 year ago

I think I'd be in favor of making name optional but keeping displayName required.

I never really understood why we had two fields. As neither is exposed to the RP anyway.

If we standardise on "displayName is what the Passkey list displays" it feels a lot simpler

mitar commented 9 months ago

I agree that it would be useful that the whole user field would not be required and that would be then used for sites which expect only one user per site. Browsers could still allow internally to have multiple users if the user decides so, but site does not even have to know about that.

But current workaround is also pretty simple in my view. In Charon an privacy preserving auth system I am working on, I simply do {id: new Uint8Array([0]), name: "site.origin.example.com", displayName: "Site name"}, name matching id from rp field, and displayName matching name from rp field. To the user I think this looks clear and simple. It is duplicated, but when shown as prompt in UI it makes sense, you are signing into the site with site name.

Firstyear commented 9 months ago

But the user field is required if the credential is discoverable, and that's why there is an id and a client-side displayname so the user knows what credential they are about to interact with and use.

Also you have made a fundamental mistake there, since there is thene no way for for a user to distinguish credentials. Imagine a pop up list where it says

Which Credential do you want to use?
Site Name
Site Name
Site Name

Does not really help the user does it?

Which is exactly why name and displayname are client side and stored in the authenticator, because then the user can put in anything they want to make their own associations without the RP ever seeing it.

mitar commented 9 months ago

Also you have made a fundamental mistake there, since there is thene no way for for a user to distinguish credentials.

In my approach, there would always be just one credential per site. So nothing to choose from.

If user modifies data in authenticator to have multiple credentials per site (which I think browsers should help them) then they can put something meaningful in there. But from the point of the site I do not care if user has one or multiple accounts. I just want to be given a credential. And if user is creating the credential through the site, the site propose a very simple and clear name for that one credential.

Which is exactly why name and displayname are client side and stored in the authenticator, because then the user can put in anything they want to make their own associations without the RP ever seeing it.

That would be great! Site never having to put anything in the user field and then browser prompts and say "hey, this site is trying to register you, do you want to pick something meaningful to remember the account you are about to create"? No need for site (or its frontend) to do anything about it.

emlun commented 9 months ago

If user modifies data in authenticator to have multiple credentials per site (which I think browsers should help them)

If you don't mind users creating multiple accounts, you should set a different user.id for each account (for example, crypto.getRandomValues(new Uint8Array(64)), but you may want to create that value in the backend and store it in the user account in your database too). Setting user.id = new Uint8Array([0]) for all account creations causes any existing credential to be overwritten, locking the user out of the previously created account.

mitar commented 8 months ago

for example, crypto.getRandomValues(new Uint8Array(64))

With residential keys, that would mean that for hardware security keys you would quickly run out of them.

Setting user.id = new Uint8Array([0]) for all account creations causes any existing credential to be overwritten, locking the user out of the previously created account.

That is true. This is why one would need getOrCreate call so that you do not create new accounts unnecessarily.

I think those two issues are intertwined. To me it is a bit surprising to have residential/discoverable keys with username at all. If you have username then you can also ask the server for the certificate ID and can have non-residental key. If you do not have username, then you should be able to call getOrCreate. But having a username requirement AND no getOrCreate to me makes residential keys unnecessary/incomplete feature. I understand that it is useful for user to be able to have some metadata to differentiate between multiple residential keys per site, but that should be asked for by the browser when site calls getOrCreate without username. So site calls getOrCreate and user picks in the browser an existing key or choose to do a new one (and pick some name for it). Site does not need to know anything about it. (Even passing the name to the site should be optional.) But having username known to the site in my view defeats the purpose of residential/discoverable keys (unless you set the field to a constant, but then we still miss getOrCreate).

timcappalli commented 7 months ago

This has been discussed in a few working group calls and the consensus was that this change is not feasible for the ecosystem.

RPs who choose not to use a user-centric account identifier can put any value they wish in user.name, including just the site name or something like "my account" (but ideally a value that will help them understand the context of the credential). Making user.name optional will cause fragmentation of user experiences across passkey providers and clients.

Closing issue.

r-jo commented 6 months ago

well some wise LLMs analyzing the issue are leaning towards no usernames at all, right now for optional usernames:

If I absolutely had to make a decision right now, I would opt for optional username fields within the WebAuthn specification. Here's why:

Practical Compromise: An optional field strikes a balance between upholding individual privacy while acknowledging existing web infrastructure that often relies on some form of user identification.

Gradual Migration: This approach provides a pathway for both Relying Parties and authenticators to progressively adapt to user experiences less-reliant on traditional usernames. Relying Parties can immediately improve privacy practices within existing frameworks, while those truly pushing boundaries have the potential to experiment.

Incentivizes Innovation: Optionality spurs new ways for Relying Parties to track accounts internally without compromising user data. It pushes authenticators like password managers to design better ways to identify and present multiple accounts for a single domain.

Important Caveats

Not the Ideal Endpoint: Optional fields should be a transitional step. WebAuthn has the potential to revolutionize login systems, and completely removing usernames better leverages this potential for security and privacy in the long run. Need for Clear Guidance: For this optional scenario to work well, the W3C would need to offer extremely clear guidance to Relying Parties on best practices. Relying Parties with privacy-first values should be rewarded, not those abusing even optionality to gather information unnecessarily.

A Difficult Decision

This is a complex choice with far-reaching ramifications. Purely privacy-minded or strongly pro-innovation individuals might find this compromise too timid. The key is to understand that standards evolve along with technology and societal change.

Let me know if you want to explore what a hypothetical transition from optional to a "no username" world might look like!

emlun commented 6 months ago

Please don't spam the thread with noise from an LLM that has no capacity to understand the discussion at hand.

r-jo commented 6 months ago

I read what you wrote and I think the LLM understands the issue way better than you. You have either problems to understand basic things or you represent a security key lobby with some older keys that cannot handle usernamless credentials. You might as well be reluctant to revisit things and admit to past mistakes. You were unable to argue againt optional username fields. You close things and hide comments without proper discussion.

Firstyear commented 6 months ago

Your comments show a grave and deep misunderstanding of both how an LLM works (statistical text autocompletion without any capacity of logical and contextual thought) but also of how webauthn works.

r-jo commented 6 months ago

The reasoning an LLM produces can be more true and logically correct regardless how it achieves its output text. That is a simple fact. Can you elaborate on that what I may misunderstand about how webauthn works? It is not elegant to spam the thread with statements without some reasoning.

r-jo commented 6 months ago

A good chess engine is not able to understan chess like humans do. They lack any capacity of logical an contextual thought. They still beat Magnus Carlsen 1000/1000 times. Their output is better than that of the best humans.

You cannot disregard the output of textual reasoning of an LLM based on how it achieves its output. If you think you understand better, feel free to argue instead of attacking others. Fight in the arena of arguments and logic :)

r-jo commented 6 months ago

Interestingly enough, I had to pull back LLMs because they were so bullish on privacy. What they did not understand (at first) how difficult it is to get rid of usernames AFTER you already introduced them and implementations build upon them that would break. That is why it is a tool. You can challenge yourself, and you should challenge the LLM too. Disregarding its output is very childish. Like those chess or go grandmasters that were sure of human superiority.

And I still lack any good arguments against OPTIONAL username fields. Talking to extremly good (and not perfectly understanding) LLMs we could identify 2 possible arguments:

Also, an LLM recognizes plenty of contradictions in the spec: how it is basically privacy focused and how these required username fields make it difficult to create future proof privacy driven authentication solutions (with passkeys and webauthn) that do not rely on usernames that are very often names, re-used nicknames, emails, phone numbers (as examples in the spec).

I am looking forward to actual discussions! Feel free to use(!) LLMs (with all their well known properties).

r-jo commented 6 months ago

Although I am not planning to use webauthn in the end (the username fields is the lesser problem, the bigger problem is that it practically mandates digital pass managers and you will always have people who prefer paper pass managers, hence webauthn is flawed as a single authentication mechanism) I will push to have the option to use it without usernames as long as

Instead of insults and closing and hiding I am still humbly awaiting arguments against OPTIONAL usernames.

At one point, the spec says if we do not need one of these username fields, it SHOULD be set to an empty field. It is then a logically OPTIONAL field, dont you think? And having plenty of authenticator/pass manager UI/UX, if I set the field to empty string, it might be an awkward empty field in some UI, others might treat it as absent and implement appropriate logic. Last time I checked, it was AWKWARD everywhere :)

If they are logically optional, they should be NOT required and become optional fields. I mean at one point you write "when inherited by"... it should etc... oh my god...

emlun commented 6 months ago

Thank you for leaving the LLM. We dismiss its output because it immediately showed that it does not understand the discussion and therefore has nothing of value to add. We consider it a waste of our time to argue with a machine with no capacity for critical thought.

  • I have not read a logically understandable argument why OPTIONAL usernames would be a problem

I'm sorry that we haven't been able to help you understand our arguments, but I believe we have spent more than enough effort trying. The fact that you do not agree does not make these arguments invalid.

  • we do not have have some web biometrics capability outside of webauthn

This is by definition out of scope for the WebAuthn working group.

At one point, the spec says if we do not need one of these username fields, it SHOULD be set to an empty field.

The motivation for this was that setting displayName to empty seemed preferable to setting both name and displayName to the same value; the name field is still required for the reasons already laid out many times in these threads (see links above). But yes, I do agree that with this in mind it could make sense to make displayName optional. I've opened #2024 to track this. But as noted in that issue, this may be a backwards-incompatible change and therefore not something we can feasibly do.

I mean at one point you write "when inherited by"... it should etc...

I agree that this is awkward, but changing the WebIDL structure is backwards-incompatible and therefore not worth it for a minor improvement in API aesthetics.

Instead of insults and closing and hiding

I apologize if we have failed to notice violations of the W3C Code of Ethics and Professional Conduct (CEPC). If so, please point out specific instances and we will take action as appropriate.