From fc5219dfb0c254b7f98a2a2e314ed482d10ba216 Mon Sep 17 00:00:00 2001 From: Eric Pierce Date: Tue, 13 Jun 2023 14:53:38 -0700 Subject: [PATCH] Add the ability to force a particular AWS region --- README.md | 1 + gimme_aws_creds/main.py | 58 +++++++++-------------------------------- 2 files changed, 14 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index 20715a70..cb75a83f 100644 --- a/README.md +++ b/README.md @@ -311,6 +311,7 @@ A list of values of to change with environment variables are: - `OKTA_MFA_CODE` - corresponds to `--mfa-code` CLI option - `OKTA_PASSWORD` - provides password during authentication, can be used in CI - `OKTA_USERNAME` - corresponds to `okta_username` configuration and `--username` CLI option +- `AWS_STS_REGION` - force the use of the STS in a specific region (`us-east-1`, `eu-north-1`, etc.) Example: `GIMME_AWS_CREDS_CLIENT_ID='foobar' AWS_DEFAULT_DURATION=12345 gimme-aws-creds` diff --git a/gimme_aws_creds/main.py b/gimme_aws_creds/main.py index 1ec3417c..8a05774a 100644 --- a/gimme_aws_creds/main.py +++ b/gimme_aws_creds/main.py @@ -39,48 +39,8 @@ class GimmeAWSCreds(object): """ This is a CLI tool that gets temporary AWS credentials - from Okta based the available AWS Okta Apps and roles - assigned to the user. The user is able to select the app - and role from the CLI or specify them in a config file by - passing --action-configure to the CLI too. - gimme_aws_creds will either write the credentials to stdout - or ~/.aws/credentials depending on what was specified when - --action-configure was ran. - - Usage: - -h, --help show this help message and exit - --username USERNAME, -u USERNAME - The username to use when logging into Okta. The - username can also be set via the OKTA_USERNAME env - variable. If not provided you will be prompted to - enter a username. - --action-configure, -c If set, will prompt user for configuration parameters - and then exit. - --profile PROFILE, -p PROFILE - If set, the specified configuration profile will be - used instead of the default. - --resolve, -r If set, performs alias resolution. - --insecure, -k Allow connections to SSL sites without cert - verification. - --mfa-code MFA_CODE The MFA verification code to be used with SMS or TOTP - authentication methods. If not provided you will be - prompted to enter an MFA verification code. - --remember-device, -m - The MFA device will be remembered by Okta service for - a limited time, otherwise, you will be prompted for it - every time. - --version gimme-aws-creds version - - Config Options: - okta_org_url = Okta URL - gimme_creds_server = URL of the gimme-creds-server - client_id = OAuth Client id for the gimme-creds-server - okta_auth_server = Server ID for the OAuth authorization server used by gimme-creds-server - write_aws_creds = Option to write creds to ~/.aws/credentials - cred_profile = Use DEFAULT or Role-based name as the profile in ~/.aws/credentials - aws_appname = (optional) Okta AWS App Name - aws_rolename = (optional) AWS Role ARN. 'ALL' will retrieve all roles, can be a CSV for multiple roles. - okta_username = (optional) Okta User Name + from Okta based on the available AWS Okta Apps and roles + assigned to the user. """ resolver = DefaultResolver() envvar_list = [ @@ -95,6 +55,7 @@ class GimmeAWSCreds(object): 'OKTA_MFA_CODE', 'OKTA_PASSWORD', 'OKTA_USERNAME', + 'AWS_STS_REGION' ] envvar_conf_map = { @@ -102,6 +63,7 @@ class GimmeAWSCreds(object): 'GIMME_AWS_CREDS_CRED_PROFILE': 'cred_profile', 'GIMME_AWS_CREDS_OUTPUT_FORMAT': 'output_format', 'OKTA_DEVICE_TOKEN': 'device_token', + 'AWS_STS_REGION': 'aws_region' } def __init__(self, ui=ui.cli): @@ -209,12 +171,16 @@ def _get_partition_from_saml_acs(saml_acs_url): raise errors.GimmeAWSCredsError("{} is an unknown ACS URL".format(saml_acs_url)) @staticmethod - def _get_sts_creds(partition, assertion, idp, role, duration=3600): + def _get_sts_creds(partition, region, assertion, idp, role, duration=3600): """ using the assertion and arns return aws sts creds """ - # Use the first available region for partitions other than the public AWS session = boto3.session.Session(profile_name=None) - if partition != 'aws': + + # If a region was passed, use that + if region is not None: + client = session.client('sts', region) + # Use the first available region for partitions other than the public AWS + elif partition != 'aws': regions = session.get_available_regions('sts', partition) client = session.client('sts', regions[0]) else: @@ -763,6 +729,7 @@ def prepare_data(self, role, generate_credentials=False): try: aws_creds = self._get_sts_creds( self.aws_partition, + self.conf_dict.get('aws_region'), self.saml_data['SAMLResponse'], role.idp, role.role, @@ -774,6 +741,7 @@ def prepare_data(self, role, generate_credentials=False): "The requested session duration was too long for the role {}. Falling back to 1 hour.".format(role.role)) aws_creds = self._get_sts_creds( self.aws_partition, + self.conf_dict.get('aws_region'), self.saml_data['SAMLResponse'], role.idp, role.role,