Reading20 min read·Module 1

Multi-Factor Authentication (MFA)

Key concepts

  • Virtual MFA devices (authenticator apps)

  • Hardware MFA devices

  • U2F security keys

  • MFA for root account is critical

  • MFA delete for S3

The Email That Almost Got Mara

Three months after the Theo incident, Trailbase runs a tidy account. Every human has an IAM user, the developers inherit permissions through groups, and the EC2 fleet uploads hiker photos through an instance role. Then an email lands in Mara's inbox. It carries the AWS logo, a plausible sender address, and a warning that her console access will be suspended unless she verifies her credentials within 24 hours. The link opens a pixel-perfect copy of the AWS sign-in page on a lookalike domain, and Mara, deep in a data migration and running on cold coffee, types her password before the URL registers.

She catches it a second later and tells Dana, who rotates the password within the hour. Nothing is lost. But the near miss exposes an uncomfortable truth: every identity at Trailbase is guarded by a single string of characters, and a string can be phished, guessed, leaked, or shoulder-surfed. All the least-privilege work from the last lesson assumed the person typing the password really is Mara.

Multi-Factor Authentication (MFA) exists to break that single point of failure. Authentication factors come in three categories: something you know (a password), something you have (a physical or virtual device), and something you are (biometrics such as a fingerprint). MFA requires proof from two or more categories, so a stolen password alone opens nothing. The attacker who phished Mara's password would still need the phone in her pocket. This one control prevents over 99% of password-related attacks.

MFA Is Now Mandatory for Root

As of 2025, AWS requires MFA for all root users across all account types. Root users of AWS Organizations member accounts must register an MFA device within 35 days of first sign-in to keep using the AWS Management Console. Dana enabled hers long before AWS forced the issue.

Exam Tip

SAA-C03 tests MFA from two angles: which device type is phishing-resistant (only FIDO2 security keys and passkeys) and which condition key enforces MFA in a policy (aws:MultiFactorAuthPresent). When a scenario says phishing-resistant, eliminate every TOTP option on sight.


How a Second Factor Changes the Sign-In

Here is what Mara's sign-in looks like once Dana turns MFA on. The password still comes first, and then AWS demands proof of the second factor before any session exists.

MFA Authentication Flow
Figure 1: The MFA authentication flow. A password alone gets you to step two, never to a session.

The flow has four steps. First, the user presents a username and password, the something-you-know factor. Second, AWS issues an MFA challenge matched to whatever device the user registered. Third, the user proves possession of that device, and the proof differs by type:

MFA TypeUser ActionVerification
Security KeyTouch deviceCryptographic signature
PasskeyBiometric/PINCryptographic signature
Virtual MFAEnter 6-digit codeTOTP validation
Hardware TOTPEnter 6-digit codeTOTP validation

Fourth, and only after both factors verify, AWS grants the session. Notice the two verification mechanisms in that table, because the entire security difference between MFA types lives there: cryptographic signatures resist phishing, and typed codes do not.


Who Carries What at Trailbase

Dana rolls out MFA the same way she rolled out least privilege: match the tool to the person and the risk. AWS supports three families of MFA devices, and each one has a natural owner at Trailbase.

MFA Types Comparison
Figure 2: The three MFA device families compared. FIDO2 devices sign challenges; TOTP devices display codes.

FIDO2 Security Keys and Passkeys: Dana and the Root Account

For the root account and her own admin user, Dana buys two hardware security keys. A security key is a small physical device, a YubiKey for example, that connects over USB, NFC, or Bluetooth and authenticates using the FIDO2 standard, an open protocol built on public key cryptography: the key holds a private key that never leaves the device, and AWS holds the matching public key.

This design is what makes FIDO2 phishing-resistant. During sign-in, the browser asks the key to sign a challenge that is cryptographically bound to the real domain. The lookalike page that fooled Mara would receive no valid signature at all, because the key only signs for the origin it was registered with. There is no code on screen for an attacker to steal, and nothing the user can be tricked into typing.

Passkeys and Security Keys (FIDO2)

FIDO2 authentication is the strongest MFA that AWS offers, and it comes in two forms.

Security keys (hardware) are physical devices like YubiKeys that connect via USB, NFC, or Bluetooth. They need no batteries, one key can protect multiple AWS accounts, and authentication is a touch rather than a typed code.

Synced passkeys (software) are the same cryptography stored as cloud-synced credentials in iCloud Keychain, Google Password Manager, 1Password, or Dashlane, unlocked with a fingerprint, a face scan, or a device PIN. They are phishing-resistant like hardware keys and cost nothing.

