Last active
December 22, 2023 02:29
-
-
Save sybeck2k/e893b753c7937d79b136097b3d7d7d6d to your computer and use it in GitHub Desktop.
A script to rapidly test IAM policies
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
#!/usr/bin/env bash | |
# MIT No Attribution | |
# Copyright 2023 Roberto Migli | |
# Permission is hereby granted, free of charge, to any person obtaining a copy of this | |
# software and associated documentation files (the "Software"), to deal in the Software | |
# without restriction, including without limitation the rights to use, copy, modify, | |
# merge, publish, distribute, sublicense, and/or sell copies of the Software, and to | |
# permit persons to whom the Software is furnished to do so. | |
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | |
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A | |
# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | |
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | |
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | |
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
# Use this script to rapidly test IAM policies with both CLI and Console access | |
# The script allows you to assume a role with AWS STS and gives you the possibility | |
# to edit your Session Policy. It also prints out a url that you can use to login to | |
# the console with this Session. The script opens a subshell with the environment variables | |
# already set for you to use the session | |
# | |
# Requires JQ, curl, Python, AWS CLI and Bash | |
usage() { | |
cat << EOF | |
Syntax: $0 -s <string> -r <string> [-e <string>] [-p <string>] [-hrvf] | |
options: | |
-r role-arn The role ARN that you want to assume | |
-s session-name The name of the session | |
-e region The region of the signin endpoint to use (default us-east-1) | |
-p session-policy-json The session-policy to use (default to inline editor) | |
-v Validate the session-policy with IAM Access Analyzer | |
-f Use GetFederationToken STS API | |
-h Print this Help. | |
EOF | |
} | |
region="us-east-1" | |
policy_file="" | |
no_shell=false | |
validate_policy=false | |
use_federation_token=false | |
while getopts nhvfr:s:p:e: flag | |
do | |
case "${flag}" in | |
r) role=${OPTARG};; | |
s) session_name=${OPTARG};; | |
e) region=${OPTARG};; | |
p) policy_file=${OPTARG};; | |
n) no_shell=true;; | |
f) use_federation_token=true;; | |
v) validate_policy=true;; | |
h) | |
usage | |
exit;; | |
*) exit 2;; | |
esac | |
done | |
if [ -z "${session_name}" ]; then | |
echo "Missing session name" | |
usage | |
exit 1; | |
fi | |
if [ $use_federation_token = false ] && [ -z "${role}" ]; then | |
echo "Missing role ARN to assume" | |
usage | |
exit 1; | |
fi | |
TMP_POLICY="$(mktemp -q)" | |
if [ -z "${policy_file}" ]; then | |
cat <<EOT >> $TMP_POLICY | |
{ | |
"Version":"2012-10-17", | |
"Statement":[ | |
{ | |
"Effect":"Allow", | |
"Action": "*", | |
"Resource": "*" | |
} | |
] | |
} | |
EOT | |
vim ${TMP_POLICY} | |
POLICY_CONTENT="$(cat $TMP_POLICY)" | |
until jq -e . >/dev/null 2>&1 <<<"$POLICY_CONTENT"; do | |
read -n 1 -p "Invalid JSON - (e)dit again or (a)bort? " cnt | |
case $cnt in | |
A|a) echo "\nAborting"; exit 0;; | |
esac | |
vim ${TMP_POLICY} | |
POLICY_CONTENT="$(cat $TMP_POLICY)" | |
done | |
else | |
fullpath_policy="$(realpath $policy_file)" | |
cat $fullpath_policy > $TMP_POLICY | |
fi | |
SESSION_POLICY_COMPACT=$(sed -e 's/^[[:blank:]]*//g' ${TMP_POLICY} | tr -d "\n\r") | |
SESSION_POLICY_PP=$(jq . -M <<< "$SESSION_POLICY_COMPACT") | |
if [ $validate_policy = true ]; then | |
AA_VALIDATE_OUTPUT=$(aws accessanalyzer validate-policy --policy-type IDENTITY_POLICY --policy-document "$SESSION_POLICY_PP" --output json ) | |
condition=$(echo "$AA_VALIDATE_OUTPUT" | jq '.findings | any(.[]; select(.findingType? == "ERRORS" or .findingType? == "SECURITY_WARNING"))') | |
echo -e "\x1B[32mIAM Access Analyzer Output\x1B[0m" | |
jq . <<< "$AA_VALIDATE_OUTPUT" | |
fi | |
echo -e "\x1B[32mSession Policy\x1B[0m" | |
jq . -C <<< "$SESSION_POLICY_COMPACT" | cat -n | |
if [ $use_federation_token = true ]; then | |
STS_OUTPUT=$(aws sts get-federation-token --name $session_name --policy "$SESSION_POLICY_COMPACT" --output json) | |
else | |
STS_OUTPUT=$(aws sts assume-role --role-arn $role --role-session-name $session_name --policy "$SESSION_POLICY_COMPACT" --output json) | |
fi | |
if [ ! $? -eq 0 ]; then | |
echo "Error when calling sts API" | |
exit 3 | |
fi | |
signin_region_domain="signin.aws.amazon.com" | |
console_region_domain="console.aws.amazon.com" | |
if [ "$region" != "us-east-1" ]; then | |
signin_region_domain="$region.signin.aws.amazon.com" | |
console_region_domain="$region.console.aws.amazon.com" | |
fi | |
AWS_ACCESS_KEY_ID=$(jq -r '.Credentials.AccessKeyId' <<< "${STS_OUTPUT}") | |
AWS_SECRET_ACCESS_KEY=$(jq -r '.Credentials.SecretAccessKey' <<< "${STS_OUTPUT}") | |
AWS_SESSION_TOKEN=$(jq -r '.Credentials.SessionToken' <<< "${STS_OUTPUT}") | |
TEMP_CREDS=$(jq -c '{sessionId: .Credentials.AccessKeyId, sessionKey: .Credentials.SecretAccessKey, sessionToken: .Credentials.SessionToken}' <<< "$STS_OUTPUT") | |
URL_ENCODED_TEMP_CREDS=$(python3 -c "import urllib.parse, sys; print(urllib.parse.quote_plus(sys.argv[1]))" "$TEMP_CREDS") | |
SIGNIN_TOKEN=$(curl -s "https://$signin_region_domain/federation?Action=getSigninToken&Session=$URL_ENCODED_TEMP_CREDS" | jq -r '.SigninToken') | |
echo -e "\x1B[32mAWS Console Access\x1B[0m" | |
echo "https://$signin_region_domain/federation?Action=login&Issuer=https%3A%2F%2Fexample.com&Destination=https%3A%2F%2F$console_region_domain%2F&SigninToken=$SIGNIN_TOKEN" | |
if [ "$no_shell" = true ] ; then | |
echo "" | |
echo "AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}" | |
echo "AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}" | |
echo "AWS_SESSION_TOKEN=${AWS_SESSION_TOKEN}" | |
echo "" | |
exit | |
fi | |
export AWS_ACCESS_KEY_ID | |
export AWS_SECRET_ACCESS_KEY | |
export AWS_SESSION_TOKEN | |
bash --rcfile <(echo "PS1='$AWS_ACCESS_KEY_ID:$session_name AWS $ '") -i |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment