Force an IAM User to use MFA authentication

Mariano Calandra
3 min readMar 12, 2018

If you are dealing with your personal AWS account, permissions are not a big concern. That single IAM user (you!) will have all necessary permissions, probably will have AdministratorAccess and the job is almost done. Probably, since you are a shrewd person, you have enabled the Multi Factor Authentication (MFA) so, along with username and password, you have to provide a six-digits random code.

But what if you had to manage an enterprise account with multiple IAM users? What tools do we have to force every user in the account to enable the MFA?

A real life scenario

Alice is responsible for her company’s AWS account and today she needs to create an IAM user for John Doe: her new colleague. John needs AWS Management Console access and PowerUser privileges. In itself, the creation of IAM user is really a simple task and Alice will need few minutes to create one.

New user screen.

She is savvy enough, so for security sake she had already set a Password policy so, during the first login, John needs to type a new password that meets the specific criteria, like a minimum length or the presence of numbers and special characters.

Note — when you check “User must crete a new passoword at next sign-in” AWS will automatically attach IAMUserChangePassword policy to the user.

Going better!

The above solution surely reduce the risk of weak passwords and since she is smart, she asks John to set Multi Factor Authentication. But…

How can Alice be sure that Joe activates MFA?

How can she easily apply these rules for each new colleague?

Using policy

A first important thing to notice is related to the PowerUserAccess and its lack of IAM related permissions. Due to this restriction, Joe can't activate MFA, even if he wants to. To solve the issue Alice needs to create a new custom policy that looks like this:

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowListUsers",
"Effect": "Allow",
"Action": [
"iam:ListUsers"
],
"Resource": "arn:aws:iam::*:user/"
},
{
"Sid": "AllowMFAHandling",
"Effect": "Allow",
"Action": [
"iam:CreateVirtualMFADevice",
"iam:DeleteVirtualMFADevice",
"iam:EnableMFADevice",
"iam:ListMFADevices",
"iam:ListVirtualMFADevices"
],
"Resource": [
"arn:aws:iam::*:mfa/*",
"arn:aws:iam::*:user/${aws:username}"
]
},
{
"Sid": "BlockEverythingUnlessSignedInWithMFA",
"Effect": "Deny",
"NotAction": [
"iam:ChangePassword",
"iam:CreateVirtualMFADevice",
"iam:DeleteVirtualMFADevice",
"iam:EnableMFADevice",
"iam:ListMFADevices",
"iam:ListUsers",
"iam:ListVirtualMFADevices"
],
"Resource": "*",
"Condition": {
"BoolIfExists": {
"aws:MultiFactorAuthPresent": "false"
}
}
}
]
}

This policy is quite simple. The statement BlockEverythingUnlessSignedInWithMFA deny almost every possible action if MFA is not present (this check is performed using Condition and Not in combo). By the way, some other actions needs to be performed when MFA is not yet active. For instance, John needs to change password as soon as he do sign-in, so Alice can't explicitly deny iam:ChangePassword, even if MFA is not yet present. Clearly, the same is for iam:CreateVirtualMFADevice, iam:EnableMFADevice and so on. The property NotAction is gold in situations like this.

The lack of an explicit deny doesn’t imply an implicit allow, so the statement AllowListUsers and AllowMFAHandling are necessary.

The only action that doesn’t have an explicit allow is iam:ChangePassword can you guess why? :)

Wrap everything up

At this point Alice can create a new IAM group (for instance PowerConsultants) attaching both PowerUserAccess and the policy just created. In this way as soon as a new collegue step into the office, she only needs to create a user and put him or her into that group.

References

--

--

Mariano Calandra

Mariano daily helps companies succeed using cloud and microservices. • AWS Authorized Instructor • AWS Community Builder • goto.calandra.me/support