Adding passkeys to your AWS Cognito native mobile app
Learn how to add passkeys to your AWS Cognito native mobile app with Authsignal.
This example will demonstrate how to add passkeys to a native mobile app when using AWS Cognito. It uses the Amplify React Native SDK, but if you’re not using Amplify then you can follow a similar approach can be used to our pre-built UI examples which use the AWS SDK client-side or server-side.
Although the example uses our React Native SDK a similar integration can also be achieved using our iOS SDK, Android SDK or Flutter SDK.
Example Repository
Example app using React Native + Amplify + Authsignal.
User flow
Sign up
The user verifies their email via an OTP challenge then is prompted to create a passkey.
Creating a passkey after registration via email OTP
Sign in
The user is prompted to sign in with their passkey without having to input their email.
Signing in with an available passkey
Prerequisites
You should first enable passkeys for your Authsignal tenant and ensure that you’ve configured your relying party.
Next, you’ll need to follow these steps to setup apple-app-site-association
(iOS) and assetlinks.json
(Android) files on your web domain.
Installation
Configuration
Update this file with the config values for your Authsignal tenant and region-specific URL, along with the values for your AWS Cognito user pool.
The AWS lambdas
The app code
Sign up
Code example
Sign up implementation.
1. Call Amplify SDK signUp
method
Pass the email as the username.
2. Call Amplify SDK signIn
method
This step invokes the Create Auth Challenge lambda.
3. Use the Authsignal Mobile SDK to enroll email OTP
Obtain the short-lived Authsignal token returned by the Create Auth Challenge lambda and use it to initiate email OTP enrollment via the Authsignal Mobile SDK.
This step will send the user an email with an OTP code. Once they input the code into the app, we can verify it using the Authsignal Mobile SDK.
The Authsignal Mobile SDK will return a result token which we can pass to our backend lambdas in the next step.
4. Call Amplify SDK confirmSignIn
method
This step invokes the Verify Auth Challenge Response lambda.
Sign in with passkey
Code example
Sign in implementation.
1. Call Authsignal SDK passkey.signIn
method
2. Call Amplify SDK signIn
and confirmSignIn
methods
Pass the username and token returned by the Authsignal SDK.
Optimizing UX for edge cases
Our sign-in approach above optimizes for the happy path where a user has a passkey available on their device. But it can also handle the scenario where a registered user doesn’t have a passkey available - for example, if they have deleted their existing passkey, or if they’ve switched to a new device on a different platform where their existing passkey can’t be synced.
Falling back to email OTP when no passkey is available
This scenario is handled by checking the errorCode
returned by the Authsignal SDK passkey.signIn
method:
On iOS if no passkey is available the Authsignal SDK will return the user_canceled
error code, because iOS treats the absence of a passkey credential as a cancellation event if preferImmediatelyAvailableCredentials is set to true.
On Android if no passkey is available the Authsignal SDK will return the no_credential
error code, because Android returns a more explicit error in this scenario.
To keep the behavior consistent on both platforms, we treat cancellation the same as not having a credential available and fall back to presenting an email OTP sign-in option in each case.
Falling back to email OTP when the user cancels passkey sign-in
This approach allows us to optimize sign-in for the happy path while also achieving a good UX for the edge case where a user can’t use passkeys.