DEV Community

Arpad Toth for AWS Community Builders

Posted on • Originally published at arpadt.com

Using YubiKeys for passwordless authentication in Cognito user pools

Cognito user pools can be configured to use passkeys to remove passwords from application sign-in processes.

1. The scenario

Let's advance Alice's passwordless authentication project to the next level and see how a third option, passkeys, can eliminate passwords from the application sign-in logic.

In summary, Alice has an application and wants to offer alternatives to passwords for the app users. She has already implemented the text message and the email passwordless methods. She will take this a step further and configure passkeys that can be stored on hardware devices like a YubiKey.

2. Pre-requisites

This post will not cover how to create the following:

  • A Cognito user pool with hosted UI/managed login, Cognito domain, and callback URL.
  • An app client.

Links to the relevant documentation pages will be provided at the end of the post for those who need them.

3. Passwordless authentication with the YubiKey

The first few steps in Cognito are very similar to configuring the email and SMS passwordless options. Let's briefly review them.

3.1. Enable the USER_AUTH flow

We must enable the USER_AUTH flow in the app client configuration if it hasn't already been enabled. With this setting turned on, the user pool will respond with a list of available sign-in methods (both password and passwordless) when the user wants to authenticate.

Please see Part 1 for more information and a visual about this step.

3.2. Enable the passkey sign-in option

Next, we must add Passkey as a sign-in option to the user pool. We can enable it inside the Sign-in option under the Authentication menu on the Cognito console page.

Enable passkey

And that's it!

Let's see the user flow for authenticating with a WebAuthn/FIDO2 type passkey stored on the YubiKey.

4. Replacing passwords with passkeys

We should discuss two scenarios: Authentication flow with a passkey for self-signed and admin-created users.

Cognito behaves differently in these cases.

The main difference is that the user pool will offer the "create a passkey" option for self-signed users. But it doesn't do so for users added directly by administrators.

4.1. Self-signed user

Users are only allowed to sign up for our application by themselves if the self-sign-up option is enabled in the user pool. The managed UI will then offer the New user? Create an account option on the sign-in page.

When we create a new user pool, Cognito allows us to configure sign-in identifiers (email, username or phone number) and required attributes for sign-up.

Required sign-up options

Here, we should enable the email or phone option as a required attribute for sign-up. One is mandatory when a user-selected username, e.g., testuser, is asked in the Username field of the login page. This example uses the email option.

This way, when the new user starts the Create an account sign-up flow, they will be prompted to enter their username, select a password and provide their email address.

From here, users experience the well-known flow. Cognito will then send them an email with a confirmation code to the email address provided, and new users will need to validate their email address by entering the code in the input field.

After the user has validated the email address and successfully signed in to the application, the user pool will automatically offer the Add passkey option.

Add passkey

Here, the user clicks on the Add passkey button.

Next, a USB security key option should be displayed in the pop-up modal. The user needs to choose it to create a passkey on the YubiKey. If this option is not shown on the screen, try to find a button saying Save another way or something similar.

The user can now insert the YubiKey and touch it to create the passkey on the device.

Check the key

We can optionally check if the key was successfully created on the YubiKey. To do this, install the YubiKey Manager CLI.

If we run the

ykman fido credentials list
Enter fullscreen mode Exit fullscreen mode

command, we will see the newly created passkey assigned to the username and the user pool's domain name.

Sign in with the passkey

After logging out of our application, the user can sign in with the new passkey.

When the user enters the username, the user pool will offer the Sign in with a passkey option.

Sign in with a passkey

After clicking Continue, the user will be prompted to insert and touch the YubiKey. Cognito will then verify the user's identity based on the passkey provided, and the user will successfully authenticate to the application.

As the screenshot shows, traditional passwords are also available as a sign-in option if the user doesn't have the YubiKey handy or has deleted the passkey.

4.2. Admin-created users or existing user pools

What if, as administrators, we add users to the user pool by creating usernames and temporary passwords for them? Or consider a scenario where a user pool already has existing users, and passkey authentication is enabled at a later time.

In this case, Cognito will not offer the user the passkey option after successful user authentication. We have to manually provide them with the passkey creation option by redirecting them to the passkey endpoint. It's a little more effort since it requires some extra lines of code in the client. It's beyond the scope of this post and might be discussed in another article.

The endpoint follows the https://USER_POOL_DOMAIN_NAME/passkeys/add format, and the request should be submitted with some mandatory query parameters:

GET https://USER_POOL_DOMAIN_NAME/passkeys/add?response_type=code&
client_id=APP_CLIENT_ID&scope=openid&redirect_uri=REDIRECT_URL
Enter fullscreen mode Exit fullscreen mode

The response_type should be set to code, and we also need to configure the APP_CLIENT_ID and the redirect URL. The scope query parameter must have at least the openid value.

The user will be then redirected to the Set up sign-in with a passkey page, and from this step, everything works as described under 4.1.

5. Considerations

Cognito also accepts passkeys stored elsewhere. Password managers like 1Password and operating systems also offer secure passkey storage. Users can select where to store their passkeys while configuring the option.

Also, the password sign-in option must be enabled before we activate passkeys. Cognito doesn't seem to allow passwordless sign-in options to be the only choice.

6. Summary

The third passwordless sign-in option Cognito allows is passkeys. Users can use external devices like the YubiKey to store passkeys used for authentication.

The user pool will automatically offer the passkey creation option to self-signed users after they successfully authenticate to the application. But, if administrators added the users to the user pool, we need to redirect them to the passkey page in the client.

7. Further reading

Getting started with user pools - How to create a user pool with an app client

Top comments (0)