Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enforce MFA for AWS console login but not for API calls

I am looking to enforce all IAM users(local and remote) to enable and activate their MFA devices. I want them all to enable MFA to do their respective tasks.

I am trying with the following policy

{
      "Effect": "Allow",
      "Action": "*",
      "Resource": "*",
      "Condition": {"Bool": {"aws:MultiFactorAuthPresent": "true"}}
}

However; this policy applies irrespective of how you are accessing the services, through console or through APIs.

There is a lot of automation done by all users and their automation breaks as MFA authentication was not implied.

As a first step, we wish everybody to at least enables MFA for console login; but the same should not enforce them to use MFA for API calls used in automation.

Is this achievable through IAM policy?

Thanks

like image 709
user2131779 Avatar asked Jan 27 '15 18:01

user2131779


People also ask

How can I enforce MFA authentication for IAM users that use the AWS console?

To configure MFA device enforcement for your usersOpen the IAM Identity Center console . In the left navigation pane, choose Settings. On the Settings page, choose the Network & security tab, and then choose Configure.

Can API use MFA?

Multi-factor authentication (MFA) provides an additional layer of security for sensitive API calls, such as terminating Amazon EC2 instances or deleting important objects stored in an Amazon S3 bucket.

Does MFA affect AWS CLI?

Note: IAM users using the AWS CLI with long-term credentials are denied access and must use MFA to authenticate. Therefore, be sure to use an MFA token to authenticate your CLI session.


3 Answers

The trick is to reverse the check...rather than only allowing if aws:MultiFactorAuthPresent is true, deny if it's false.

Here's the doc on self-service MFA management: http://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_users-self-manage-mfa-and-creds.html

The full policy suggested in there is:

{     "Version": "2012-10-17",     "Statement":[         {             "Sid": "AllowAllUsersToListAccounts",             "Effect": "Allow",             "Action":[                 "iam:ListAccountAliases",                 "iam:ListUsers",                 "iam:GetAccountSummary"             ],             "Resource": "*"         },         {             "Sid": "AllowIndividualUserToSeeAndManageTheirOwnAccountInformation",             "Effect": "Allow",             "Action":[                 "iam:ChangePassword",                 "iam:CreateAccessKey",                 "iam:CreateLoginProfile",                 "iam:DeleteAccessKey",                 "iam:DeleteLoginProfile",                 "iam:GetAccountPasswordPolicy",                 "iam:GetLoginProfile",                 "iam:ListAccessKeys",                 "iam:UpdateAccessKey",                 "iam:UpdateLoginProfile",                 "iam:ListSigningCertificates",                 "iam:DeleteSigningCertificate",                 "iam:UpdateSigningCertificate",                 "iam:UploadSigningCertificate",                 "iam:ListSSHPublicKeys",                 "iam:GetSSHPublicKey",                 "iam:DeleteSSHPublicKey",                 "iam:UpdateSSHPublicKey",                 "iam:UploadSSHPublicKey"             ],             "Resource": "arn:aws:iam::accountid:user/${aws:username}"         },         {             "Sid": "AllowIndividualUserToListTheirOwnMFA",             "Effect": "Allow",             "Action":[                 "iam:ListVirtualMFADevices",                 "iam:ListMFADevices"             ],             "Resource":[                 "arn:aws:iam::accountid:mfa/*",                 "arn:aws:iam::accountid:user/${aws:username}"             ]         },         {             "Sid": "AllowIndividualUserToManageTheirOwnMFA",             "Effect": "Allow",             "Action":[                 "iam:CreateVirtualMFADevice",                 "iam:DeactivateMFADevice",                 "iam:DeleteVirtualMFADevice",                 "iam:RequestSmsMfaRegistration",                 "iam:FinalizeSmsMfaRegistration",                 "iam:EnableMFADevice",                 "iam:ResyncMFADevice"             ],             "Resource":[                 "arn:aws:iam::accountid:mfa/${aws:username}",                 "arn:aws:iam::accountid:user/${aws:username}"             ]         },         {             "Sid": "BlockAnyAccessOtherThanAboveUnlessSignedInWithMFA",             "Effect": "Deny",             "NotAction": "iam:*",             "Resource": "*",             "Condition":{                 "BoolIfExists":{ "aws:MultiFactorAuthPresent": "false"}             }         }     ] } 

The most important part is the last statement, which does the deny. If you change it to this:

{     "Sid": "BlockAnyAccessOtherThanAboveUnlessSignedInWithMFA",     "Effect": "Deny",     "NotAction": "iam:*",     "Resource": "*",     "Condition":{         "Bool":{ "aws:MultiFactorAuthPresent": "false"}     } } 

(BoolIfExists changed to Bool) it will allow IAM access keys to bypass the requirement of MFA, while still requiring you to use MFA when logging in through the AWS Console. (Note: this doesn't work for all APIs; some, such as ECR, always supply the "MultiFactorAuthPresent" property, which breaks this work-around)

Be careful if you decide to use that full policy from the docs. Note that it allows a user to create access keys and change their password, and the deny clause only blocks non-IAM actions...this means that, if MFA gets disabled on an account, a user's password could be changed or new access keys could be provisioned without an MFA check, and if you've made the Bool change, those new access keys would be able to access anything that the user has permissions for, without MFA. I.E., all of the security vulnerabilities of unsecured keys, with some potential for account hijacking on top.

I would suggest using a policy similar to this instead:

Note: This policy should not be used verbatim, due to security issues mentioned in the comments

{     "Version": "2012-10-17",     "Statement": [         {             "Sid": "AllowAllUsersToListAccounts",             "Effect": "Allow",             "Action": [                 "iam:ListAccountAliases",                 "iam:ListUsers"             ],             "Resource": [                 "arn:aws:iam::accountid:user/*"             ]         },         {             "Sid": "AllowIndividualUserToSeeTheirAccountInformation",             "Effect": "Allow",             "Action": [                 "iam:GetAccountPasswordPolicy",                 "iam:GetAccountSummary",                 "iam:GetLoginProfile"             ],             "Resource": [                 "arn:aws:iam::accountid:user/${aws:username}"             ]         },         {             "Sid": "AllowIndividualUserToListTheirMFA",             "Effect": "Allow",             "Action": [                 "iam:ListVirtualMFADevices",                 "iam:ListMFADevices"             ],             "Resource": [                 "arn:aws:iam::accountid:mfa/*",                 "arn:aws:iam::accountid:user/${aws:username}"             ]         },         {             "Sid": "AllowIndividualUserToManageThierMFA",             "Effect": "Allow",             "Action": [                 "iam:CreateVirtualMFADevice",                 "iam:DeactivateMFADevice",                 "iam:DeleteVirtualMFADevice",                 "iam:EnableMFADevice",                 "iam:ResyncMFADevice"             ],             "Resource": [                 "arn:aws:iam::accountid:mfa/${aws:username}",                 "arn:aws:iam::accountid:user/${aws:username}"             ]         },         {             "Sid": "DoNotAllowAnythingOtherThanAboveUnlessMFAd",             "Effect": "Deny",             "NotAction": "iam:*",             "Resource": "*",             "Condition": {                 "Bool": {                     "aws:MultiFactorAuthPresent": "false"                 }             }         }     ] } 
like image 125
Josh Hancock Avatar answered Nov 08 '22 12:11

Josh Hancock


Create 2 IAM users for each person:

  1. one for AWS Console sign-in which enforces MFA, and
  2. one for API usage that doesn't have a password and that does not enforce MFA
like image 29
Matt Houser Avatar answered Nov 08 '22 13:11

Matt Houser


Posting for posterity. I tried using the methods posted by Josh Hancock but the api calls from enforced console MFA accounts fail for some AWS services like elastic filesystem and some s3 api calls. When raised a support ticket, the response from AWS was that, "There is a feature request for this precise issue as there is currently no reliable mechanism to enforce MFA for the console only. I have added your account to the list of requesting accounts for this feature request. Unfortunately, I do not have a reliable workaround other than enable MFA everywhere, or only apply the IAM MFA policy to users that are console only."

like image 30
rchaos Avatar answered Nov 08 '22 14:11

rchaos