Telling people to turn on MFA is a request. A policy makes it a rule.
{
"Effect": "Deny",
"NotAction": ["iam:ListMFADevices", "iam:CreateVirtualMFADevice", "iam:EnableMFADevice", "iam:ChangePassword", "iam:GetUser", "sts:GetSessionToken"],
"Resource": "*",
"Condition": { "BoolIfExists": { "aws:MultiFactorAuthPresent": "false" } }
}Two new pieces:
NotActionturns the list around: the statement covers every action except the ones listed. The exceptions are what a person needs to set up MFA.BoolIfExistsonaws:MultiFactorAuthPresentwithfalsematches when the person signed in without MFA, and also when the key is missing from the request, which is what happens with a long-term access key.
Because a Deny wins over every Allow, the person keeps nothing until they have MFA. With MFA, the condition is false, the Deny is skipped, and the group's other policies decide as before.
Who it is for
This policy is for people who sign in to the web console, where MFA is part of signing in. A request signed with a long-term access key carries no MFA at all, so the condition matches and the Deny applies: every CLI command a member of the group runs with their key is denied. Put it on the group of console users, not on programs, and expect anyone in that group who uses the CLI to need temporary credentials that include MFA.
Putting it in place
There is no new command. Store the document with create-policy, then attach it with attach-group-policy to the group the console users belong to. The simulator checks it before anyone is locked out:
aws iam simulate-principal-policy --policy-source-arn arn:aws:iam::123456789012:user/sam --action-names s3:ListAllMyBuckets --context-entries ContextKeyName=aws:MultiFactorAuthPresent,ContextKeyValues=false,ContextKeyType=boolean