IAM Policy to Deny Actions Without MFA
Create an IAM policy that denies all actions unless multi-factor authentication (MFA) is present. A security best practice for privileged accounts.
Detailed Explanation
MFA Enforcement Policy
Requiring multi-factor authentication (MFA) for sensitive operations adds a strong layer of security. This policy denies all actions unless the request was authenticated with MFA.
Policy JSON
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyAllWithoutMFA",
"Effect": "Deny",
"NotAction": [
"iam:CreateVirtualMFADevice",
"iam:EnableMFADevice",
"iam:GetUser",
"iam:ListMFADevices",
"iam:ListVirtualMFADevices",
"iam:ResyncMFADevice",
"sts:GetSessionToken"
],
"Resource": "*",
"Condition": {
"BoolIfExists": {
"aws:MultiFactorAuthPresent": "false"
}
}
}
]
}
NotAction (Not "Action")
This policy uses NotAction instead of Action. This means "deny everything EXCEPT the listed actions when MFA is not present." The excepted actions allow the user to set up and manage their MFA device — without this exception, a user without MFA could never enable it.
BoolIfExists
BoolIfExists is used instead of Bool because:
aws:MultiFactorAuthPresentis not present at all in requests using long-term access keys (not just "false").BoolIfExistsevaluates to true when the key exists and is "false", AND when the key does not exist at all.Boolalone would not catch long-term access key requests.
How to Use This Policy
Attach this policy alongside the user's permission policies. The Deny always wins over any Allow, so even if other policies grant broad access, those permissions only work after MFA authentication.
Workflow for Users
- Authenticate with username/password
- Call
sts:GetSessionTokenwith MFA code - Use the returned temporary credentials for all subsequent API calls
Use Case
Enforcing MFA for admin accounts, privileged users, and any principals with access to production resources or sensitive data. A common requirement for SOC 2, PCI DSS, and security-focused organizations.