Created
March 7, 2018 11:05
-
-
Save defanator/9befe0d75486b4f3b081565998a7c08b to your computer and use it in GitHub Desktop.
Example of direnv .envrc configuration for working with awscli as MFA-enabled IAM user
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# Copyright (C) Andrei Belov ([email protected]) | |
# | |
# This is an example of direnv [1] .envrc file approaching the way | |
# of using awscli [2] with MFA-enabled accounts in a (more or less) | |
# secure manner. | |
# | |
# The following assumptions are expected: | |
# | |
# a) there should be two files, key.asc and skey.asc, containing | |
# AWS access key and secure access key, respectively, encrypted | |
# with GPG using a key specified in the DEFAULT_GPG_KEY | |
# environment variable; | |
# | |
# b) IAM user name equals local user name reported by whoami(1); | |
# | |
# c) IAM user has basic permissions to obtain general account details | |
# as well as personal settings like MFA devices. | |
# | |
# The policy outlined in the following document should work: | |
# https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_users-self-manage-mfa-and-creds.html | |
# | |
# Honored environment variables: | |
# | |
# - DEFAULT_GPG_KEY (mandatory, no default): GPG key which is being | |
# used to decrypt initial credentials from key.asc and skey.asc, | |
# as well as to encrypt IAM user session credentials in order to | |
# keep them in a temporary file; | |
# | |
# - AWS_SESSION_TOKEN_DURATION (default is 900): the duration, in seconds, | |
# that the credentials should remain valid. Acceptable durations | |
# for IAM user sessions range from 900 seconds (15 minutes) to 129600 | |
# seconds (36 hours). | |
# | |
# Also it's worth to increase DIRENV_WARN_TIMEOUT to something greater | |
# than the default (5s) in order to avoid unnecessary warnings. | |
# | |
# [1] https://direnv.net | |
# [2] https://github.com/aws/aws-cli | |
# | |
umask 077 | |
if [ -z "${DEFAULT_GPG_KEY}" ]; then | |
echo "Please set DEFAULT_GPG_KEY" >&2 | |
exit 1 | |
fi | |
if [ -z "${AWS_SESSION_TOKEN_DURATION}" ]; then | |
export AWS_SESSION_TOKEN_DURATION=900 | |
fi | |
export AWS_DEFAULT_REGION=us-east-1 | |
export AWS_ACCESS_KEY_ID=`cat key.asc | gpg2 -d -r ${DEFAULT_GPG_KEY} --no-tty 2>/dev/null` | |
export AWS_SECRET_ACCESS_KEY=`cat skey.asc | gpg2 -d -r ${DEFAULT_GPG_KEY} --no-tty 2>/dev/null` | |
HASMFA=1 | |
WHOAMI=`whoami` | |
MFASERIAL=`aws --output text iam list-mfa-devices --user-name ${WHOAMI} --query 'MFADevices[0].SerialNumber'` | |
if [ x"${MFASERIAL}" = x"None" ]; then | |
HASMFA=0 | |
fi | |
if [ ${HASMFA} -eq 1 ]; then | |
ACCOUNT=`aws --output text sts get-caller-identity --query 'Account'` | |
TMPSTATE=/tmp/${ACCOUNT}.asc | |
GETNEW=1 | |
if [ -e ${TMPSTATE} ]; then | |
TOKENAGE=$((`date +%s` - `stat -f '%m' ${TMPSTATE}`)) | |
if [ ${TOKENAGE} -lt ${AWS_SESSION_TOKEN_DURATION} ]; then | |
GETNEW=0 | |
fi | |
fi | |
if [ ${GETNEW} -eq 1 ]; then | |
ACCOUNTALIAS=`aws --output text iam list-account-aliases --query 'AccountAliases[0]'` | |
if [ x"${ACCOUNTALIAS}" = x"None" ]; then | |
echo -n "MFA code for ${WHOAMI}@${ACCOUNT}: " | |
else | |
echo -n "MFA code for ${WHOAMI}@${ACCOUNTALIAS}: " | |
fi | |
read TOKENCODE | |
STS=`aws --output text sts get-session-token --serial-number "${MFASERIAL}" --token-code ${TOKENCODE} --duration ${AWS_SESSION_TOKEN_DURATION}` | |
echo ${STS} | gpg2 -ae -r ${DEFAULT_GPG_KEY} >${TMPSTATE} | |
else | |
STS=`cat ${TMPSTATE} | gpg2 -d -r ${DEFAULT_GPG_KEY} --no-tty 2>/dev/null` | |
fi | |
export AWS_ACCESS_KEY_ID=`echo ${STS} | awk '{print $2}'` | |
export AWS_SECRET_ACCESS_KEY=`echo ${STS} | awk '{print $4}'` | |
export AWS_SESSION_TOKEN=`echo ${STS} | awk '{print $5}'` | |
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The proposed .envrc is supposed to be placed in a top-level directory of a structure like the following (${HOME}/aws/111122223333/.envrc): | |
$ tree -al ${HOME}/aws/111122223333/ | |
├── .envrc | |
├── eu-west-1 | |
│ └── .envrc | |
├── key.asc | |
├── skey.asc | |
├── us-east-1 | |
│ └── .envrc | |
├── us-west-1 | |
│ └── .envrc | |
└── us-west-2 | |
└── .envrc | |
In subdirectories, .envrc could be as simple as: | |
$ cat ${HOME}/aws/111122223333/us-west-1/.envrc | |
source_env .. | |
export AWS_DEFAULT_REGION=us-west-1 | |
$ cat ${HOME}/aws/111122223333/eu-west-1/.envrc | |
source_env .. | |
export AWS_DEFAULT_REGION=eu-west-1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment