This project is an example of how to set up biometric login for web-based apps (WebAuthn) using Amazon Cognito as the identity provider. This project accomplishes this by leaning on AWS Cognito custom authentication challenges and the SimpleWebAuthn library.
For more information on how this works, here are some references:
- https://aws.amazon.com/blogs/security/how-to-implement-password-less-authentication-with-amazon-cognito-and-webauthn/
- Getting Started with WebAuthn with Nick Steele
- Good Q & A thread
- Yubico's WebAuthn Guide
This project takes inspiration from the following projects:
- https://github.com/MasterKale/SimpleWebAuthn
- https://github.com/aws-samples/webauthn-with-amazon-cognito
- https://github.com/lockdrop/cdk-serverless-cognito-fido2-webauthn
- https://github.com/webauthn-open-source/fido2-lib
The project uses the following libraries for handling the biometric login flow:
- https://github.com/MasterKale/SimpleWebAuthn
- https://github.com/feross/buffer
- https://github.com/Hexagon/base64
The during the authentication process on the frontend, the SimpleWebAuthn library requires some methods that are present on the Node.js Buffer sub class. These methods are not availble in the browser natively, and must be added via the buffer
js library. This is being imported and initialized in the index.html
file in the /frontend
directory.
To run the project, make sure that you have an AWS account and have configured the serverless cli
Create an AWS account if you don't already have one, and set up credentials to be used with Serverless https://www.serverless.com/framework/docs/providers/aws/guide/credentials/
Install the serverless cli:
npm install -g serverless
Create a .env
file in the /serverless
directory and paste in this content:
RELYING_PARTY_ORIGIN=http://localhost:5173
RELYING_PARTY_ID=localhost
These values should be set to the URL of the relying party site, since we're running the relying party locally (frontend project), these values above should be fine.
From the /serverless
directory, run the following commands:
npm install
sls deploy
In the serverless.yml
file, uncomment the section under the verifyAuthChallengeResponse
function. Looks like this:
verifyAuthChallengeResponse:
handler: ./functions/verify-auth-challenge-response.handler
# Leave the following section commented out on the first deployment.
# Enable this section once you can add the created user pool resource arn
# iamRoleStatementsName: verifyAuthChallengeRes-cognito-idp_AdminUpdateUserAttributes
# iamRoleStatements:
# - Effect: Allow # Action: cognito-idp:AdminUpdateUserAttributes
# # Paste User Pool Resource ARN here
# Resource: your-resource-arn
Find the Cognito User Pool on AWS and copy the user pool's ARN. Paste it in the serverless.yml file for the correct iamRoleStatement.
locate: 'Paste User Pool Resource ARN here'
Create a .env.local
file in the /frontend
directory and paste in this content:
VITE_AUTH_REGION=us-east-2
VITE_AUTH_USER_POOL_ID=us-east-2_user-pool-id
VITE_AUTH_USER_POOL_WEB_CLIENT_ID=user-pool-web-client-id
VITE_AUTH_COOKIE_STORAGE_DOMAIN=localhost
Replace the values with your own. I've left in some fake ones as an example.
Add the AWS Region
,User Pool ID
, and User Pool Web Client ID
to the created .env file in the /frontend
directory
From the /frontend
directory, run the following commands:
npm install
npm run dev
run sls remove
If it fails to remove the stack, you might need to manually delete the S3 deployment bucket
Passkeys located here in Chrome:
chrome://settings/passkeys