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

[5.x] Add passkey 🔑 support to CP logins #9239

Open
wants to merge 29 commits into
base: 5.x
Choose a base branch
from

Conversation

ryanmitchell
Copy link
Contributor

@ryanmitchell ryanmitchell commented Dec 22, 2023

This PR adds WebAuthn/Passkey support to the CP login:

CleanShot.2023-12-22.at.08.12.14.mp4

We make use of the following libraries for backend and front end support respectively:
https://github.com/web-auth/webauthn-lib
https://simplewebauthn.dev/docs/packages/browser/

I noticed CraftCMS have used the same libraries for their Passkey support.

The user flow is as follows:

  • An already authenticated user goes to the Passkeys page (new option under user menu) where they can create or remove Passkeys.
  • Once a passkey has been created (through the Browsers in-built UI) the user then has the option to login using that on the CP login page. It should 'just work'.

The changes behind the scenes are:

  • There is a new webauthn config file, allow this functionality to be enabled
    - There is a new passkeys stache store (inside a new passkeys folder in the users folder)
    - There is a passkeys repository and query builder to allow querying of a user's passkeys

I still need to add support for eloquent stored passkeys, and the UI on the passkeys page in the CP could do with being improved by someone who has better design skills than me.

Closes statamic/ideas#1059

@robdekort
Copy link
Contributor

This is amazing. I just did a test run and with SSL enabled locally and "web-auth/webauthn-lib": "^4.7" added to my composer.json I was able to create a passkey and login. Very hot stuff!

A side note regarding the login flow - and this should probably be addressed for oAuth as well in a separate PR - I'd ditch the Login with email button:

Screenshot_2023-12-22_at_12 22 09

And instead always show the regular login fields and below that options for other types of login: passkeys, oauth. This is basically the flow GitHub uses:

Screen_Recording_2023-12-22_at_10.48.25.mov

@robdekort
Copy link
Contributor

One thing I noticed is that the users table lists the key as a user.
Screenshot 2023-12-22 at 12 35 44

@jasonvarga
Copy link
Member

@jasonvarga jasonvarga self-assigned this Feb 28, 2024
@robdekort
Copy link
Contributor

One note regarding this that I don't remember being in this PR. I feel Statamic should disable the option to login with password for the account that has a Passkey set. That seems to be the standard, as otherwise there's no security benefit, but it's just a convenience.

@jasonvarga
Copy link
Member

Looking at GitHub as an example, I have set up a passkey there, but they still give me the option to sign in with a username and password. Both work.

@robdekort
Copy link
Contributor

Looking at GitHub as an example, I have set up a passkey there, but they still give me the option to sign in with a username and password. Both work.

I see, you’re right regarding GitHub. I’m honestly surprised by that. That is not what I see most sites that offer Passkeys do. For example my accounting software completely disables password logins as soon as you set a Passkey. And so does Sony on their recently introduced Passkeys for PS5.

I believe this should be how it’s done. Passkeys are here to eliminate passwords and improve security. By keeping the ability to login with a password there’s no security benefit gained.

@jasonvarga
Copy link
Member

Do you mean the option is gone from the form? Or you just get denied if you try to enter a username/password?

@jasonvarga
Copy link
Member

I have a PS account so I could test that myself. It seems that you have to enter your username first, then it gives you the appropriate option. e.g. I entered my email then it showed me the option to sign in with a passkey. I tried again with a fake email and it shows me the password field.

@robdekort
Copy link
Contributor

Do you mean the option is gone from the form? Or you just get denied if you try to enter a username/password?

Yeah, getting denied. Sony disabled my password and 2fa, no way to enable it with a Passkey enabled. Here you can see it. Sorry Dutch, but I think you'll understand:
Screenshot 2024-04-18 at 21 02 18

This is my accounting software. Also Dutch, but when I try to login with my e-mail it says nope:
Screenshot 2024-04-18 at 21 03 54

@robdekort
Copy link
Contributor

Weirdly enough Apple does offer the password option. Perhaps because I had 2fa enabled, I'm not sure.
Screenshot 2024-04-18 at 21 05 56

I guess it's a choice. But security wise I don't think it makes sense to keep the option.

@jasonvarga
Copy link
Member

jasonvarga commented Apr 18, 2024

Nice I love inconsistency. So I think maybe we do this:

Have an allow_password_login_with_passkey config that controls whether you can login with a password if you have a passkey set.

I assume the difference across the sites is because of different requirements on a per-company scope. Some might like it one way, others not.

This options should allow most situations:

  • Users without a passkey can still log in with email/password.
  • Users with a passkey that enter their password can still log in, if you configure it that way.
  • Users with a passkey that enter their password will be denied, if you configure it that way.

@robdekort
Copy link
Contributor

That sounds like a perfect solution. For example, I would enforce it by default. But maybe not if I’d use the 2fa addon. All options possible. I love it.

@ryanmitchell
Copy link
Contributor Author

Sounds good to me too. Let me know if you want me to update this to work that way.

@ryanmitchell ryanmitchell changed the base branch from 4.x to master April 23, 2024 06:40
@ryanmitchell ryanmitchell changed the title [4.x] Add passkey 🔑 support to CP logins [5.x] Add passkey 🔑 support to CP logins Apr 23, 2024
@ryanmitchell ryanmitchell marked this pull request as ready for review April 23, 2024 08:37
@ryanmitchell
Copy link
Contributor Author

ryanmitchell commented Apr 23, 2024

@jasonvarga I've updated this:

  • It now targets 5.x
  • It implements the allow_password_login_with_passkey config as suggested above
  • Passkeys no longer have a store, querybuilder or repository. In stache they are stored in the user yaml, in eloquent we query the model directly
  • I added some tests for adding and deleting passkeys (test coverage of the passkey functionality itself should come from the library not Statamic?)

@robdekort
Copy link
Contributor

This flow seems really great, for anyone wondering what Ryan has done, I just test ran it and it uses the same flow as Github:
Screenshot_2024-04-23_at_17 23 09

If you have allow_password_login_with_passkey set to true and you have setup a passkey, you can login using either options. If you have it set to false it blocks your login:
Screenshot_2024-04-23_at_17 23 36

They only thing I've noticed is that when you enable oauth, you still get this middle step:
Screenshot_2024-04-23_at_17 25 15

Which now isn't correct anymore. Perhaps this step could be removed and simplified to something like this?
Screenshot_2024-04-23_at_17 27 13

@ryanmitchell
Copy link
Contributor Author

That sort of UI change is above my pay grade :)

@edalzell
Copy link
Contributor

That sort of UI change is above my pay grade :)

I'll chip in £5

Co-Authored-By: Rob de Kort <[email protected]>
@robdekort
Copy link
Contributor

Ok, I think I've got all the various states now. Happy to make more changes. This is what it looks like:

Normal login
Screenshot 2024-04-24 at 09 16 42

Passkeys enabled
Screenshot 2024-04-24 at 09 16 52

Passkeys and oAuth enabled
Screenshot 2024-04-24 at 09 17 11

E-mail login disabled
Screenshot 2024-04-24 at 09 17 20

Only oAuth enabled
Screenshot 2024-04-24 at 09 17 28

@robdekort
Copy link
Contributor

robdekort commented Apr 24, 2024

Some icons on those flat buttons might be the icing on the cake, but I don't have access to streamline.

@ryanmitchell ryanmitchell changed the base branch from master to 5.x August 29, 2024 12:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

🔑 Passkeys!
4 participants