AWS IAM force MFA but allows change password the first time

Viewed 1227

How do you force the use of MFA for AWS IAM users but allow them to change their password when they log in for the first time?

If you follow AWS Docs, and force MFA, new users cannot change password when they first get their accounts.

I know you can either force MFA or not and allow users to manage their own password and credentials. Also, AWS has a way to work around the issue but it's not recommended:

This example policy does not allow users to reset a password while signing in. New users and users with an expired password might try to do so. You can allow this by adding iam:ChangePassword to the statement DenyAllExceptListedIfNoMFA. However, IAM does not recommend this. Allowing users to change their password without MFA can be a security risk.

So what's the "recommended" way?

This question was also asked in AWS forum without a real answer.

1 Answers

The recommended path here is to use SSO / identity federation, but I've come up with a manual, one-policy solution that makes it easier to manage if you don't yet have SSO. There's still a risk with my solution, but it's limited in scope to only the initial account setup process. It involves manually tagging a new IAM user with a NewUser tag, and then manually untagging them after they've reset their password and configured MFA.

The following guidance assumes that you're using the recommended policy from AWS to allow MFA-authenticated IAM users to manage their own credentials on the My Security Credentials page.

Edit your MFA policy where your "Sid": "DenyAllExceptListedIfNoMFA" block is, and replace it with the following:

{
    "Sid": "DenyAllExceptListedIfNoMFAAndNewUser",
    "Effect": "Deny",
    "NotAction": [
        "iam:CreateVirtualMFADevice",
        "iam:EnableMFADevice",
        "iam:GetUser",
        "iam:ListMFADevices",
        "iam:ListVirtualMFADevices",
        "iam:ResyncMFADevice",
        "sts:GetSessionToken",
        "iam:ChangePassword"
    ],
    "Resource": "*",
    "Condition": {
        "BoolIfExists": {
            "aws:MultiFactorAuthPresent": "false"
        }
    }
},
{
    "Sid": "DenyAllExceptListedIfNoMFA",
    "Effect": "Deny",
    "NotAction": [
        "iam:CreateVirtualMFADevice",
        "iam:EnableMFADevice",
        "iam:GetUser",
        "iam:ListMFADevices",
        "iam:ListVirtualMFADevices",
        "iam:ResyncMFADevice",
        "sts:GetSessionToken"
    ],
    "Resource": "*",
    "Condition": {
        "BoolIfExists": {
            "aws:MultiFactorAuthPresent": "false"
        },
        "StringNotEqualsIfExists": {
            "iam:ResourceTag/NewUser": "true"
        }
    }
}

Create a new user and add a NewUser tag with the value set to true. AWS IAM console screenshot describing previous statement

Send the credentials to the new user. Once they've logged in for the first time, delete the NewUser tag from their IAM user resource.

You can see an example of my full policy here.

Related