Created
May 25, 2018 12:43
-
-
Save tongpu/69ac6fcdd7c48c54a8916df48934aeb6 to your computer and use it in GitHub Desktop.
Open the AWS console with an AWS role secured by `ExternalID`
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
#!/usr/bin/env python | |
import click | |
import configparser | |
import json | |
import os | |
import requests | |
import webbrowser | |
from boto.sts import STSConnection | |
@click.command() | |
@click.option( | |
'--profile', | |
default='default', | |
help='AWS profile to switch to') | |
@click.option( | |
'--destination', | |
default='https://console.aws.amazon.com/', | |
help='URL to redirect to after login') | |
@click.option( | |
'--federation-url', | |
default='https://signin.aws.amazon.com/federation', | |
help='Federation URL used for login' | |
) | |
def main(profile, destination, federation_url): | |
# Read AWS profile configuration from ~/.aws/config or AWS_CONFIG_FILE | |
# environment variable if set | |
aws_config = configparser.ConfigParser() | |
aws_config_file = os.getenv( | |
'AWS_CONFIG_FILE', | |
os.path.expanduser('~/.aws/config') | |
) | |
aws_config.read(aws_config_file) | |
aws_profile = aws_config['profile {}'.format(profile)] | |
# Connect to AWS STS and call AssumeRole to receive temporary security | |
# credentials. | |
sts_connection = STSConnection(profile_name=aws_profile['source_profile']) | |
assumed_role_object = sts_connection.assume_role( | |
role_arn = aws_profile['role_arn'], | |
role_session_name = 'AssumeRoleSession', | |
external_id = aws_profile['external_id'] | |
) | |
# Put temporary session credentials into a dict for the subsequent | |
# getSigninToken call | |
assumed_role_session_credentials = { | |
'sessionId': assumed_role_object.credentials.access_key, | |
'sessionKey': assumed_role_object.credentials.secret_key, | |
'sessionToken': assumed_role_object.credentials.session_token | |
} | |
# Make a request to the AWS federation endpoint to get a sign-in | |
# token, passing parameters in the query string. The call requires an | |
# Action parameter ('getSigninToken') and a Session parameter (the | |
# JSON string that contains the temporary credentials that have | |
# been URL-encoded). | |
signin_token_request_params = { | |
'Action': 'getSigninToken', | |
'Session': json.dumps(assumed_role_session_credentials) | |
} | |
r = requests.get(federation_url, params=signin_token_request_params) | |
# Get the SigninToken from the JSON return value from the federation | |
# endpoint | |
sign_in_token = r.json()['SigninToken'] | |
# Create the URL that will let users sign in to the console using the | |
# sign-in token. This URL must be used within 15 minutes of when the | |
# sign-in token was issued. | |
login_request_params = { | |
'Action': 'login', | |
'Issuer': '', | |
'Destination': destination, | |
'SigninToken': sign_in_token | |
} | |
browser_url = requests.Request( | |
'GET', | |
federation_url, | |
params=login_request_params | |
).prepare().url | |
# Use the default browser to sign in to the console using the | |
# generated URL. | |
webbrowser.open(browser_url) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment