Using AWS CLI Securely with IAM Roles and MFA
Tags: aws, devops, security, cli
Published: 2023-06-13 16:32:14


## Summary

This quick and easy guide provides step-by-step instructions on securely using **AWS CLI** with **IAM roles** and **Multi-Factor Authentication (MFA)**. Learn how to set up AWS CLI securely by assuming IAM roles and enabling **MFA**.

---

## Introduction

As **AWS developers**, it's crucial to prioritize security when accessing **AWS resources**. Instead of relying on permanent access keys, which pose risks like exposure and misuse, AWS offers a more secure approach using IAM roles. **IAM roles** provide fine-grained permissions and generate temporary security credentials, eliminating the need for permanent access keys. Additionally, enabling **MFA** adds an extra layer of protection to **AWS CLI usage**.

---

## Prerequisites

Before getting started, make sure you have the following prerequisites:

- An active **AWS account** and access to the AWS Management Console.
- Basic understanding of the command line interface (CLI) or shell scripting.
- A **virtual MFA** device (e.g., Google Authenticator) set up on your smartphone.

---

## Part I - AWS Console Setup


### Step 1: Creating an IAM User with Programmatic Access


**1**. Open the **AWS Management Console** and sign in with your credentials.
**2**. Search for **IAM** in the search bar and open the IAM console.
**3**. In the left navigation pane, click on **`Users`** and then the **`Add user`** button.
**4**. Provide a name for the user and select **`Programmatic access`** under **`Access type`**.
**5**. Choose an existing **`IAM group`** or attach policies directly to the user for permissions.
**6**. Review the user details and add tags if necessary.
**7**. Create the user and securely download the access key and secret access key.

![IAM User](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d1dn2hda25zw1rprslmc.png)

> Note: If you have an existing user that you want to provide programmatic access, just select the user and go to the "Security Credentials" tab and create a new access key.

![Access Key](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gnk1pj8983zj0p8zpfnu.png)

---

### Step 2: Setting Up MFA on AWS Console

**1**. Go to the IAM service in the AWS Management Console and select your IAM user.
**2**. In the "Security credentials" tab, click on "Manage" in the "Multi-factor authentication (MFA)" section.
**3**. Choose "Virtual MFA device" and follow the on-screen instructions to set up your MFA device.
**4**. Use the authenticator app to scan the QR code or enter the secret key to link the virtual MFA device.

![MFA Device](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/51htu5sz9uo26zfwn1xd.png)

---

### Step 3: Creating an IAM Role with MFA Condition
**1**. Go to the IAM service in the AWS Management Console and click on "Roles".
**2**. Click on "Create role" and select the appropriate service or use case.
**3**. Attach the necessary policies to the role and skip the permissions boundary section.
**4**. Scroll down to the "IAM role trust relationship" section and click on "Edit trust relationship".
**5**. Replace the existing trust policy with the provided JSON policy, replacing `<YOUR_ACCOUNT_ID>` with your AWS account ID.
```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect":

 "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::<YOUR_ACCOUNT_ID>:root"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "Bool": {
          "aws:MultiFactorAuthPresent": "true"
        }
      }
    }
  ]
}
```
**6**. Save the changes to update the trust relationship.

---

## Part II - Command Line Setup

### Step 1: Installing AWS CLI

**1**. Check if **Python 3 (version 3.6 or later)** is installed by running `python3 --version`.
**2**. Install AWS CLI using `pip` with the command: `pip install awscli --upgrade --user`.
**3**. Verify the installation by running `aws --version`.

```bash
aws --version
aws-cli/2.11.26 Python/3.11.4 Darwin/22.5.0 source/x86_64 prompt/off
```

---

### Step 2: Initial Configuration with IAM User Credentials
**1**. Obtain the access key ID and secret access key for your IAM user from the AWS Management Console.
**2**. Configure AWS CLI with your IAM user credentials by running `aws configure`.
**3**.  Enter the access key ID, secret access key, default region, and output format as prompted.

```bash
$ aws configure
AWS Access Key ID [xxx]:
...
```

   This command prompts you to enter the access key ID, secret access key, default region, and output format. Provide the IAM user credentials and other details as prompted.

   - The access key ID and secret access key are the credentials obtained for your IAM user.
   - The default region is the AWS region where you want to operate. For example, `us-west-2` for US West (Oregon) region.
   - The output format specifies how AWS CLI should display the command output. You can choose `json`, `text`, or `table`.


**4**. **Verify Initial Configuration:** To verify that AWS CLI is configured correctly with your IAM user credentials, run the following command:

   ```bash
   $ aws sts get-caller-identity --no-cli-pager
   ```

> Note: The `aws sts get-caller-identity --no-cli-pager` command is useful in the context of assuming IAM roles, as it allows you to verify the identity of the user or role associated with the temporary credentials.

> This command will return information about the AWS account ID, IAM entity ARN, and other details associated with the current credentials.

---

### Step 3: Assume Roles with MFA Configuration

In this step, we'll configure AWS CLI to assume roles using the named profiles specified in the configuration file. Follow the instructions below:

**1**. **Add Assume Role with MFA Configuration:** Add the following configuration block to the file located at `~/.aws/config` (Linux/Mac) or `%USERPROFILE%\.aws\config` (Windows) , specifying the details for the IAM role you want to assume and mfa parameters:

   ```bash
   [default]
   region = us-west-2

   [profile mfa]
   region = us-west-2
   output = json
   role_arn = arn:aws:iam::123456789012:role/MyRole
   source_profile = default
   mfa_serial = arn:aws:iam::123456789012:mfa/MyMFADevice
   ```

   In this example:

   - `[default]` represents the default profile used for general AWS CLI operations.
   - `[profile mfa]` represents a named profile that will be used to assume the IAM role with MFA.
   - `region` specifies the AWS region you want to use.
   - `output` specifies the output format for AWS CLI commands.
   - `role_arn` is the ARN of the IAM role you want to assume. **(This is role created on the 1st part of this article)**
   - `source_profile` is the profile name used to retrieve the initial temporary credentials (usually the default profile).
   - `mfa_serial` is the ARN of the MFA device associated with your IAM user.

> Note that the role here is the one we created with the trust policy with **MFA condition**.

The mfa_serial can be obtained when selecting the **MFA serial** created in the 1st part of this article, under the user, **security credentials** tab.

![MFA ARN](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0zajvzrmxg5bwrotiyta.png)

**2**. After configuring the AWS CLI, run the following command to assume the IAM role with MFA:

```bash
$ aws sts assume-role --profile mfa --role-session-name MySessionName --duration-seconds 3600
```

   Replace `mfa` with the profile name you specified in the AWS CLI configuration file. `MySessionName` can be any descriptive name for your session. `3600` represents the duration for which the temporary security credentials will be valid (in this example, 1 hour).

   This command generates temporary security credentials that you can use for AWS operations.

**3**. Run the following command to retrieve the caller identity after assuming the IAM role:

```bash
$ aws --profile devadmin sts get-caller-identity --no-cli-pager                                                                   Enter MFA code for arn:aws:iam::XXXXXX:mfa/user1:
```

---

## Conclusion

Setting up **AWS CLI** to assume **IAM roles** with **MFA as a condition** enhances the security and control of your AWS environment. By following the steps outlined in this article, **DevOps** and experienced **AWS developers** can securely configure AWS CLI for their day-to-day operations, ensuring temporary credentials, an additional authentication factor, and an MFA condition are used.

Remember to regularly rotate **IAM roles**, **update policies**, and review **user access permissions** to maintain a strong security posture within your AWS infrastructure.

---