A password policy reduces basic risk
The account password policy can set minimum length, character requirements, reuse prevention, expiry, and whether users may change their own passwords. Complexity does not replace MFA; favor long, unique passwords managed by a password manager. Very frequent forced expiry tends to produce weaker, predictable passwords, so current guidance prefers length and MFA over constant rotation.
flowchart LR U["dev-alice<br/>signs in"] --> P["Password<br/>something you know"] P --> M["MFA device<br/>something you have"] M --> V["Verified session<br/>Console"] T["Stolen password<br/>only"] -. "blocked" .-> X["Sign-in fails"] %% step U: A user starts a Console sign-in. %% step P: The password is the first factor and is checked against the password policy. %% step M: The second factor proves possession of a device: a security key, passkey or authenticator app. %% step V: Only with both factors does the session start. %% step T: An attacker who phished or guessed the password still lacks the device. %% step X: The sign-in is refused.
MFA types
| Type | How it works | Phishing resistance |
|---|---|---|
| FIDO2 security key or passkey | Hardware key or device biometrics, bound to the real site | Strongest |
| Virtual authenticator app | 6-digit TOTP codes on a phone | Good, but codes can be phished |
| Hardware TOTP token | Codes on a key fob | Good |
MFA blocks sign-in with only a stolen password. Enable MFA for root and privileged principals; a FIDO security key is more phishing-resistant than OTP codes. A virtual authenticator is still stronger than password-only access. An IAM user or root can register up to eight MFA devices, so register a backup to avoid lockout.
MFA for the CLI and API
Console MFA does not automatically require MFA for every access-key API request. To enforce MFA for APIs, a policy must inspect context such as aws:MultiFactorAuthPresent, and the caller needs an appropriate session:
{"Effect": "Deny", "NotAction": ["iam:*MFA*", "sts:GetSessionToken"], "Resource": "*",
"Condition": {"BoolIfExists": {"aws:MultiFactorAuthPresent": "false"}}}
The user then calls aws sts get-session-token --serial-number <mfa-arn> --token-code 123456 to get temporary credentials that carry the MFA flag. Identity Center users get MFA at the portal sign-in, which is simpler.
A practical baseline
- Root: strong password, a FIDO key or authenticator, no access keys.
- Every human: MFA required; prefer Identity Center.
- Password policy: at least 14 characters, prevent reuse, allow users to change their own.
- Alert when root signs in (CloudTrail + EventBridge) — it should be rare.
| Command | Purpose |
|---|---|
aws iam update-account-password-policy --minimum-password-length 14 ... |
Set the password policy |
aws iam get-account-password-policy |
View the current policy |
aws iam list-mfa-devices --user-name dev-alice |
View MFA devices |
aws iam create-virtual-mfa-device ... |
Create a virtual MFA device |
Traps: assuming Console MFA protects access keys; relying on complexity rules instead of MFA; registering a single MFA device and losing it.