Skip to content

Instantly share code, notes, and snippets.

@tongpu
Created May 25, 2018 12:43
Show Gist options
  • Save tongpu/69ac6fcdd7c48c54a8916df48934aeb6 to your computer and use it in GitHub Desktop.
Save tongpu/69ac6fcdd7c48c54a8916df48934aeb6 to your computer and use it in GitHub Desktop.
Open the AWS console with an AWS role secured by `ExternalID`
#!/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