Skip to main content

Ensure Multi-Factor Authentication (MFA) is Enabled for Amazon Cognito User Pools

Overview

This check verifies that your Amazon Cognito User Pools have Multi-Factor Authentication (MFA) enabled and enforced. MFA adds a second layer of security beyond passwords, requiring users to provide an additional verification factor when signing in.

Risk

Without MFA, user accounts are vulnerable to:

  • Credential theft: Stolen or guessed passwords give attackers full access
  • Phishing attacks: Users tricked into revealing passwords have no backup protection
  • Brute force attacks: Automated password guessing can compromise accounts
  • Credential stuffing: Reused passwords from other breaches can be exploited

A compromised account can lead to unauthorized access to your application data, APIs, and user information.

Remediation Steps

Prerequisites

You need permission to modify Cognito User Pool settings. Typically this requires the cognito-idp:SetUserPoolMfaConfig IAM permission.

IAM permissions details

The following IAM permissions are needed:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"cognito-idp:SetUserPoolMfaConfig",
"cognito-idp:DescribeUserPool"
],
"Resource": "arn:aws:cognito-idp:us-east-1:<account-id>:userpool/<user-pool-id>"
}
]
}

AWS Console Method

  1. Open the Amazon Cognito console
  2. Select the user pool you want to configure
  3. In the left navigation, click Sign-in experience
  4. Scroll to the Multi-factor authentication section and click Edit
  5. Under MFA enforcement, select Require MFA - All users must sign in with an additional factor
  6. Under MFA methods, check Authenticator apps (TOTP)
  7. Click Save changes

Important: Requiring MFA affects all users. Ensure users have a way to set up their authenticator app before enforcing MFA, or use "Optional MFA" initially to allow gradual adoption.

AWS CLI

Enable required MFA with TOTP (authenticator apps):

aws cognito-idp set-user-pool-mfa-config \
--user-pool-id <your-user-pool-id> \
--software-token-mfa-configuration Enabled=true \
--mfa-configuration ON \
--region us-east-1

Enable optional MFA (users can choose to enable):

aws cognito-idp set-user-pool-mfa-config \
--user-pool-id <your-user-pool-id> \
--software-token-mfa-configuration Enabled=true \
--mfa-configuration OPTIONAL \
--region us-east-1

Replace <your-user-pool-id> with your actual user pool ID (format: us-east-1_xxxxxxxxx).

MFA configuration options:

  • ON - MFA is required for all users
  • OPTIONAL - Users can choose to enable MFA
  • OFF - MFA is disabled (not recommended)
CloudFormation
AWSTemplateFormatVersion: '2010-09-09'
Description: Amazon Cognito User Pool with MFA enabled

Parameters:
UserPoolName:
Type: String
Description: Name of the Cognito User Pool
Default: my-secure-user-pool

Resources:
CognitoUserPool:
Type: AWS::Cognito::UserPool
Properties:
UserPoolName: !Ref UserPoolName
MfaConfiguration: 'ON'
EnabledMfas:
- SOFTWARE_TOKEN_MFA
Policies:
PasswordPolicy:
MinimumLength: 12
RequireLowercase: true
RequireNumbers: true
RequireSymbols: true
RequireUppercase: true

Outputs:
UserPoolId:
Description: ID of the Cognito User Pool
Value: !Ref CognitoUserPool
UserPoolArn:
Description: ARN of the Cognito User Pool
Value: !GetAtt CognitoUserPool.Arn

MfaConfiguration values:

  • ON - MFA required for all users
  • OPTIONAL - Users can choose to enable MFA
  • OFF - MFA disabled (not recommended)

EnabledMfas options:

  • SOFTWARE_TOKEN_MFA - Authenticator apps (TOTP)
  • SMS_MFA - SMS-based codes (requires additional SNS configuration)
Terraform
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}

provider "aws" {
region = "us-east-1"
}

resource "aws_cognito_user_pool" "example" {
name = "example-pool"

mfa_configuration = "ON"

software_token_mfa_configuration {
enabled = true
}
}

mfa_configuration values:

  • ON - MFA required for all users
  • OPTIONAL - Users can choose to enable MFA
  • OFF - MFA disabled (not recommended)

For SMS MFA, you would also need to configure sms_configuration with an IAM role for SNS.

Verification

After enabling MFA, verify the configuration:

  1. In the Cognito console, open your user pool
  2. Go to Sign-in experience
  3. Confirm the Multi-factor authentication section shows "Required" or your chosen setting
  4. Test by signing in with a user account - you should be prompted for MFA
CLI verification
aws cognito-idp describe-user-pool \
--user-pool-id <your-user-pool-id> \
--query 'UserPool.MfaConfiguration' \
--region us-east-1

Expected output for required MFA:

"ON"

Additional Resources

Notes

  • User impact: Enabling required MFA affects all existing and new users. Plan for user communication and support.
  • TOTP vs SMS: Authenticator apps (TOTP) are more secure than SMS-based MFA. SMS can be vulnerable to SIM swapping attacks.
  • Gradual rollout: Consider using "Optional" MFA first to let users adopt at their own pace, then switch to "Required" once adoption is high.
  • Recovery: Ensure you have account recovery options configured (email/phone verification) in case users lose access to their MFA device.
  • SMS costs: If using SMS MFA, be aware of Amazon SNS messaging costs and ensure your account is out of the SMS sandbox for production use.