Question: How do I use remembered devices in my Amazon Cognito user pool?

I want to track devices that users in my Amazon Cognito user pool have used to sign in to my app. How do I do that?Short descriptionAmazon Cognito can track and remember devices that users in a user pool use for signing in. By activating device remembering, you can set sign-in restrictions (for example, to limit signing in from a single device). Or, you can let users skip repeated sign-ins on the same device. For more information, see Specifying user pool device tracking settings.Note: You must use the USER_SRP_AUTH authentication flow to use the device tracking feature. To use remembered devices to replace multi-factor authentication (MFA), you must also turn on MFA for your user pool.Remembering devices is a two-part process:Confirming a new device. Initiate authentication from the device, and then confirm it with Amazon Cognito to get unique device identifiers.Verifying a confirmed device. Initiate authentication from a confirmed device to skip the MFA step on subsequent sign-in attempts.

ResolutionNote: The following instructions describe the Amazon Cognito API calls to make in your app client's code. If you're using a client-side SDK, such as the AWS Mobile SDKs for Android or iOS, then much of the implementation is handled by the SDK.Set up remembered devicesIn the Amazon Cognito console, choose Manage user pools, and then choose your user pool.In the left navigation pane, under General settings, choose Devices.For Do you want to remember your user's devices, choose Always or User Opt In. For more information, see Tracking and remembering devices using Amazon Cognito your user pools.For Do you want to use a remembered device to suppress the second factor during multi-factor authentication (MFA), choose Yes or No. For more information, see Using remembered devices to suppress multi-factor authentication (MFA).Note: If these options don't appear, then MFA isn't activated. To set up MFA, in the left navigation pane, choose MFA and verifications.Choose Save changes.Call SetUserMFAPreferenceIn your app client's code, call the SetUserMFAPreference API to set the MFA preference to true for the MFA methods that you're using.Call InitiateAuthIn your app client's code, call the InitiateAuth API to get the device keys. In this API request, be sure to include the following request parameters:AuthFlow. Use USER_SRP_AUTH.AuthParameters. Include the authentication parameters USERNAME, SRP_A, and SECRET_HASH.Note: SECRET_HASH is required only if your app client is configured with a client secret.Calculate SRP_A using this formula:SRP_A = ga (mod N)Use g as defined in AuthenticationHelper.js on the AWS Amplify (JavaScript) GitHub repository.Let a = 128 random bytesFor more information, see request syntax and the API reference for your chosen AWS SDK.Call RespondToAuthChallenge for MFA challengesAfter your app client makes the InitiateAuth API call, your Amazon Cognito user pool returns a set of MFA challenges based on the MFA methods that you activated.Your app must answer these challenges using the RespondToAuthChallenge API. For example, if you activated SMS text message MFA in your user pool, then include the parameter ChallengeName with the value SMS_MFA. For more information, see request syntax and the API reference for your chosen AWS SDK.Store the device keysWhen all MFA challenges are answered, Amazon Cognito responds with a DeviceGroupKey and a unique DeviceKey in the NewDeviceMetadataType field.When you use the AWS Mobile SDK for Android, iOS, or JavaScript in the Browser, these keys are automatically moved to the device's local storage by the application. If you're using another AWS SDK, then be sure to design a similar key storage solution for your app.Call ConfirmDeviceWith the DeviceGroupKey and DeviceKey, create a secret using the Secure Remote Password (SRP) protocol, which generates a salt and a password verifier. Pass these to Amazon Cognito in a ConfirmDevice API call that includes the following request parameters:AccessToken. Use a valid access token for the user.DeviceKey. Use the unique key for the device, returned from Amazon Cognito.DeviceName. Use a name that you give to the device. (The AWS Mobile SDKs use User Agent.)DeviceSecretVerifierConfig. Include Salt (16 random bytes, base64-encoded) and PasswordVerifier.For PasswordVerifier, use this formula:PasswordVerifier = g( SHA256_HASH(salt + FULL_PASSWORD) ) (mod N)Use g as defined in AuthenticationHelper.js on the AWS Amplify (JavaScript) GitHub repository.Let FULL_PASSWORD = SHA256_HASH(DeviceGroupKey + username + ":" + RANDOM_PASSWORD)Let RANDOM_PASSWORD = 40 random bytes, base64-encodedUse N as defined in AuthenticationHelper.js on the AWS Amplify (JavaScript) GitHub repository.For more information, see request syntax and the API reference for your chosen AWS SDK.(Optional) Call UpdateDeviceStatusWhen setting up remembered devices in your user pool, you can skip this step if you choose Always. If you choose User Opt In, then you must include an UpdateDeviceStatus API call.Note: If you're using the Amazon Cognito Identity SDK for JavaScript, then you must instead call setDeviceStatusRemembered or setDeviceStatusNotRemembered. For more information, see Usage in the SDK's README file on GitHub.When you give your app's users an option to have their device remembered, confirming the device tracks it in your user pool as 'non-remembered.' You must ask the user whether they want to have the device remembered, and then send their input using the UpdateDeviceStatus API.Note: When opt-in is required, the user must opt-in before the device can be remembered and the MFA challenge can be suppressed.Call InitiateAuth with the device keyIn your app client's code, call the InitiateAuth API to verify a remembered device. In this call, include the device key in the request parameters as follows:AuthFlow. Use USER_SRP_AUTH.AuthParameters. Include the authentication parameters USERNAME, SRP_A, and DEVICE_KEY.For more information, see request syntax and the API reference for your chosen AWS SDK.Call RespondToAuthChallenge for DEVICE_SRP_AUTHAfter your app client makes the InitiateAuth API call with a valid device key, your Amazon Cognito user pool returns the PASSWORD_VERIFIER challenge. You must include the DEVICE_KEY in the challenge response. Then, you receive the DEVICE_SRP_AUTH challenge. To respond, call the RespondToAuthChallenge API and include the following request parameters:ChallengeName. Use DEVICE_SRP_AUTH.ClientId. Use a valid app client ID.ChallengeResponses. Include USERNAME, DEVICE_KEY, and SRP_A in these responses.Note: For SRP_A, use the formula mentioned earlier in these instructions.After this API call, Amazon Cognito responds with one more challenge: DEVICE_PASSWORD_VERIFIER. In the response, you also get the values for the ChallengeParameters SECRET_BLOCK and SRP_B, which you need for responding to the challenge.For more information, see request syntax and the API reference for your chosen AWS SDK.Call RespondToAuthChallenge for DEVICE_PASSWORD_VERIFIERTo respond to the DEVICE_PASSWORD_VERIFIER challenge, call the RespondToAuthChallenge API and include the following request parameters:ChallengeName. Use DEVICE_PASSWORD_VERIFIER.ClientId. Use a valid app client ID.ChallengeResponses. Include USERNAME, PASSWORD_CLAIM_SECRET_BLOCK, TIMESTAMP, PASSWORD_CLAIM_SIGNATURE, and DEVICE_KEY.Define the challenge responses as follows:For PASSWORD_CLAIM_SECRET_BLOCK, use the value of SECRET_BLOCK.For TIMESTAMP, include the current time. (For example, Tue Sep 25 00:09:40 UTC 2018.)Let PASSWORD_CLAIM_SIGNATURE = SHA256_HMAC(K_USER, DeviceGroupKey + DeviceKey + PASSWORD_CLAIM_SECRET_BLOCK + TIMESTAMP), base64-encodedLet K_USER = SHA256_HASH(S_USER)Let S_USER = [ ( SRP_B - [ k * [ (gx) (mod N) ] ] )(a + ux) ](mod N)Let x = SHA256_HASH(salt + FULL_PASSWORD)Let u = SHA256_HASH(SRP_A + SRP_B)Let k = SHA256_HASH(N + g)Get JSON web tokens from your user poolAfter successfully responding to the last challenge, your Amazon Cognito user pool returns JSON web tokens in the AuthenticationResult:{     "AuthenticationResult": {         "AccessToken": "...",         "ExpiresIn": 3600,         "IdToken": "...",         "RefreshToken": "...",         "TokenType": "Bearer"     },     "ChallengeParameters": {} }Related informationUser pool authentication flowUser pools reference (AWS Management Console)CognitoUser.js (AWS Amplify GitHub repo)