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.

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.