Enforce MFA Access to the AWS Console
Tags: aws, security, devops, beginners
Published: 2021-11-16 12:26:17

## Introduction
One of the most important security concerns for entities using AWS is securing their AWS accounts. Evidently, managing an AWS account with 5 users may be somewhat a walk in the park. However, as the usage of the account scales, and the number of users increases, managing account becomes trivial. Several policies must be put in place in order to organize access between different stakeholders. 

One of the most common security features is to enable [Multi-Factor Authentication](https://en.wikipedia.org/wiki/Multi-factor_authentication) on the AWS account users.

In this tutorial, we are going to setup a process that forbids any AWS user from using any service without:

1. Setting up an MFA device.
2. Signing in using MFA. Any user that signs in without MFA must not be allowed to manage any resource on AWS.

## Steps
In this tutorial we will perform the following:

1. Create the required policy.
2. Create a test user.
3. Validate the setup.

## Setup
### Policy Creation

Navigate to **Policies** section, under the **IAM** service, and create the following policy:
```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowViewAccountInfo",
            "Effect": "Allow",
            "Action": [
                "iam:GetAccountPasswordPolicy",
                "iam:GetAccountSummary",       
                "iam:ListVirtualMFADevices"
            ],
            "Resource": "*"
        },       
        {
            "Sid": "AllowManageOwnPasswords",
            "Effect": "Allow",
            "Action": [
                "iam:ChangePassword",
                "iam:GetUser"
            ],
            "Resource": "arn:aws:iam::*:user/${aws:username}"
        },
        {
            "Sid": "AllowManageOwnAccessKeys",
            "Effect": "Allow",
            "Action": [
                "iam:CreateAccessKey",
                "iam:DeleteAccessKey",
                "iam:ListAccessKeys",
                "iam:UpdateAccessKey"
            ],
            "Resource": "arn:aws:iam::*:user/${aws:username}"
        },
        {
            "Sid": "AllowManageOwnSigningCertificates",
            "Effect": "Allow",
            "Action": [
                "iam:DeleteSigningCertificate",
                "iam:ListSigningCertificates",
                "iam:UpdateSigningCertificate",
                "iam:UploadSigningCertificate"
            ],
            "Resource": "arn:aws:iam::*:user/${aws:username}"
        },
        {
            "Sid": "AllowManageOwnSSHPublicKeys",
            "Effect": "Allow",
            "Action": [
                "iam:DeleteSSHPublicKey",
                "iam:GetSSHPublicKey",
                "iam:ListSSHPublicKeys",
                "iam:UpdateSSHPublicKey",
                "iam:UploadSSHPublicKey"
            ],
            "Resource": "arn:aws:iam::*:user/${aws:username}"
        },
        {
            "Sid": "AllowManageOwnGitCredentials",
            "Effect": "Allow",
            "Action": [
                "iam:CreateServiceSpecificCredential",
                "iam:DeleteServiceSpecificCredential",
                "iam:ListServiceSpecificCredentials",
                "iam:ResetServiceSpecificCredential",
                "iam:UpdateServiceSpecificCredential"
            ],
            "Resource": "arn:aws:iam::*:user/${aws:username}"
        },
        {
            "Sid": "AllowManageOwnVirtualMFADevice",
            "Effect": "Allow",
            "Action": [
                "iam:CreateVirtualMFADevice",
                "iam:DeleteVirtualMFADevice"
            ],
            "Resource": "arn:aws:iam::*:mfa/${aws:username}"
        },
        {
            "Sid": "AllowManageOwnUserMFA",
            "Effect": "Allow",
            "Action": [
                "iam:DeactivateMFADevice",
                "iam:EnableMFADevice",
                "iam:ListMFADevices",
                "iam:ResyncMFADevice"
            ],
            "Resource": "arn:aws:iam::*:user/${aws:username}"
        },
        {
            "Sid": "DenyAllExceptListedIfNoMFA",
            "Effect": "Deny",
            "NotAction": [
                "iam:CreateVirtualMFADevice",
                "iam:EnableMFADevice",
                "iam:GetUser",
                "iam:ListMFADevices",
                "iam:ListVirtualMFADevices",
                "iam:ResyncMFADevice",
                "sts:GetSessionToken",
                "iam:ChangePassword",
                "iam:GetUser"
            ],
            "Resource": "*",
            "Condition": {
                "BoolIfExists": {
                    "aws:MultiFactorAuthPresent": "false"
                }
            }
        }
    ]
}
```
The policy above allows a user to only perform certain actions related to their account such as changing the password, or setting an MFA device. Moreover, the policy denies every other action for the user, if signed in without an MFA device. This policy allows any user to login for the first time, and set their own MFA device.

Give the policy a name and finalize its creation.

### Test User Creation.
Navigate to **Users** section, under the **IAM** service, and add a new user with the following options:
- Name: testuser
- AWS Credential Type: autogenerated password that should be changed on first signed in for the AWS Management Console.
- Under the permissions section, navigate to "Attach existing policies directly", search for the name of the policy created previously, and add it to the user.
- Attach the **AmazonEC2FullAccess** policy as well, giving the user full access to the EC2 service.
- Leave the remaining options as defaults, and create the user.
- A password will be generated. Use this password to login to the console with the new user.

### MFA setup and Validation

In order to validate the setup, perform the following:

- Login to the AWS management console using the new testuser. For the first time, you will be able to login using only the password. Moreover, you will be asked to change the password.

- After successfully logging in, navigate to the EC2 instances console. You will be greeted with the following message "You are not authorized to perform this operation." forbidding you from listing any existing instances. Even though this user has full access to the EC2 service, managing EC2 resources is forbidden before signing in using MFA.

- To setup MFA, navigate to the dashboard of the **IAM** section. The dashboard will be filled with permission error messages.

- Click on **Add MFA** --> **Assign MFA Device** --> Virtual MFA device.

- Download an MFA software (Google, Microsoft, etc) on your phone, and complete the setup on AWS by scanning the QR code, and then copying 2 consecutive MFA Codes.

- Upon completion, you will receive the following message:
```
You have successfully assigned virtual MFA
This virtual MFA will be required during sign-in.
```

- Sign out, and sign back in. This time, you will be prompted to enter the code from the authentication device.

- After signing in, navigate again to the EC2 instances dashboard. The error message is now replaced by the list of EC2 instances present.

The end :)