Skip to content
AWS aws iam 6 min read

Enabling MFA

A password on its own is a weak gate. People reuse passwords, fall for phishing emails, and leak credentials in ways you never find out about. MFA (multi-factor authentication) fixes this by demanding a second proof of identity at sign-in — something you have (a phone or a hardware key) on top of something you know (the password). With MFA enabled, a stolen password alone is useless to an attacker. This page explains the supported MFA types, walks through turning it on for both the root user and an IAM (Identity and Access Management) user, and shows the gotcha most guides miss: how to enforce MFA with a policy instead of just hoping people enable it.

What MFA is and why it matters

Authentication factors come in categories: something you know (a password), something you have (a device), and something you are (a fingerprint). MFA simply means using more than one category. After you type your password, AWS asks for a second factor — usually a short numeric code or a tap on a security key.

The most important place to enable MFA is the root user — the all-powerful account owner created when you first signed up. The root user can close the account, change billing, and bypass most permission controls. If its password leaks and there is no MFA, an attacker owns everything. AWS now strongly nudges you toward this, and for some account types MFA on root is mandatory.

MFA is not optional for humans. Treat MFA as mandatory for the root user and for every IAM user who can sign in to the AWS Management Console (the web dashboard). A console password without MFA is a single point of failure.

Supported MFA types — which to choose

AWS supports several kinds of second factor. You can even register more than one per user as a backup.

MFA typeWhat it isBest forWatch out for
Virtual TOTP appA phone/desktop app (Google Authenticator, Authy, 1Password) that generates a 6-digit TOTP (time-based one-time password) every 30 secondsEveryone — the easy, free defaultCodes live on one device; losing the phone without a backup locks you out
Passkey / FIDO2A passwordless credential stored in your device or browser (Face ID, Touch ID, Windows Hello)Modern, phishing-resistant human sign-inNeeds a compatible device/browser
Hardware security keyA physical key (YubiKey and similar) you plug in or tap over NFCHigh-security admins, break-glass root accessCosts ~$25-$70 per key; keep a spare

A virtual TOTP app is the simplest starting point and costs nothing. For the root user and for privileged admins, a hardware security key or passkey is stronger because it is resistant to phishing — there is no code an attacker can trick you into typing.

Enabling MFA on the root user

Sign in as the root user (using the email address you signed up with), then:

  1. Open the account menu at the top right and choose Security credentials.
  2. In the Multi-factor authentication (MFA) section, choose Assign MFA device.
  3. Enter a device name, pick a type (Authenticator app, Passkey or security key, or Hardware TOTP token), and choose Next.
  4. For an authenticator app: scan the QR code with your app, then enter two consecutive codes it generates to confirm pairing.
  5. Choose Add MFA. You are done — the next root sign-in will ask for a code.

Root MFA cannot be done with the CLI. The AWS CLI (Command Line Interface) can manage MFA for IAM users, but the root user’s MFA must be configured in the Console while signed in as root. Store the recovery details and any backup device somewhere safe and offline.

Enabling MFA on an IAM user

Console steps

  1. Open the IAM console at https://console.aws.amazon.com/iam/.
  2. Choose Users, click the user (for example jane.doe), then open the Security credentials tab.
  3. Under Multi-factor authentication (MFA), choose Assign MFA device.
  4. Name the device, pick the MFA type, and choose Next.
  5. Scan the QR code (for an app) or follow the prompts (for a security key/passkey), then enter the verification code(s).
  6. Choose Add MFA.

A best practice is to let users enable their own MFA. You grant them a small self-service policy, send them the sign-in link, and they register a device on first login.

CLI for a virtual MFA device

First create the virtual device. The QR code is returned as a PNG you decode, scan, then confirm:

aws iam create-virtual-mfa-device \
  --virtual-mfa-device-name jane.doe \
  --outfile /tmp/jane-qr.png \
  --bootstrap-method QRCodePNG

Output:

{
    "VirtualMFADevice": {
        "SerialNumber": "arn:aws:iam::123456789012:mfa/jane.doe"
    }
}

Scan /tmp/jane-qr.png with an authenticator app, then bind the device to the user by submitting two consecutive codes:

aws iam enable-mfa-device \
  --user-name jane.doe \
  --serial-number arn:aws:iam::123456789012:mfa/jane.doe \
  --authentication-code1 123456 \
  --authentication-code2 789012

This command produces no output on success. The user must now provide an MFA code when signing in to the Console.

The gotcha: enforce MFA with a policy

Enabling MFA on a device only allows MFA — it does not require it. A user with a password can still skip the setup and keep working. To actually force it, attach a policy that uses the aws:MultiFactorAuthPresent condition key. This denies sensitive actions unless the current session was authenticated with MFA, while still letting the user manage their own MFA device so they can get set up.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowManageOwnMFA",
      "Effect": "Allow",
      "Action": [
        "iam:CreateVirtualMFADevice",
        "iam:EnableMFADevice",
        "iam:ListMFADevices",
        "iam:ResyncMFADevice"
      ],
      "Resource": [
        "arn:aws:iam::123456789012:mfa/${aws:username}",
        "arn:aws:iam::123456789012:user/${aws:username}"
      ]
    },
    {
      "Sid": "DenyEverythingElseWithoutMFA",
      "Effect": "Deny",
      "NotAction": [
        "iam:CreateVirtualMFADevice",
        "iam:EnableMFADevice",
        "iam:ListMFADevices",
        "iam:ResyncMFADevice",
        "iam:GetUser",
        "iam:ChangePassword"
      ],
      "Resource": "*",
      "Condition": {
        "BoolIfExists": { "aws:MultiFactorAuthPresent": "false" }
      }
    }
  ]
}

The Deny statement is the enforcer: if aws:MultiFactorAuthPresent is false, almost everything is blocked. The small Allow list (plus the carve-outs in NotAction) is what lets a brand-new user log in and register a device. BoolIfExists makes the check behave sensibly for credential types where the key is absent.

Use a Deny, not an Allow. Only an explicit Deny reliably blocks users who already have other permissions. “Encouraging” MFA through documentation does not work — a policy condition is the only thing that truly stops a non-MFA session from doing damage.

Cost note

MFA itself is free — AWS does not charge for assigning virtual, passkey, or hardware MFA devices, and there is no per-sign-in fee. The only cost is hardware: a physical security key runs roughly $25-$70, while authenticator apps are free. Given that a single compromised root account can lead to thousands of dollars of fraudulent usage, MFA is the cheapest security control you will ever add.

Best Practices

  • Enable MFA on the root user first, then lock the root credentials away and use it almost never.
  • Require MFA for every IAM user that has a console password — make it non-negotiable.
  • Enforce MFA with an aws:MultiFactorAuthPresent policy condition; do not rely on people opting in.
  • Use phishing-resistant factors (hardware security keys or passkeys) for privileged admins and root.
  • Register a backup MFA device, or store recovery details safely, so a lost phone does not lock you out.
  • Prefer IAM Identity Center for human sign-in, where MFA can be enforced centrally across all accounts.
  • Audit regularly with the IAM credential report to find any user that still lacks an MFA device.
Last updated June 15, 2026
Was this helpful?