Mastodon Mastodon - AWS - Forced MFA and the CLI
 logo
  • Home 
  • Tags 
  • Blog posts 
  1. Home
  2. Blog posts
  3. AWS - Forced MFA and the CLI

AWS - Forced MFA and the CLI

Posted on July 20, 2022  (Last modified on July 2, 2024) • 3 min read • 444 words
Aws   Cloud: Aws   Cli   Solved  
Aws   Cloud: Aws   Cli   Solved  
Share via
Link copied to clipboard

Let’s say you want to force every user to enable MFA for AWS IAM accounts. Sure, that is possible.

Now there’s just one problem: This does not work on the CLI. The credentials in $HOME/.aws/credentials are “static”, they never have a aws:MultiFactorAuthPresent flag attached.

That would mean that CLI users are either not forced to use MFA, or they just can’t use the CLI any more. Which would - for example - break terraform.

There’s a solution though. Just get a token using aws sts get-session-token --serial-number ... --token-code ....

To ease this process (cause it’s really annoying) I created this function, which you can add to your .bashrc or .zshrc (or equivalent shell startup script).

Enjoy.

# gat = (G)et (A)ws session(T)oken
gat() {
  local TOKEN_DURATION=28800 # 8h

  # save existing AWS_* env vars
  local APRO_BACKUP
  local AKID_BACKUP
  local ASAK_BACKUP
  local ASET_BACKUP
  APRO_BACKUP=$AWS_PROFILE
  AKID_BACKUP=$AWS_ACCESS_KEY_ID
  ASAK_BACKUP=$AWS_SECRET_ACCESS_KEY
  ASET_BACKUP=$AWS_SESSION_TOKEN

  # check if we already have a session token active
  if [ -n "$AWS_SESSION_TOKEN" ] ; then
    if [ "$1" != "-f" ] ; then
      echo "Seems we are already using a session token, use -f to override."
      return
    else
      echo "Session token found, but '-f' set; proceeding."
    fi
  fi

  echo -n "AWS profile to use (ENTER for none): "
  read AWS_PROFILE
  if [ -z "$AWS_PROFILE" ] ; then
    echo "Not using specific AWS profile."
    unset AWS_PROFILE
  else
    echo "Using AWS profile '$AWS_PROFILE'"
    export AWS_PROFILE
  fi

  echo -n "Enter MFA token value (ENTER to abort): "
  read MFA_TOKEN
  if [ -z "$MFA_TOKEN" ] ; then
    echo "Abort."
    return
  fi

  # clean env variables, but only if a session token is active
  if [ -n "$AWS_SESSION_TOKEN" ] ; then
    echo "Cleaning existing ENV vars (already have a session token)"
    unset AWS_SESSION_TOKEN
    unset AWS_ACCESS_KEY_ID
    unset AWS_SECRET_ACCESS_KEY
  fi

  echo -n "Getting MFA ARN ... "
  MFA_ARN=$(aws iam list-mfa-devices | jq -r '.MFADevices[0].SerialNumber')
  if [ "$?" != "0" ] ; then
    echo "ERROR: something failed getting the session token."
    export AWS_PROFILE=$APRO_BACKUP
    export AWS_ACCESS_KEY_ID=$AKID_BACKUP
    export AWS_SECRET_ACCESS_KEY=$ASAK_BACKUP
    export AWS_SESSION_TOKEN=$ASET_BACKUP
    return
  fi
  echo $MFA_ARN

  echo -n "Getting session token ... "
  SESSION_TOKEN_JSON=$(aws sts get-session-token --serial-number $MFA_ARN --token-code $MFA_TOKEN --duration-seconds $TOKEN_DURATION)
  if [ "$?" != "0" ] ; then
    echo "ERROR: something failed getting the session token."
    export AWS_PROFILE=$APRO_BACKUP
    export AWS_ACCESS_KEY_ID=$AKID_BACKUP
    export AWS_SECRET_ACCESS_KEY=$ASAK_BACKUP
    export AWS_SESSION_TOKEN=$ASET_BACKUP
    return
  else
    echo "done."
  fi

  echo "Setting env variables:"
  export AWS_ACCESS_KEY_ID=$(echo $SESSION_TOKEN_JSON | jq -r '.Credentials.AccessKeyId')
  echo "  * (set) AWS_ACCESS_KEY_ID"
  export AWS_SECRET_ACCESS_KEY=$(echo $SESSION_TOKEN_JSON | jq -r '.Credentials.SecretAccessKey')
  echo "  * (set) AWS_SECRET_ACCESS_KEY"
  export AWS_SESSION_TOKEN=$(echo $SESSION_TOKEN_JSON | jq -r '.Credentials.SessionToken')
  echo "  * (set) AWS_ACCESS_KEY_ID"
  # just to be sure
  unset AWS_PROFILE
  echo "  * (*un*set) AWS_PROFILE"
  echo "... done.\n\nYou should be all set now."
}

(Stripped down version available here)

 Fix tmux on Mac
Mac quick action - edit PDF documents 
In case you want to follow me

Here are some links. The further to the right, the less active.

           
(c) Axel Bock | Powered by Hinode.
Code copied to clipboard