Both forms sign a challenge bound to the real AWS domain, which is why neither can be phished by a fake sign-in page.

Virtual MFA Apps: Mara and the Developers

For everyone else, Dana standardizes on virtual MFA apps, the free and fast option. A virtual MFA device is an authenticator app that generates a time-based one-time password (TOTP): a 6-digit code, derived from a secret seed shared with AWS at enrollment plus the current time, that changes every 30 seconds under the RFC 6238 algorithm. Google Authenticator, Microsoft Authenticator, Authy, and Duo Mobile all work, and a single app can hold tokens for many accounts.

The honest caveat: TOTP raises the bar without being phish-proof. A sufficiently patient attacker can build a fake page that asks for the code too and relays it to AWS within its 30-second window. Mara's phishing email could have been built exactly that way. That residual risk is why Dana keeps FIDO2 on the identities that can do the most damage.

Virtual MFA Devices (TOTP)

Virtual MFA applications generate time-based one-time passwords: 6-digit codes that rotate every 30 seconds, computed from a shared seed and a synchronized clock per RFC 6238.

They are free, take two minutes to set up, and one app can store tokens for multiple accounts. The trade-offs are that codes must be typed manually, the device clock must stay in sync with AWS, and a real-time phishing page can capture and replay a code within its validity window.

Hardware TOTP Tokens: The Compliance Corner

When Priya's audit firm reviews Trailbase, her checklist includes environments where phones are banned from the room. That is the niche for hardware TOTP tokens: dedicated battery-powered devices, such as Thales tokens purchased with an AWS-approved pre-shared seed, that display the same rotating 6-digit codes as an app. They satisfy compliance regimes that mandate a physical token and work where no phone is allowed.

Hardware TOTP Tokens

Hardware TOTP tokens are standalone physical devices that display 6-digit time-based codes. The seed must come pre-shared from AWS-approved sources, the battery has a finite lifespan, and each token binds to exactly one user.

Reach for them in high-security or air-gapped environments and where compliance explicitly requires a hardware token. Otherwise AWS recommends FIDO2 security keys instead, which are phishing-resistant, battery-free, and reusable across accounts.

MFA Device Comparison

FeatureFIDO2 Security KeyPasskey (Synced)Virtual MFA AppHardware TOTP
Phishing ResistantYesYesNoNo
Battery RequiredNoNo (device battery)No (device battery)Yes
Cost$20-50FreeFree$15-30
Multiple AccountsYesYesYes (in app)No (1 per device)
Backup MethodSecond keyCloud syncRecovery codesManual backup
Best ForHigh securityConvenience + securityGeneral useCompliance
Q

Trailbase wants phishing-resistant MFA for everyone who can touch production. Which device type qualifies?

AVirtual MFA apps (TOTP)
BHardware TOTP tokens
CSMS text messages
DFIDO2 security keys and passkeys

Registering Devices, and Why One Is Never Enough

Enrollment is quick: in the IAM console, open the user, go to the Security credentials tab, choose Assign MFA device, and follow the wizard for the device type. The limits matter more than the clicks. Every user, including root, can register up to 8 MFA devices in any mix of types, while each individual device belongs to exactly one user and can never be shared.

That 8-device ceiling is an invitation, and Dana accepts it. She registers a second security key for root and locks it in a fire safe, because a lost sole device turns MFA from a shield into a lockout. Mara registers both her authenticator app and a synced passkey. Losing one factor should mean reaching for the backup, never filing a support case.

MFA Device Limits

Account TypeMax MFA DevicesNotes
Root User8 devicesCan mix different MFA types
IAM User8 devicesCan mix different MFA types
Per Device1 user onlyCannot share devices between users

When recovery is needed anyway, the path depends on who lost what. An IAM administrator can deactivate a user's MFA device and let them re-enroll, so Mara losing her phone costs minutes. Root recovery goes through the AWS Support identity verification process and can take days, which is exactly why the fire safe exists.

MFA Recovery Options

ScenarioRecovery Method
Lost virtual MFA deviceUse backup MFA device or contact AWS Support
Lost security keyUse backup security key or passkey
All MFA devices lost (IAM user)Admin can deactivate MFA and allow re-enrollment
All MFA devices lost (root user)AWS Support identity verification process
Q

How many MFA devices can a single IAM user register?

A1
B2
C5
D8

Enforcing MFA: Turning a Habit into a Rule

A week after rollout, Dana spots a gap. Everyone has enrolled a device, but enrollment by itself only protects console sign-in. A developer using long-term access keys from the CLI skips MFA entirely, and nothing stops a user from simply never enrolling. Policy from lesson 1 gives her the fix: IAM conditions can inspect whether a request was MFA-authenticated and deny it when it was not.

