cms
cms copied to clipboard
[5.x] Add passkey 🔑 support to CP logins
This PR adds WebAuthn/Passkey support to the CP login:
https://github.com/statamic/cms/assets/51899/97eca681-2d55-478c-8ed8-0dfd88aa796d
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 https://github.com/statamic/ideas/issues/1059
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:
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:
https://github.com/statamic/cms/assets/69107412/bfec98c0-cc70-4377-871b-ae6b7c64f439
One thing I noticed is that the users table lists the key as a user.
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.
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.
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.
Do you mean the option is gone from the form? Or you just get denied if you try to enter a username/password?
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.
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:
This is my accounting software. Also Dutch, but when I try to login with my e-mail it says nope:
Weirdly enough Apple does offer the password option. Perhaps because I had 2fa enabled, I'm not sure.
I guess it's a choice. But security wise I don't think it makes sense to keep the option.
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.
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.
Sounds good to me too. Let me know if you want me to update this to work that way.
@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?)
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:
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:
They only thing I've noticed is that when you enable oauth
, you still get this middle step:
Which now isn't correct anymore. Perhaps this step could be removed and simplified to something like this?
That sort of UI change is above my pay grade :)
That sort of UI change is above my pay grade :)
I'll chip in £5
Ok, I think I've got all the various states now. Happy to make more changes. This is what it looks like:
Normal login
Passkeys enabled
Passkeys and oAuth enabled
E-mail login disabled
Only oAuth enabled
Some icons on those flat buttons might be the icing on the cake, but I don't have access to streamline.