2.7 IAM Password Policies and MFA Enforcement
Alright, let’s talk about locking down the front door. IAM users are great, but a username and password alone are about as secure as a screen door on a submarine. We’re going to fortify that door with two things: a brutally strong password policy and, far more importantly, Multi-Factor Authentication (MFA). Consider this non-negotiable. If you leave this section without setting up MFA, I will find out, and I will be very disappointed in you.
The Password Policy: Your First, Flimsy Line of Defense
AWS gives you a way to enforce a baseline level of password hygiene across your account. It’s not perfect, but it’s better than letting people set their password to “password”. You can configure things like minimum length, requiring different character types, and preventing re-use. You do this by creating a password policy. Here’s the thing: this is a global, account-wide setting. You don’t attach it to users; it just exists and applies to everyone.
Let’s set one up with the AWS CLI. The following command enforces 14-character passwords (because 12 is the new 8), requires a smorgasbord of character types, and prevents the more egregious security sins.
aws iam update-account-password-policy \
--minimum-password-length 14 \
--require-symbols \
--require-numbers \
--require-uppercase-characters \
--require-lowercase-characters \
--allow-users-to-change-password \
--max-password-age 90 \
--password-reuse-prevention 3
Why do we do this? Because humans are terrible at passwords. We’ll use our pet’s name followed by a “!”. This policy forces a bit of complexity. The --allow-users-to-change-password is crucial; without it, your IAM users are stuck with whatever password they have until an admin changes it for them—a massive pain for everyone involved.
The Pitfall: The password policy doesn’t apply to root user passwords or IAM users who sign in via AWS Single Sign-On (SSO). It’s only for IAM users signing directly into the AWS Management Console. It’s a good start, but it’s a tiny piece of the puzzle. A strong password is still just a password, and passwords get phished, leaked, and reused. Which brings us to the main event.
Multi-Factor Authentication: The Actual Lock
MFA is the concept of “something you know” (your password) plus “something you have” (a physical device that generates a code). It’s the single most effective security control you can enable in your AWS account, full stop. It’s the difference between a burglar guessing your hide-a-key is under the flowerpot and them also needing to pick the deadbolt.
AWS supports a variety of MFA devices: virtual ones like Google Authenticator or Authy, hardware key fobs like those from Yubico, and even FIDO2 security keys. For 99.9% of use cases, a virtual MFA device on your phone is perfectly sufficient and vastly better than nothing.
Enabling MFA for a user is a two-step process done via the CLI. First, you create the virtual MFA device association, which gives you a secret key. Then, the user uses that key to generate two consecutive codes to prove they have the device.
# Step 1: Create the virtual MFA device for the user
aws iam create-virtual-mfa-device \
--virtual-mfa-device-name MyVirtualMFADevice \
--outfile /tmp/QRCode.png \
--bootstrap-method QRCodePNG
# This command outputs a secret configuration key. You'll need it for the next step.
Now, the user (or you, acting as them) would use an app like Authy to scan the QR code generated in /tmp/QRCode.png. Then, to complete the enrollment, you submit two consecutive codes from the app.
# Step 2: Enable the MFA device for the IAM user
aws iam enable-mfa-device \
--user-name some-username \
--serial-arn arn:aws:iam::123456789012:mfa/MyVirtualMFADevice \
--authentication-code-1 123456 \
--authentication-code-2 789012
The Massive, Glaring Pitfall: Here’s the absurd part. If you have the iam:CreateVirtualMFADevice and iam:EnableMFADevice permissions, you can enable MFA on any user, including yourself, without having to prove you know their current password. AWS’s official stance is that the permission to alter MFA状态 is a highly privileged action and should be guarded accordingly. And they’re right! But it feels weirdly like being able to change the locks on someone else’s house without their consent. The lesson? Be extremely careful with who you grant those MFA permissions to. It’s a superpower.
Enforcing MFA with Policy Conditions
Creating a password policy and enabling MFA is useless if you don’t force its use. The only way to do that is by using IAM Policies with a specific condition key: aws:MultiFactorAuthPresent.
This condition key is true only if the user authenticated with a valid MFA device. You can use it to create policies that effectively say, “You can only do this dangerous thing if you used MFA to log in.”
Here’s a best practice: a policy that denies all actions unless MFA is present. You wouldn’t attach this broadly, but it’s perfect for highly privileged roles.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "BlockMostAccessUnlessSignedInWithMFA",
"Effect": "Deny",
"NotAction": [
"iam:CreateVirtualMFADevice",
"iam:EnableMFADevice",
"iam:GetUser",
"iam:ListMFADevices",
"iam:ListUsers",
"iam:ResyncMFADevice"
],
"Resource": "*",
"Condition": {
"BoolIfExists": {
"aws:MultiFactorAuthPresent": "false"
}
}
}
]
}
Notice the "BoolIfExists" instead of just "Bool". This is a critical nuance. It means “if this key is in the request context, check it; if it’s not there, let this condition be true.” This allows the necessary API calls for a user to set up their MFA device for the first time without already having MFA. Without IfExists, they’d be completely locked out before they even started. It’s these little details that separate a working policy from a support nightmare.
The final word: Set a strong password policy because it’s easy. Enforce MFA on every human user because it’s essential. And use conditional policies to protect your crown jewels. Do this, and your brilliant IAM structure won’t be undone by a stolen password.