Two condition keys do the work. aws:MultiFactorAuthPresent is a Boolean that is true when the request rides on MFA-backed temporary credentials. aws:MultiFactorAuthAge is the number of seconds since MFA authentication happened, which lets you demand a fresh challenge for the scariest operations even inside a valid session.

Enforcing MFA with IAM Policies

IAM policies can require MFA per action using two condition keys.

aws:MultiFactorAuthPresent is true when the request was authenticated with MFA and false when it was not. Requests signed with long-term access keys omit the key entirely, which is why enforcement policies pair it with the BoolIfExists operator.

aws:MultiFactorAuthAge counts seconds since MFA authentication, so you can require a recent second factor for sensitive operations rather than trusting a session that authenticated hours ago.

Here is the policy Dana attaches to the Developers group. It denies everything except a short self-service list until MFA is present, so a user without a device can enroll one and can do nothing else:

JSONPolicy: Deny Actions Without MFA
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyAllExceptListedWithoutMFA",
      "Effect": "Deny",
      "NotAction": [
        "iam:CreateVirtualMFADevice",
        "iam:EnableMFADevice",
        "iam:GetUser",
        "iam:ListMFADevices",
        "iam:ListVirtualMFADevices",
        "iam:ResyncMFADevice",
        "sts:GetSessionToken"
      ],
      "Resource": "*",
      "Condition": {
        "BoolIfExists": {
          "aws:MultiFactorAuthPresent": "false"
        }
      }
    }
  ]
}

Two elements deserve a slow read. NotAction inverts the action list: the deny applies to every action except the MFA-enrollment calls named there, which keeps the bootstrap path open. BoolIfExists handles the sneaky case. A request signed with long-term access keys carries no aws:MultiFactorAuthPresent key at all, and a plain Bool check would let it slide through unmatched. BoolIfExists treats a missing key as a match, so key-based requests get denied too. Recall the evaluation ladder from lesson 1: this explicit Deny beats every Allow the developer holds.

For the actions that ended Theo's bucket, Dana goes further and requires that MFA happened within the last hour:

JSONPolicy: Require Recent MFA (Within 1 Hour)
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "RequireRecentMFA",
      "Effect": "Deny",
      "Action": [
        "ec2:StopInstances",
        "ec2:TerminateInstances",
        "rds:DeleteDBInstance"
      ],
      "Resource": "*",
      "Condition": {
        "NumericGreaterThan": {
          "aws:MultiFactorAuthAge": "3600"
        }
      }
    }
  ]
}
Q

Which IAM condition key checks whether a request was authenticated with MFA?

Aaws:MFAEnabled
Baws:MultiFactorAuthPresent
Caws:SecondFactorAuth
Diam:MFARequired

MFA on the Command Line

The morning after the enforcement policy lands, Mara's migration script starts failing with AccessDenied, which means the policy is working. Her script authenticates with access keys, and access keys carry no MFA context. Her first instinct, plugging her security key into the laptop, goes nowhere, because FIDO2 works only with the AWS Management Console. The CLI and the APIs accept MFA exclusively through TOTP codes exchanged for temporary credentials.

The exchange goes through sts:GetSessionToken, an STS call that takes the ARN of her MFA device (its serial number) plus the current 6-digit code and returns temporary credentials that are flagged as MFA-authenticated. Mara exports those, and every subsequent CLI call passes the aws:MultiFactorAuthPresent check until they expire:

SHUsing MFA with AWS CLI
# Get temporary credentials with MFA
aws sts get-session-token \
  --serial-number arn:aws:iam::123456789012:mfa/user-name \
  --token-code 123456

# Response contains temporary credentials:
# {
#   "Credentials": {
#     "AccessKeyId": "ASIA...",
#     "SecretAccessKey": "...",
#     "SessionToken": "...",
#     "Expiration": "2024-01-15T12:00:00Z"
#   }
# }

# Export credentials for subsequent commands
export AWS_ACCESS_KEY_ID=ASIA...
export AWS_SECRET_ACCESS_KEY=...
export AWS_SESSION_TOKEN=...

Notice that sts:GetSessionToken sits in the NotAction list of Dana's enforcement policy. That is deliberate: the call has to be reachable without MFA, since it is the very step that trades an MFA code for MFA-flagged credentials.

Q

Mara needs her production script to run with MFA-backed credentials from the CLI. What must she do?

APlug in her FIDO2 security key
BCall aws sts get-session-token with her MFA serial number and current code
CAdd an mfa flag to every CLI command
DNothing, because MFA applies only to the console

Trailbase, Two Factors Deep

