Last active
April 22, 2018 11:27
-
-
Save lrvick/60d31dac10395ac18dccd83e8b99f7b0 to your computer and use it in GitHub Desktop.
Use AWS CLI transparently with TOTP and IAM accounts.
This file contains hidden or 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
[default] | |
region = us-west-2 | |
output = json | |
[profile example] | |
role_session_name = example | |
mfa_serial = arn:aws:iam::567582265868:mfa/example | |
credential_process = bash -c "~/.aws/aws-mfa.sh example path/to/credentials.gpg" |
This file contains hidden or 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
#!/bin/bash | |
set -e | |
function get_mfa_token { | |
mfa_token=$(echo "GETPIN" | pinentry-gtk-2 | grep -o "[0-9]\\+"); | |
[[ "$mfa_token" =~ ^[0-9]{6}$ ]] || \ | |
{ ( >&2 echo "TOTP token must be 6 digits" ); exit 1; } | |
echo "$mfa_token" | |
} | |
function get_session { | |
creds="$1" | |
profile="$2" | |
mfa_serial=$(aws --profile "$profile" configure get mfa_serial) | |
[[ "$mfa_serial" =~ ^arn:aws:iam::[0-9]{12}:mfa/[a-z]+$ ]] || \ | |
{ (>&2 echo "mfa_serial invalid in ~/.aws/config" ); exit 1; } | |
mfa_token=$(get_mfa_token) || exit 1; | |
AWS_ACCESS_KEY_ID=$(echo "$creds" | jq -r '.AccessKeyId') | |
AWS_SECRET_ACCESS_KEY=$(echo "$creds" | jq -r '.SecretAccessKey') | |
export AWS_ACCESS_KEY_ID | |
export AWS_SECRET_ACCESS_KEY | |
response=$( | |
aws sts get-session-token \ | |
--serial-number "$mfa_serial" \ | |
--token-code "$mfa_token" | |
) | |
echo "$response" | jq -r '.[] + { Version: 1 }' | |
} | |
function cache_valid { | |
cache_file=$1 | |
[ -e "$cache_file" ] || return 1 | |
exp=$( jq -r '.Expiration' < "$cache_file" | xargs date +%s -d ) | |
now=$( date +%s ) | |
[[ "$exp" > "$now" ]] || return 1 | |
} | |
function cache_update { | |
session="$1" | |
profile="${2}-role" | |
cache_file="$3" | |
key_id=$( echo "$session" | jq -r '.AccessKeyId') | |
key_secret=$( echo "$session" | jq -r '.SecretAccessKey' ) | |
session_token=$( echo "$session" | jq -r '.SessionToken' ) | |
aws --profile "$profile" configure set aws_access_key_id "$key_id" | |
aws --profile "$profile" configure set aws_secret_access_key "$key_secret" | |
aws --profile "$profile" configure set aws_session_token "$session_token" | |
echo "$session" > "$cache_file" | |
} | |
function get_creds { | |
creds_file="$1" | |
gpg -d "$creds_file" 2>/dev/null | |
} | |
profile=$1 | |
creds_file=$2; [ -e "$2" ] || { echo "File does not exist: $2"; exit 1; } | |
cache_file="$HOME/.aws/cache/${profile}-creds.json" | |
if cache_valid "$cache_file"; then | |
cat "$cache_file" | |
else | |
creds=$(get_creds "$creds_file"); | |
session=$(get_session "$creds" "$profile") | |
cache_update "$session" "$profile" "$cache_file" | |
echo "$session" | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment