This is a tutorial on how to setup your command line access to AWS while using multi-factor authentication.

1Password Configuration

brew install --cask 1password 1password-cli
brew install --formula awscli

Create a new 1Password login for AWS

Inside of it needs the following entries.

Name Data
username Your AWS username
one-time password The rotating TOTP code
aws_access_key_id AWS access key
aws_secret_access_key AWS secret key

AWS Documentation on MFA setup

Configuring 1Password CLI

Configuration Settings on OSX

  1. Open and unlock the app.
  2. Click your account or collection at the top of the sidebar.
  3. Navigate to Settings > Developer.
  4. Select “Connect with 1Password CLI”.

1Password Documentation

Code

Create a folder to store the local executable file

mkdir ~/bin

Store the following bash script in the new directory.

I recommend calling it something simple such as mfa.

vim ~/bin/mfa

Update the following variables

Variables Value Description
ITEM_NAME AWS The name of the item you stored the aws credentials in
VAULT_NAME Private Name of the 1Password vault
REGION_VAR us-west-2 Default region
PROF_NAME main_mfa What you want to call the new profile
#! /bin/bash

set -o pipefail
set -o nounset
set -o errexit

ITEM_NAME="AWS"
VAULT_NAME="Private"

REGION_VAR="us-west-2"
PROF_NAME="main_mfa"

if [[ "${DEBUG:-0}" != "0" ]]; then
  set -x
fi

DEFAULT="\e[39m"
BLUE="\e[34m"

error_code=0

aws sts get-caller-identity --profile ${PROF_NAME} &> /dev/null || error_code=$?

if [ $error_code -eq 0 ]; then
  exit
fi

_1PASSWORD=$(op item get --format json ${ITEM_NAME} --vault ${VAULT_NAME} --fields label=username,aws_access_key_id,aws_secret_access_key)

USERNAME=$(echo ${_1PASSWORD} | jq -r '.[] | select(.label=="username") | .value ')

export AWS_ACCESS_KEY_ID=$(echo ${_1PASSWORD} | jq -r '.[] | select(.label=="aws_access_key_id") | .value ')
export AWS_SECRET_ACCESS_KEY=$(echo ${_1PASSWORD} | jq -r '.[] | select(.label=="aws_secret_access_key") | .value ')

ACCOUNT_NUMBER=$(aws sts get-caller-identity | jq -r .Account)

# Get the mfa code
OTP_CODE=$(op item get ${ITEM_NAME} --vault ${VAULT_NAME} --otp)

# Call aws with mfa and retrieve the information to create the mfa varified account
eval `aws sts get-session-token --serial-number arn:aws:iam::${ACCOUNT_NUMBER}:mfa/${USERNAME} --token-code ${OTP_CODE} | awk -F\" '/AccessKeyId/ {print "_AWS_ACCESS_KEY_ID="$4} /SecretAccessKey/ {print "_AWS_SECRET_ACCESS_KEY="$4} /SessionToken/ {print "_AWS_SESSION_TOKEN="$4}'`

printf "${BLUE}Setting credentials in aws profile${DEFAULT}\n"

# Configure the profile
aws configure set region ${REGION_VAR} --profile $PROF_NAME
aws configure set aws_access_key_id $_AWS_ACCESS_KEY_ID --profile $PROF_NAME
aws configure set aws_secret_access_key $_AWS_SECRET_ACCESS_KEY --profile $PROF_NAME
aws configure set aws_session_token $_AWS_SESSION_TOKEN --profile $PROF_NAME

Add the ~/bin directory into your path.

This can be done by running the following command to put it config file

echo 'export PATH=$HOME/bin/:$PATH' >> ~/.zshrc

Usage

From your terminal run the file you put in your ~/bin directory.

mfa

1Password will prompt for a password / biometrics to pull the credentials.