# Webauthn support

**URL:** https://meta.discourse.org/t/webauthn-support/126454
**Category:** Feature
**Tags:** rfc
**Created:** [August 21, 2019, 11:20pm UTC](https://meta.discourse.org/t/webauthn-support/126454 "2019-08-21T23:20:40Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![featheredtoast](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/featheredtoast/32/116994_2.png) [@featheredtoast](https://meta.discourse.org/u/featheredtoast)
#### Post date: [August 21, 2019, 11:20pm UTC](https://meta.discourse.org/t/webauthn-support/126454/1 "2019-08-21T23:20:40Z")

</div>

# Webauthn RFC

This topic aims to document the Discourse project goals around FIDO2 / Webauthn authentication.

### Why?

Adding Webauthn support to Discourse will increase the security of user accounts, enabling easily acessible password-less accounts using their devices secure features, like a smartphone fingerprint reader.

### Authentication Methods

- Webauthn as a second factor authenticator (act like a Google Authenticator alternative)
- Webauthn as a first factor authenticator (act like a social login alternative)
- Webauthn as a multi factor authenticator (username-less login)

### 

#### Webauthn as a second factor authenticator

This will allow a Discourse user, who already has an active account to use Webauthn as a 2FA, where today we only support TOTP.

Any Webauthn method can work here, be it device biometrics (fingerprint header in Android, Windows Hello laptop), a device secure chip (TPM, secure enclave) or a hardware key (like a [Yubikey](https://www.yubico.com/)).

This would be availiable for every user who browses with:

- Microsoft Edge on Windows, using Windows Hello (with facial recognition, fingerprint reader, or PIN)
- Chrome on macOS, using Touch ID
- Android Phone
- Laptop/Desktop/Phone + Physical Key (Yubikey, Google Titan)

 ![webauthn-2fa-mockup](https://global.discourse-cdn.com/meta/original/3X/2/c/2cbeb46ad38e314084d370a8303ad053d0980728.png)

#### Webauthn as a first factor authenticator (password-less accounts)

Allows a user to sign in to their Discourse account using the Webauthn authentication as an alternative to a password. If a first-factor authenticator is set up, the user will be prompted to use the authenticator in lieu of a password.

The same authentication methods for second-factor authentication will work for first-factor authentication: biometrics, secure chip, or hardware key.

##### Register Flow

 ![image](https://global.discourse-cdn.com/meta/original/3X/0/d/0d2f78e3a43d42ab8e1f0b9b65c71fd4785daf66.png)

 ![image](https://global.discourse-cdn.com/meta/original/3X/e/4/e4fccc9f8b0d00829cb8ccce1cd1865869a8a10a.png)  
No password field

 ![image](https://global.discourse-cdn.com/meta/original/3X/2/6/26dff93090fe3f59ee7fcf380cd0e21ed13b037e.png)

##### Login Flow

 ![](https://global.discourse-cdn.com/meta/original/3X/e/2/e2c8f69dd68fc99fc51c02a502a639a0d62e08ab.png)

 ![](https://global.discourse-cdn.com/meta/original/3X/6/4/6413235b21b9f514723297a0da14699d7c23498e.png)

 ![](https://global.discourse-cdn.com/meta/original/3X/4/9/490bf4aa3ae253cd28b5da154613cbff27fb1ad5.png)

#### Webauthn as a multi factor authenticator (username-less logins)

Will expose an alternative login method that only prompts for Webauthn input. The registered security key will additionally pass user ID information to the Discourse server.

This authentication method currently requires a modern authentication key (eg a Yubikey 5) plus Google Chrome 76+, since it relies in a feature called “Residential Keys”. Since this stores data on the authenticator there can be limits, for example Yubikey 5C can only store up to 25 of those.

##### Register Flow

Those flows are an evolution from the one for password-less logins, not a separate login flow. This allows for a iterative implementation.

 ![image](https://global.discourse-cdn.com/meta/original/3X/0/d/0d2f78e3a43d42ab8e1f0b9b65c71fd4785daf66.png)

 ![image](https://global.discourse-cdn.com/meta/original/3X/c/6/c613287cb30d3666e2d96292f7731d01cfbea9f2.png)  
No password field, adds extra checkbox for Residential keys usage

 ![image](https://global.discourse-cdn.com/meta/original/3X/2/6/26dff93090fe3f59ee7fcf380cd0e21ed13b037e.png)

##### Login Flow

 ![](https://global.discourse-cdn.com/meta/original/3X/e/2/e2c8f69dd68fc99fc51c02a502a639a0d62e08ab.png)

 ![image](https://global.discourse-cdn.com/meta/original/3X/9/2/92f83d0760737a48b1e8387c7be968c8b1f0e3aa.png)  
If the username is left blank we will try to fetch a `user_id` from the autheticator

 ![](https://global.discourse-cdn.com/meta/original/3X/4/9/490bf4aa3ae253cd28b5da154613cbff27fb1ad5.png)

### References

> **[Web Authentication: An API for accessing Public Key Credentials - Level 2](https://www.w3.org/TR/webauthn/)**

> **[Web Authentication: An API for accessing Public Key Credentials - Level 3](https://w3c.github.io/webauthn/)**

> **[Web Authentication](https://www.yubico.com/authentication-standards/webauthn/)**
>
> Learn the definition of Web Authentication and get answers to FAQs regarding: What Web Authentication is and how it works.

### Demos

> **[Bitwarden Passwordless.dev - Passwordless Authentication | Bitwarden](https://bitwarden.com/products/passwordless/)**
>
> Embrace passkey & passwordless authentication with Bitwarden Passwordless.dev, empowering devs to build seamless login experiences with standard FIDO passkeys.

> **[Web Authentication (WebAuthn) Credential and Login Demo](https://www.webauthn.me/)**
>
> Try the Web Authentication demo to register a credential and login with biometrics. WebAuthn spec enables public key-based credentials for securely authenticating users using hardware authenticators.

[https://webauthndemo.appspot.com/](https://webauthndemo.appspot.com/)

[https://webauthn.io/dashboard](https://webauthn.io/dashboard)

> **[Yubico demo website](https://demo.yubico.com/webauthn/)**

## Resources

[https://github.com/cedarcode/webauthn-ruby](https://github.com/cedarcode/webauthn-ruby)

[https://medium.com/@herrjemand/introduction-to-webauthn-api-5fd1fb46c285](https://medium.com/@herrjemand/introduction-to-webauthn-api-5fd1fb46c285)

> **[Guide to Web Authentication](https://webauthn.guide/)**
>
> An introduction to Web Authentication (WebAuthn), the new API that can replace passwords with strong authentication.

---

<div class="post-metadata">

### Author: ![Martin\_Brennan](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/martin_brennan/32/157653_2.png) [@Martin\_Brennan](https://meta.discourse.org/u/Martin_Brennan)
#### Post date: [August 23, 2019, 9:20am UTC](https://meta.discourse.org/t/webauthn-support/126454/2 "2019-08-23T09:20:15Z")

</div>

Thank you for this RFC, it is quite thorough! I had a thought though about the flow for using Webauthn as a second-factor authentication method with a normal username & password login. When I have 2FA using TOTP I get this modal when I log in:

 ![image](https://global.discourse-cdn.com/meta/original/3X/6/8/68218dbaee85148bb00d0f43338a7d63fc6662f6.png)

If a user has both TOTP codes enabled AND Webauthn authenticators, what would the flow be? Would the user decide in this modal whether they want to use Webauthn or their 2FA token? Or if this would be too onerous? Maybe Discourse could default to asking for Webauthn if the user has it set up and the browser supports it, then fall back to 2FA?

**Existing Implementations**

Twitter:

 ![image](https://global.discourse-cdn.com/meta/original/3X/c/3/c323b496377d73453c2f286b5a1a8d783534628a.png)  
 ![image](https://global.discourse-cdn.com/meta/original/3X/d/a/da3715d464b9c7a1d137b64768ad4213e421c484.png)  
 ![image](https://global.discourse-cdn.com/meta/original/3X/6/3/6376a450c694bff150db15192409cc964fc275e7.png)

Github:

> **[GitHub supports Web Authentication (WebAuthn) for security keys](https://github.blog/news-insights/product-news/github-supports-webauthn-for-security-keys/)**
>
> The WebAuthn standard for security keys is making authentication as easy as possible. Now you can use security keys for second-factor authentication on GitHub with many more browsers and devices.

 ![image](https://global.discourse-cdn.com/meta/original/3X/5/4/5409b0423666d00ddf18b18b734d742bec00ce13.png)  
 ![image](https://global.discourse-cdn.com/meta/original/3X/d/4/d475ee95f706e1cd231d7ccca59ac6b17055920a.png)

Google Account:

 ![image](https://global.discourse-cdn.com/meta/original/3X/0/5/050eac30ca437ab14f8c7a65865d0490a956695b.png)  
 ![image](https://global.discourse-cdn.com/meta/original/3X/c/5/c5ba9a0a0cc3a87cd18e4414feb0058d57095334.png)  
 ![image](https://global.discourse-cdn.com/meta/original/3X/5/8/586041abc39f2edd271beb29d8a7b1e09b77e2d7.png)

---

<div class="post-metadata">

### Author: ![featheredtoast](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/featheredtoast/32/116994_2.png) [@featheredtoast](https://meta.discourse.org/u/featheredtoast)
#### Post date: [August 23, 2019, 3:43pm UTC](https://meta.discourse.org/t/webauthn-support/126454/3 "2019-08-23T15:43:31Z")

</div>

> [@Martin\_Brennan](#):
>
> Discourse could default to asking for Webauthn if the user has it set up and the browser supports it, then fall back to 2FA

Yeah that seems to becoming the standard way to implement web authn, and I quite like the login flow. I definitely think we’ll be going in that direction here as well.

---

<div class="post-metadata">

### Author: ![Martin\_Brennan](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/martin_brennan/32/157653_2.png) [@Martin\_Brennan](https://meta.discourse.org/u/Martin_Brennan)
#### Post date: [August 24, 2019, 7:20am UTC](https://meta.discourse.org/t/webauthn-support/126454/4 "2019-08-24T07:20:48Z")

</div>

Thank you Jeff, that makes sense. A few other thoughts today after more investigation:

**First Factor Authentication**

- If a user signs up for a Discourse account using Webauthn as a first factor authentication method, would be there a way later on for them to change to use a password instead? And if so, would the Webauthn authentication they’ve set up then fall back to being a regular 2FA method, until whichever time they want to remove it?
- If the Webauthn was used as a first factor method, would it still show up in the UI under second factor preferences, and just not be removable?
- Would it also be fair to say that the user the user to set up social logins in the same way they are prevented from doing so if they have 2FA enabled?
- I’d imagine the section of the user preferences where the reset password email is sent would change too, as they would not have a password using first factor:

 ![image](https://global.discourse-cdn.com/meta/original/3X/9/8/98a5d4fad03687a62c7404c8dc1b705250277b9a.png)

---

<div class="post-metadata">

### Author: ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)
#### Post date: [August 26, 2019, 1:08am UTC](https://meta.discourse.org/t/webauthn-support/126454/5 "2019-08-26T01:08:57Z")

</div>

Text wise, I don’t like using the term “Web Authn” I think it is confusing to end users, just use “Security Key” or something like that.

I would very much like to avoid even thinking about “First factor / passwordless” auth here, to me we got to ship this feature and live with it for 3-4 months before even considering this.

Especially since we already support log in via email, so you can technically forget your password.

I agree the flow should be … if you can and have the apis and a webauthn key, try webauthn first, but give user an escape hatch. Also keep in mind you may have multiple webauthn devices, I would follow what google do here for dealing with this. (A choose another option link or something)

One thing that I do think about longer term in a separate item, we could use “discourse app” for 2fa which would be pretty cool @pmusaraj. That could make use of 2fa much more ubiquitous.

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [August 26, 2019, 1:14am UTC](https://meta.discourse.org/t/webauthn-support/126454/6 "2019-08-26T01:14:15Z")

</div>

> [@sam](#):
>
> Text wise, I don’t like using the term “Web Authn” I think it is confusing to end users, just use “Security Key” or something like that.

Yes, I agree. The “webauthn” on mockups is just a placeholder.

That said, security key doesn’t convey the fact that a user can employ their laptop/phone fingerprint/camera.

> [@sam](#):
>
> I would very much like to avoid even thinking about “First factor / passwordless” auth here, to me we got to ship this feature and live with it for 3-4 months before even considering this.

Yeah, the 3 methods presented are supposed to be implemented in the order, since 1 is a bit more simply but lays the groundwork for 2 and 3.

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [August 26, 2019, 1:16am UTC](https://meta.discourse.org/t/webauthn-support/126454/7 "2019-08-26T01:16:08Z")

</div>

> [@sam](#):
>
> I agree the flow should be … if you can and have the apis and a webauthn key, try webauthn first, but give user an escape hatch.

GitHub is on that same page too:

 ![image](https://global.discourse-cdn.com/meta/original/3X/1/4/149ad02d854850a5121102f6649f393f148cec1a.png)

---

<div class="post-metadata">

### Author: ![Rafe](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/rafe/32/105093_2.png) [@Rafe](https://meta.discourse.org/u/Rafe)
#### Post date: [August 27, 2019, 2:17pm UTC](https://meta.discourse.org/t/webauthn-support/126454/8 "2019-08-27T14:17:24Z")

</div>

Re. “Webauthn as a first factor authenticator”, there’s discussion for for level 2 of the standard to mention the privacy implications this can have: [https://github.com/w3c/webauthn/pull/1250/](https://github.com/w3c/webauthn/pull/1250/)

Re. security key naming, I agree for the reasons outlined on the [RubyGems.org PR](https://github.com/rubygems/rubygems.org/pull/2108#discussion_r316488585).

I also suggested there to add a “last used for login at” timestamp in addition to security key nickname to help disambiguate them and spot potential malicious activity.

---

<div class="post-metadata">

### Author: ![riking](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/riking/32/170938_2.png) [@riking](https://meta.discourse.org/u/riking)
#### Post date: [August 28, 2019, 3:13am UTC](https://meta.discourse.org/t/webauthn-support/126454/9 "2019-08-28T03:13:03Z")

</div>

> [@Rafe](#):
>
> I also suggested there to add a “last used for login at” timestamp in addition to security key nickname to help disambiguate them and spot potential malicious activity.

At work (which is a high security context) we also have an alert that emails you after a security key has been unused for 90 days, prompting you to either use it or remove it from your account.

I think implementing that at 360 days might be a good idea?

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [August 28, 2019, 3:23am UTC](https://meta.discourse.org/t/webauthn-support/126454/10 "2019-08-28T03:23:07Z")

</div>

> [@riking](#):
>
> I think implementing that at 360 days might be a good idea?

Great idea. Having a lower interval would be annoying as we use “infinite” sessions and I think most people will have a day to day key plus a backup one in a drawer. Not counting multiple devices native security keys.

---

<div class="post-metadata">

### Author: ![featheredtoast](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/featheredtoast/32/116994_2.png) [@featheredtoast](https://meta.discourse.org/u/featheredtoast)
#### Post date: [October 2, 2019, 2:18am UTC](https://meta.discourse.org/t/webauthn-support/126454/11 "2019-10-02T02:18:24Z")

</div>

I am pleased to announce that [I have just merged the PR for this feature](https://github.com/discourse/discourse/pull/8099), so we can kick some webauthn tires very, very soon! 🎉

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [October 2, 2019, 3:08am UTC](https://meta.discourse.org/t/webauthn-support/126454/12 "2019-10-02T03:08:05Z")

</div>

Just added my Android fingerprint, Yubikey via NFC and Yubikey via USB-C, using Chrome Android and Firefox Desktop and all looks ok so far.

 ![Screenshot_20191002-000411](https://global.discourse-cdn.com/meta/original/3X/5/4/54f4889b8eb92a8add0db4a1603aa6b9862887a6.png)

Big bug @Martin_Brennan @featheredtoast, no way to log in on Mobile view:

 ![Screenshot_20191002-001000](https://global.discourse-cdn.com/meta/original/3X/1/e/1e9b41edc2f81a386ec9ec0bf9d4ead21b7a19b0.png)

Works fine on Desktop view:

 ![Screenshot_20191002-001132](https://global.discourse-cdn.com/meta/original/3X/4/7/475be24d686f9c0ee41fd296e7ed6fd597205dc3.png) ![Screenshot_20191002-001137](https://global.discourse-cdn.com/meta/original/3X/6/8/686b7f7c5216653a519db89a4595a7a388a32748.png)

---

<div class="post-metadata">

### Author: ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)
#### Post date: [October 2, 2019, 3:59am UTC](https://meta.discourse.org/t/webauthn-support/126454/13 "2019-10-02T03:59:38Z")

</div>

Some random feedback 🙂

This does not look right:

 ![image](https://global.discourse-cdn.com/meta/original/3X/e/3/e3e0c048d29a04a58060bcea819f6bb7eb081030.png)

We should follow the composer here on margin and color of cancel.

 ![image](https://global.discourse-cdn.com/meta/original/3X/4/3/43db3493f02de60dae0d597649cdac40ed476d5c.png)

* * *

Instead of `Password reset email" feels a bit like it does not belong here.

Instead maybe?

> Continue cancel
> 
> Forgot password? ← in light grey

* * *

Password entry looks way big, should be a bit smaller.

* * *

 ![image](https://global.discourse-cdn.com/meta/original/3X/7/5/753533baf25c2c9b95b88b68e788c13a6b72ce0a.png)

I think this should say “Remove” or “Delete”

* * *

If you try to add a yubikey that you already added a cryptic error shows up.

* * *

Overall 👍 👍 👍 🎊

---

<div class="post-metadata">

### Author: ![featheredtoast](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/featheredtoast/32/116994_2.png) [@featheredtoast](https://meta.discourse.org/u/featheredtoast)
#### Post date: [October 2, 2019, 4:28am UTC](https://meta.discourse.org/t/webauthn-support/126454/14 "2019-10-02T04:28:24Z")

</div>

Argh, I knew I was missing a route in review. Good catch ❤

> [@sam](#):
>
> Instead of `Password reset email" feels a bit like it does not belong here.

I think it’s been like this for a while, but yes these are good changes

> [@sam](#):
>
> I think this should say “Remove” or “Delete”

Agree, good change.

> [@sam](#):
>
> a cryptic error

Perhaps we can re-use the built-in chrome copy here? “You have already registered this security key. You don’t have to register it again.” is a nice clear copy.

---

<div class="post-metadata">

### Author: ![Martin\_Brennan](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/martin_brennan/32/157653_2.png) [@Martin\_Brennan](https://meta.discourse.org/u/Martin_Brennan)
#### Post date: [October 2, 2019, 4:36am UTC](https://meta.discourse.org/t/webauthn-support/126454/15 "2019-10-02T04:36:20Z")

</div>

Thanks @Falco and @sam for your feedback. I didn’t realise there was a different route for mobile login either! I will start work on these fixes including the password labelling/button changes tonight, hopefully even open a new PR to fix!

---

<div class="post-metadata">

### Author: ![Martin\_Brennan](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/martin_brennan/32/157653_2.png) [@Martin\_Brennan](https://meta.discourse.org/u/Martin_Brennan)
#### Post date: [October 2, 2019, 4:37am UTC](https://meta.discourse.org/t/webauthn-support/126454/16 "2019-10-02T04:37:51Z")

</div>

I’m really glad this worked on your Android as well (even though the mobile view is not working correctly) — I didn’t have an Android to test with.

---

<div class="post-metadata">

### Author: ![codinghorror](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/codinghorror/32/110067_2.png) [@codinghorror](https://meta.discourse.org/u/codinghorror)
#### Post date: [October 2, 2019, 6:44am UTC](https://meta.discourse.org/t/webauthn-support/126454/17 "2019-10-02T06:44:57Z")

</div>

> [@Martin\_Brennan](#):
>
> I didn’t have an Android to test with.

May I recommend the Xiaomi Mi 9?

> <https://twitter.com/codinghorror/status/1179137770603724800>

---

<div class="post-metadata">

### Author: ![Martin\_Brennan](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/martin_brennan/32/157653_2.png) [@Martin\_Brennan](https://meta.discourse.org/u/Martin_Brennan)
#### Post date: [October 2, 2019, 9:38am UTC](https://meta.discourse.org/t/webauthn-support/126454/18 "2019-10-02T09:38:49Z")

</div>

I’m not sure I’m ready to return to Android – I love my iPhone 8 too much 😅

---

<div class="post-metadata">

### Author: ![Martin\_Brennan](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/martin_brennan/32/157653_2.png) [@Martin\_Brennan](https://meta.discourse.org/u/Martin_Brennan)
#### Post date: [October 2, 2019, 10:34am UTC](https://meta.discourse.org/t/webauthn-support/126454/19 "2019-10-02T10:34:43Z")

</div>

Here is the PR to fix up the above 🚀

[https://github.com/discourse/discourse/pull/8135](https://github.com/discourse/discourse/pull/8135)

---

<div class="post-metadata">

### Author: ![codinghorror](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/codinghorror/32/110067_2.png) [@codinghorror](https://meta.discourse.org/u/codinghorror)
#### Post date: [October 2, 2019, 10:47am UTC](https://meta.discourse.org/t/webauthn-support/126454/20 "2019-10-02T10:47:07Z")

</div>

Who said return? That is old world thinking! Modern people own multiple devices 😉

[Next page](https://meta.discourse.org/t/webauthn-support/126454.md?page=2)
