Authentication flows
The process of authentication with Amazon Cognito user pools can best be described as a flow where users make an initial choice, submit credentials, and respond to additional challenges. When you implement managed login authentication in your application, Amazon Cognito manages the flow of these prompts and challenges. When you implement flows with an AWS SDK in your application back end, you must construct the logic of requests, prompt users for input, and respond to challenges.
As an application administrator, your user characteristics, security requirements, and authorization model help determine how you want to permit users to sign in. Ask yourself the following questions.
-
Do I want to permit users to sign in with credentials from other identity providers (IdPs)?
-
Is a username and password enough proof of identity?
-
Could my authentication requests for username-password authentication be intercepted? Do I want my application to transmit passwords, or to negotiate authentication using hashes and salts?
-
Do I want to permit users to skip password entry and receive a one-time password that signs them in?
-
Do I want to permit users to sign in with a thumbprint, face, or a hardware security key?
-
When do I want to require multi-factor authentication (MFA), if at all?
-
Do I want to persist user sessions without re-prompting for credentials?
-
Do I want to extend my authorization model beyond the built-in capabilities of Amazon Cognito?
When you have the answers to these questions, you can learn how to activate the relevant features and implement them in the authentication requests that your application makes.
After you set up sign-in flows for a user, you can check their current status for MFA and choice-based authentication factors with requests to the GetUserAuthFactors API operation. This operation requires authorization with the access token of a signed-in user. It returns user authentication factors and MFA settings.
Topics
Sign-in with third-party IdPs
Amazon Cognito user pools serve as an intermediate broker of authentication sessions between IdPs like Sign in with Apple, Login with Amazon, and OpenID Connect (OIDC) services. This process is also called federated sign-in or federated authentication. Federated authentication doesn't make use of any of the authentication flows that you can build into your app client. Instead, you assign configured user pool IdPs to your app client. Federated sign-in happens when users select their IdP in managed login or your application invokes a session with a redirect to their IdP sign-in page.
With federated sign-in, you delegate primary and MFA authentication factors to the user's IdP. Amazon Cognito doesn't add the other advanced flows in this section to a federated user unless you link them to a local user. Unlinked federated users have usernames, but they are a store of mapped attribute data that's not typically used for sign-in independent of the browser-based flow.
Implementation resources
Sign-in with persistent passwords
In Amazon Cognito user pools, every user has a username. This might be a phone number, an email address, or a chosen or administrator-provided identifier. Users of this type can sign in with their username and their password, and optionally provide MFA. User pools can perform username-password sign-in with public or IAM-authenticated API operations and SDK methods. Your application can directly send the password to your user pool for authentication. Your user pool responds with additional challenges or the JSON web tokens (JWTs) that are the result of successful authentication.
Sign-in with persistent passwords and secure payload
Another form of the username-password sign-in methods in user pools is with the Secure
Remote Password (SRP) protocol. This option sends proof of knowledge of a password—a
password hash and a salt—that your user pool can verify. With no readable secret
information in the request to Amazon Cognito, your application is the only entity that processes the
passwords that users enter. SRP authentication involves mathematical calculations that are
best done by an existing component that you can import in your SDK. SRP is typically
implemented in client-side applications like mobile apps. For more information about the
protocol, see The Stanford SRP Homepage
Built-in authentication flow and challenges
Amazon Cognito contains built-in AuthFlow
and ChallengeName
values so
that a standard authentication flow can validate a username and password through the
Secure Remote Password (SRP) protocol. The AWS SDKs have built-in support for these
flows with Amazon Cognito.
The flow starts by sending USER_SRP_AUTH
as the AuthFlow
to
InitiateAuth
. You also send USERNAME
and SRP_A
values in AuthParameters
. If the InitiateAuth
call is
successful, the response has included PASSWORD_VERIFIER
as the
ChallengeName
and SRP_B
in the challenge parameters. The app
then calls RespondToAuthChallenge
with the PASSWORD_VERIFIER
ChallengeName
and the necessary parameters in
ChallengeResponses
. If the call to RespondToAuthChallenge
is
successful and the user signs in, Amazon Cognito issues tokens. If you activated multi-factor
authentication (MFA) for the user, Amazon Cognito returns the ChallengeName
of
SMS_MFA
. The app can provide the necessary code through another call to
RespondToAuthChallenge
.
Passwordless sign-in with one-time passwords
Passwords can be lost or stolen. You might want to verify only that your users have access to a verified email address, phone number, or authenticator app. The solution to this is passwordless sign-in. Your application can prompt users to enter their username, email address, or phone number. Amazon Cognito then generates a one-time password (OTP), a code that they must confirm. A successful code completes authentication.
When a user correctly enters a code they received in an SMS or email message as part of
passwordless authentication, in addition to authenticating the user, your user pool marks
the user’s unverified email address or phone number attribute as verified. The user status
also changed from UNCONFIRMED
to CONFIRMED
, regardless of whether
you configured your user pool to automatically
verify email addresses or phone numbers.
New options with passwordless sign-in
When you activate passwordless authentication in your user pool, it changes how some user flows work.
-
Users can sign up without a password and choose a passwordless factor when they sign in. You can also create users without passwords as an administrator.
-
Users who you import with a CSV file can sign in immediately with a passwordless factor. They aren't required to set a password before sign-in.
-
Users who don't have a password can submit ChangePassword API requests without the
PreviousPassword
parameter.
Automatic sign-in with OTPs
Users who sign up and confirm their user accounts with email or SMS message OTPs can automatically sign in with the passwordless factor that matches their confirmation message. In the managed login UI, users who confirm their accounts and are eligible for OTP sign-in with the confirmation-code delivery method automatically proceed through to their first sign-in after they provide the confirmation code. In your custom-built application with an AWS SDK, pass the following parameters to an InitiateAuth or AdminInitiateAuth operation.
-
The
Session
parameter from the ConfirmSignUp API response as theSession
request parameter. -
An AuthFlow of
USER_AUTH
.
You can pass a PREFERRED_CHALLENGE of EMAIL_OTP
or SMS_OTP
, but it's
not required. The Session
parameter provides proof of authentication and Amazon Cognito
ignores the AuthParameters
when you pass a valid session code.
The sign-in operation returns the response that indicates successful authentication, AuthenticationResult, with no additional challenges if the following conditions are true.
-
The
Session
code is still valid. -
The user is eligible for the requested
PREFERRED_CHALLENGE
authentication method -
The user doesn't have MFA set up. If they do have MFA, Amazon Cognito returns the appropriate challenge to complete MFA.
Passkey sign-in
Passkeys are secure and impose a relatively low effort level on users. Passkey sign-in makes use of authenticators, external devices that users can authenticate with. Regular passwords expose users to vulnerabilities like phishing, password guessing, and credential theft. With passkeys, your application can benefit from advanced security measures on mobile phones and other devices attached to or built in to information systems. A common passkey sign-in workflow starts with a call to your device that invokes your password or credentials manager, for example the iOS keychain or the Google Chrome password manager. The on-device credentials manager prompts them to select a passkey and authorize it with an existing credential or device-unlock mechanism. Modern phones have face scanners, fingerprint scanners, unlock patterns and other mechanisms, some that simultaneously satisfy the something you know and something you have principles of strong authentication. In the case of passkey authentication with biometrics, passkeys represent a something you are.
You might want to replace passwords with the thumbprint, face, or security-key authentication. This is passkey or WebAuthn authentication. It's common for application developers to permit users to enroll a biometric device after they first sign in with a password. With Amazon Cognito user pools, your application can configure this sign-in option for users.
What are passkeys?
Passkeys simplify the user experience by eliminating the need to remember complex
passwords or enter OTPs. Passkeys are based on WebAuthn and CTAP2 standards drafted by the
World Wide Web Consortium
When a user registers an authenticator with a website or an app, the authenticator creates a public-private key pair. WebAuthn browsers and platforms submit the public key to the application back end of the website or app. The authenticator keeps the private key, key IDs, and metadata about the user and application. When the user wants to authenticate in the registered application with their registered authenticator, the application generates a random challenge. The response to this challenge is the digital signature of the challenge generated with the private key of the authenticator for that application and user, and relevant metadata. The browser or application platform receives the digital signature and passes it to the application back end. The application then validates the signature with the stored public key.
Note
Your application doesn't receive any authentication secrets that users provide to their authenticator, nor does it receive information about the private key.
The following are some examples and capabilities of authenticators currently on the market. An authenticator might meet any or all of these categories.
-
Some authenticators perform user verification with factors like a PIN, biometric input with a face or fingerprint, or a passcode before granting access, ensuring that only the legitimate user can authorize actions. Other authenticators don't have any user verification capabilities, and some can skip user verification when an application doesn't require it.
-
Some authenticators, for example YubiKey hardware tokens, are portable. They communicate with devices through USB, Bluetooth or NFC connections. Some authenticators are local and bound to a platform, for example Windows Hello on a PC or Face ID on an iPhone. A device-bound authenticator can be carried by user if small enough, like a mobile device. Sometimes users can connect their hardware authenticator with many different platforms with wireless communication. For example, users in desktop browsers can use their smart phone as a passkey authenticator when they scan a QR code.
-
Some platform-bound passkeys sync to the cloud so that they can be used from multiple locations. For example, Face ID passkeys on iPhones sync passkey metadata with users' Apple accounts in their iCloud Keychain. These passkeys grant seamless authentication across Apple devices, instead of requiring that users register each device independently. Software-based authenticator apps like 1Password, Dashlane, and Bitwarden sync passkeys across all platforms where the user has installed the app.
In WebAuthn terminology, websites and apps are relying
parties. Each passkey is associated with a specific relying party ID, a
unified identifier that represents the websites or apps that accept passkey
authentication.. Developers must carefully select their relying party ID to have the right
scope of authentication. A typical reliying party ID is the root domain name of a
webserver. A passkey with this relying party ID specification can authenticate for that
domain and subdomains. Browsers and platforms deny passkey authentication when the URL of
the website a user want to access doesn't match the relying party ID. Similarly, for
mobile apps, a passkey can only be used if the app path is present in the
.well-known
association files that the application makes available at the
path indicated by the relying party ID.
Passkeys are discoverable. They can be automatically recognized and used by a browser or platform without requiring the user to input a username. When a user visits a website or app that supports passkey authentication, they can select from a list of passkeys that the browser or platform already knows, or they can scan a QR code.
How does Amazon Cognito implement passkey authentication?
Passkeys are an opt-in feature that's available in all feature plans other than Lite. It is only available in the choice-based authentication flow. With managed login, Amazon Cognito handles the logic of passkey authentication. You can also use the Amazon Cognito user pools API in AWS SDKs to do passkey authentication in your application back end.
Amazon Cognito recognizes passkeys created using either of two asymmetric cryptographic
algorithms, ES256(-7) and RS256(-257). Most authenticators support both algorithms. By
default, users can set up any type of authenticators, for example hardware tokens, mobile
smart phones, and software authenticator apps. Amazon Cognito doesn't currently support attestation
In your user pool, you can configure user verification to be preferred or required. This setting defaults to preferred in API requests that don't provide a value, and preferred is selected by default in the Amazon Cognito console. When you set user verification to preferred, users can set up authenticators that don't have the user verification capability, and registration and authentication operations can succeed without user verification. To mandate user verification in passkey registration and authentication, change this setting to required.
The relying party (RP) ID that you set in your passkey configuration is an important
decision. When you don't specify otherwise and your domain branding version is managed login, your user pool defaults to expecting
the name of your custom domain
as the RP ID. If you don't have a custom domain and don't specify otherwise, your user
pool defaults to an RP ID of your prefix domain. You can also configure your RP ID to be any domain name not in
the public suffix list (PSL). Your RP ID entry applies to passkey registration and
authentication in managed login and in SDK authentication. Passkey is only functional in
mobile applications with Amazon Cognito can locate a .well-known
association file with
your RP ID as the domain. As a best practice, determine and set the value of your relying
party ID before your website or app is publicly available. If you change your RP ID, your
users must register again with the new RP ID.
Each user can register up to 20 passkeys. They can only register a passkey after they have signed in to your user pool at least once. Managed login removes significant effort from passkey registration. When you enable passkey authentication for a user pool and app client, your user pool with a managed login domain reminds end users to register a passkey after they sign up for a new user account. You can also invoke users' browsers at any time to direct them to a managed login page for passkey registration. Users must provide a username before Amazon Cognito can initiate passkey authentication. Managed login handles this automatically. The sign-in page prompts for a username, validates that the user has at least one passkey registered, and then prompts for passkey sign-in. Similarly, SDK-based applications must prompt for a username and provide it in the authentication request.
When you set up user pool authentication with passkeys and you have a custom domain and a prefix domain, the RP ID defaults to the fully-qualified domain name (FQDN) of your custom domain. To set a prefix domain as the RP ID in the Amazon Cognito console, delete your custom domain or enter the FQDN of the prefix domain as a Third-party domain.
MFA after sign-in
You can set up users who complete sign-in with a username-password flow to be prompted for additional verification with a one-time password from an email message, SMS message, or code-generating application. MFA is distinct from passwordless sign-in, a first authentication factor that doesn't include MFA. MFA in user pools is a challenge-response model, where a user first demonstrates they know the password, then they demonstrate that they have access to their registered second-factor device.
Implementation resources
Refresh tokens
When you want to permit users to select a Remember me checkbox, refresh tokens are the tool that your application has to persist a user's session. Applications can present refresh tokens to your user pool and exchange them for new ID and access tokens. With token refresh, you can ensure that a signed-in user is still active, get updated attribute information, and update access-control entitlements without user intervention.
Implementation resources
Custom authentication
You might want to configure a method of authentication for your users that isn't listed here. You can do that with custom authentication with Lambda triggers. In a sequence of Lambda functions, Amazon Cognito issues a challenge, asks a question that users must answer, checks the answer for accuracy, then determines if another challenge should be issued. The questions and answers can include security questions, requests to a CAPTCHA service, requests to an external MFA service API, or all of these in sequence.
Implementation resources
Custom authentication flow
Amazon Cognito user pools also make it possible to use custom authentication flows, which can help you create a challenge/response-based authentication model using AWS Lambda triggers.
The custom authentication flow makes possible customized challenge and response cycles
to meet different requirements. The flow starts with a call to the
InitiateAuth
API operation that indicates the type of authentication to use
and provides any initial authentication parameters. Amazon Cognito responds to the
InitiateAuth
call with one of the following types of information:
-
A challenge for the user, along with a session and parameters.
-
An error if the user fails to authenticate.
-
ID, access, and refresh tokens if the supplied parameters in the
InitiateAuth
call are sufficient to sign the user in. (Typically the user or app must first answer a challenge, but your custom code must determine this.)
If Amazon Cognito responds to the InitiateAuth
call with a challenge, the app
gathers more input and calls the RespondToAuthChallenge
operation. This call
provides the challenge responses and passes it back the session. Amazon Cognito responds to the
RespondToAuthChallenge
call similarly to the InitiateAuth
call. If the user has signed in, Amazon Cognito provides tokens, or if the user isn't signed in,
Amazon Cognito provides another challenge, or an error. If Amazon Cognito returns another challenge, the
sequence repeats and the app calls RespondToAuthChallenge
until the user
successfully signs in or an error is returned. For more details about the
InitiateAuth
and RespondToAuthChallenge
API operations, see
the API
documentation.
Custom authentication flow and challenges
An app can initiate a custom authentication flow by calling InitiateAuth
with CUSTOM_AUTH
as the Authflow
. With a custom authentication
flow, three Lambda triggers control challenges and verification of the responses.
-
The
DefineAuthChallenge
Lambda trigger uses a session array of previous challenges and responses as input. It then generates the next challenge name and Booleans that indicate whether the user is authenticated and can be granted tokens. This Lambda trigger is a state machine that controls the user’s path through the challenges. -
The
CreateAuthChallenge
Lambda trigger takes a challenge name as input and generates the challenge and parameters to evaluate the response. WhenDefineAuthChallenge
returnsCUSTOM_CHALLENGE
as the next challenge, the authentication flow callsCreateAuthChallenge
. TheCreateAuthChallenge
Lambda trigger passes the next type of challenge in the challenge metadata parameter. -
The
VerifyAuthChallengeResponse
Lambda function evaluates the response and returns a Boolean to indicate if the response was valid.
A custom authentication flow can also use a combination of built-in challenges, such as SRP password verification and MFA through SMS. It can use custom challenges such as CAPTCHA or secret questions.
Use SRP password verification in custom authentication flow
If you want to include SRP in a custom authentication flow, you must begin with SRP.
-
To initiate SRP password verification in a custom flow, the app calls
InitiateAuth
withCUSTOM_AUTH
as theAuthflow
. In theAuthParameters
map, the request from your app includesSRP_A:
(the SRP A value) andCHALLENGE_NAME: SRP_A
. -
The
CUSTOM_AUTH
flow invokes theDefineAuthChallenge
Lambda trigger with an initial session ofchallengeName: SRP_A
andchallengeResult: true
. Your Lambda function responds withchallengeName: PASSWORD_VERIFIER
,issueTokens: false
, andfailAuthentication: false
. -
The app next must call
RespondToAuthChallenge
withchallengeName: PASSWORD_VERIFIER
and the other parameters required for SRP in thechallengeResponses
map. -
If Amazon Cognito verifies the password,
RespondToAuthChallenge
invokes theDefineAuthChallenge
Lambda trigger with a second session ofchallengeName: PASSWORD_VERIFIER
andchallengeResult: true
. At that point, theDefineAuthChallenge
Lambda trigger responds withchallengeName: CUSTOM_CHALLENGE
to start the custom challenge. -
If MFA is enabled for a user, after Amazon Cognito verifies the password, your user is then challenged to set up or sign in with MFA.
Note
The Amazon Cognito hosted sign-in webpage can't activate Custom authentication challenge Lambda triggers.
For more information about the Lambda triggers, including sample code, see Customizing user pool workflows with Lambda triggers.
Admin authentication flow
User migration authentication flow
A user migration Lambda trigger helps migrate users from a legacy user management system
into your user pool. If you choose the USER_PASSWORD_AUTH
authentication flow,
users don't have to reset their passwords during user migration. This flow sends your users'
passwords to the service over an encrypted SSL connection during authentication.
When you have migrated all your users, switch flows to the more secure SRP flow. The SRP flow doesn't send any passwords over the network.
To learn more about Lambda triggers, see Customizing user pool workflows with Lambda triggers.
For more information about migrating users with a Lambda trigger, see Importing users with a user migration Lambda trigger.