The phishing email that started this lesson would land differently today. Mara's password alone buys an attacker a login form asking for a factor they do not have. Root and Dana answer challenges with security keys that no fake page can satisfy, and a spare key sits in the fire safe. Every developer enrolled within a day, because the Developers policy made an MFA-less session nearly useless. Even Mara's scripts prove a second factor before they touch production, and CloudTrail records every enrollment and challenge along the way.

The Trailbase MFA Playbook

Prefer FIDO2 keys or passkeys wherever phishing resistance matters, and put hardware keys on root. Register at least two devices per identity and store the backup securely. Then enforce MFA in policy with aws:MultiFactorAuthPresent, because a factor that is optional protects only the diligent. Monitor compliance with AWS Config rules such as iam-user-mfa-enabled.

Exam Tip

SAA-C03 MFA questions are matching exercises: strongest or phishing-resistant maps to FIDO2, convenience plus security maps to synced passkeys, compliance-mandated hardware maps to TOTP tokens, and enforce in policy maps to aws:MultiFactorAuthPresent. Any scenario mixing MFA with CLI access is pointing at sts:GetSessionToken.

MFA Exam Scenarios

ScenarioSolutionWhy
Company wants phishing-resistant MFA for executivesFIDO2 security keys or passkeysCryptographic authentication cannot be phished
Users complain MFA is inconvenientSynced passkeys with biometricsOne-touch authentication, synced across devices
Require MFA only for production account accessIAM policy with aws:MultiFactorAuthPresent conditionEnforces MFA at policy level
User lost their MFA deviceAdmin deactivates MFA, user re-enrolls with new deviceIAM admins can manage user MFA devices
Need MFA for CLI/API accessUse sts:GetSessionToken with MFA codeCLI requires temporary credentials for MFA
Compliance requires hardware MFA tokensHardware TOTP tokens from AWS-approved vendorPhysical token meets compliance requirements

Common Pitfalls

A Naked Root Account

Root has unrestricted access that no IAM policy can limit, so an unprotected root password is a single point of total failure. Enable MFA on root immediately after account creation, use the strongest device available (a FIDO2 security key), and register a backup device stored somewhere safe. AWS now mandates this, and the mandate arrived because too many accounts learned it the hard way.

One Device, No Backup

A single registered MFA device means one dropped phone stands between you and your account, and root recovery through AWS Support identity verification can take days. Every user gets up to 8 device slots. Use at least two of them, keep the backup in a separate secure location, and make sure passkeys are actually syncing to their cloud backup.

Expecting FIDO2 to Work in the Terminal

FIDO2 security keys and passkeys authenticate the Management Console only. The CLI and APIs require a TOTP device plus a call to sts:GetSessionToken to exchange the code for temporary credentials. Users who registered only a security key will discover they cannot satisfy an MFA-enforcement policy from the command line at all.

MFA Enabled but Never Enforced

Enrolling devices without a policy behind them leaves the back door open, since long-term access keys bypass console MFA entirely. Write a Deny with the aws:MultiFactorAuthPresent condition and the BoolIfExists operator so that key-signed requests, which omit the MFA context key, are denied too. Enforcement in policy is what turns MFA from a habit into a guarantee.


Quick Reference

TEXTMFA Condition Keys
aws:MultiFactorAuthPresent    - Boolean: true if MFA was used
aws:MultiFactorAuthAge        - Numeric: seconds since MFA authentication
SHMFA CLI Commands
# List MFA devices for current user
aws iam list-mfa-devices

# List all virtual MFA devices in account
aws iam list-virtual-mfa-devices

# Create virtual MFA device
aws iam create-virtual-mfa-device --virtual-mfa-device-name MyMFADevice

# Enable MFA device for user
aws iam enable-mfa-device \
  --user-name username \
  --serial-number arn:aws:iam::123456789012:mfa/MyMFADevice \
  --authentication-code1 123456 \
  --authentication-code2 789012

# Deactivate MFA device
aws iam deactivate-mfa-device \
  --user-name username \
  --serial-number arn:aws:iam::123456789012:mfa/MyMFADevice

# Get session token with MFA
aws sts get-session-token \
  --serial-number arn:aws:iam::123456789012:mfa/username \
  --token-code 123456
TEXTMFA Device ARN Formats
Virtual MFA:  arn:aws:iam::ACCOUNT-ID:mfa/DEVICE-NAME
Hardware:     arn:aws:iam::ACCOUNT-ID:mfa/SERIAL-NUMBER
Root MFA:     arn:aws:iam::ACCOUNT-ID:mfa/root-account-mfa-device


Further Reading

Related services

IAMS3