AWS MFA Authentication Helper
The helper script below assumes the following configuration:
- MFA key is stored on Yubikey.
- Key name is set appropriately to match Yubikey.
(line 11)
- AWS IAM MFA ARN is set appropriately.
(line 17)
How it works...
Once authenticated, the script adds a new entry to the bottom of ~/.aws/credentials
labeled [cli]
; however, session variables are also assigned. As long as you remain in the same shell session, you will not have to pass --profile cli
with each command.
Additional terminal windows is a new session and can't use the previously set local variables, so to utilize the authentication performed earlier, pass --profile cli
with each command to utilize the existing valid authentication. Example: aws s3 ls --profile cli
Performing a second authentication in a different window will overwrite the previous authentication's token and invalidate that session.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59 | alias awslogin="awsToken "
awsToken() {
ykTest=$(ykman list)
if [ -z "$ykTest" ]; then
printf "${color_yellow_italic}YubiKey not detected.${color_nocolor}\n"
printf "Insert key and try again.\n"
return 1
fi
printf "${cyanarrow}${color_cyan2} YubiKey detected...${color_nocolor}\n"
ykOathValue="AWS [Prod]:name@example.com" # (1)
unset AWS_SESSION_TOKEN;
unset AWS_SECRET_ACCESS_KEY;
unset AWS_ACCESS_KEY_ID;
unset PROFTXT;
unset AWSUME_PROFILE;
MFA="arn:aws:iam::123456789876:mfa/name@example.com" # (2)
MFACODE=$(ykman oath accounts code -s "$ykOathValue")
if [ $? -eq 1 ]; then
printf "${color_yellow_italic}Correct OATH token not found on YubiKey!${color_nocolor}\n"
return 1
fi
AWSCREDS=`aws sts get-session-token --serial-number $MFA --token-code $MFACODE`;
ACCESS_KEY=`echo $AWSCREDS | jq .Credentials.AccessKeyId`
SECRET_KEY=`echo $AWSCREDS | jq .Credentials.SecretAccessKey`
SESSION_TOKEN=`echo $AWSCREDS | jq .Credentials.SessionToken`
export AWS_ACCESS_KEY_ID=`echo $ACCESS_KEY | sed -e 's/^"//' -e 's/"$//'`
export AWS_SECRET_ACCESS_KEY=`echo $SECRET_KEY | sed -e 's/^"//' -e 's/"$//'`
export AWS_SESSION_TOKEN=`echo $SESSION_TOKEN | sed -e 's/^"//' -e 's/"$//'`
export PROFTXT="XYZ AWS" # (3)
export AWSUME_PROFILE="prod" # (4)
echo "$(awk '/cli/{n=4}; n {n--; next}; 1' $HOME/.aws/credentials)" > $HOME/.aws/credentials
echo "" >> $HOME/.aws/credentials
echo "[cli]" >> $HOME/.aws/credentials
TMP1=$(echo "aws_access_key_id = $ACCESS_KEY" | tr -d \")
echo $TMP1 >> $HOME/.aws/credentials
TMP2=$(echo "aws_secret_access_key = $SECRET_KEY" | tr -d \")
echo $TMP2 >> $HOME/.aws/credentials
TMP3=$(echo "aws_session_token = $SESSION_TOKEN" | tr -d \")
echo $TMP3 >> $HOME/.aws/credentials
echo -e "\n\033[7;33""m NOTICE - NOTICE - NOTICE - NOTICE - NOTICE \033[0m"
echo -e "\033[5;33""m ==> -> DLRDMV AWS ACCOUNT ACTIVE <- <== \033[0m"
echo " "
export AWS_PAGER='' && aws sts get-caller-identity --output yaml && export AWS_PAGER='less'
}
# Quickly identify which profile you're authenticated against.
awsprofile() {
if [ -z "$PROFTXT" ]
then
echo "${color_yellow_italic}NO PROFILE IS ACTIVE${color_nocolor}"
else
echo -e "\033[7;33""m =========================================== \033[0m"
echo -e "\033[5;33""m ==> -> $PROFTXT ACCOUNT ACTIVE <- <== \033[0m"
echo -e "\033[7;33""m =========================================== \033[0m"
echo " "
export AWS_PAGER='' && aws sts get-caller-identity --output yaml && export AWS_PAGER='less'
fi
}
|
- Key value must match the name as defined when the MFA value was added to Yubikey.
- MFA ARN is located under the "Security credentials" tab of the IAM user.
- If you regularly access multiple AWS accounts,
PROFTXT
can be used to quickly identify which environment is currently active.
- p10k can read AWSUME_PROFILE (
/internal/p10k.zsh
) to show this value on the terminal prompt. It's useful for seeing at a glance which environment your command will apply to.
