Requiring AWS IAM Users to Enable MFA

When AWS announced Lambda at the 2014 re:Invent, my immediate thought was “Cool, you can now program the cloud itself”. Since then, everyone has jumped on the “serverless” bandwagon for building apps. After this year’s re:Invent I’m inspired to get back to using Lambda to program the cloud.

One of the sessions I attended was on Security Automation. I’ll have more to say on that later. However, it gave me the idea for a setup that would require users to have MFA enabled, or otherwise be blocked from doing anything with their IAM User in the AWS account.

Thus over the holidays I published RequireMFA which you can get here:

It consists of a Lambda and a CloudFormation Template which will create:

  • an IAM Group (DenyUntilMFAEnabledGroup) with a policy that denies everything but the actions necessary to change your password and add and enable your MFA
  • a CloudWatch Event looking for IAM API calls of EnableMFADevice, CreateLoginProfile or DeactivateMFADevice
  • a Lambda Function which is called by the CloudWatch Event and will add or remove the user from the DenyUntilMFAEnabled Group.
  • The necessary IAM roles for the Lambda and invocation perms for the Event.

As soon as a password is added to an IAM user (the CreateLoginProfile API call) the Lambda will add the IAM User to the DenyUntilMFAEnabled Group. Because the DenyUntilMFAEnabledGroup uses explicit Deny statements, the user could be an Administrator and they’re still prohibited from doing anything. The user is only able to:

  • Login via the console
  • Change their password
  • Navigate to the IAM Page
  • Find themselves in the user list
  • Click on Security Credentials
  • Click on the MFA icon and create and enable their device

The Event will detect the IAM API call EnableMFADevice and remove them from the DenyUntilMFAEnabled Group, thus granting them whatever privileges were assigned when the user was created.

If the MFA Device is later disabled, the CloudWatch Event will trigger again and drop the user back into the DenyUntilMFAEnabled Group.

The one disappointing aspect of this setup is that the blackhole’d user can still view a list of all the IAM users. I was unable to figure out how to deny the ListUsers action and still allow the user to navigate to themselves on the IAM page.