6262
6363function aws_choose_role() {
6464 _preview=" ${FZF_PREVIEW:- crudini --format=ini --get " $AWS_CONFIG_FILE " ' profile {}' } "
65- cat " ${AWS_SHARED_CREDENTIALS_FILE:- ${GEODESIC_AWS_HOME} / .aws / credentials} " " ${AWS_CONFIG_FILE:- ${GEODESIC_AWS_HOME} / .aws / config} " 2> /dev/null |
65+ cat " ${AWS_SHARED_CREDENTIALS_FILE:- ${GEODESIC_AWS_HOME} / credentials} " " ${AWS_CONFIG_FILE:- ${GEODESIC_AWS_HOME} / config} " 2> /dev/null |
6666 crudini --get - | sed ' s/^ *profile *//' |
6767 fzf \
6868 --height 30% \
@@ -107,7 +107,7 @@ function aws_sdk_assume_role() {
107107# Asks AWS what the currently active identity is and
108108# sets environment variables accordingly
109109function export_current_aws_role() {
110- local role_name
110+ local role_name role_names
111111 # Could be a primary or assumed role. If we have assumed a role, cut off the session name.
112112 local current_role=$( aws sts get-caller-identity --output text --query ' Arn' 2> /dev/null | cut -d/ -f1-2)
113113 if [[ -z $current_role ]]; then
@@ -116,28 +116,62 @@ function export_current_aws_role() {
116116 fi
117117
118118 # If AWS_VAULT is not enabled, clear any setting from it.
119- [[ ${AWS_VAULT_ENABLED:- false} == " true" ]] || unset AWS_VAULT
119+ [[ " ${AWS_VAULT_ENABLED:- false} " == " true" ]] || unset AWS_VAULT
120120
121121 # Quick check, are we who we say we are? Does the current role match the profile?
122122 local profile_arn
123123 local profile_target=${AWS_PROFILE:- ${AWS_VAULT:- default} }
124+ # Remove the session name from the profile target role, if present
124125 profile_arn=$( aws --profile " ${profile_target} " sts get-caller-identity --output text --query ' Arn' 2> /dev/null | cut -d/ -f1-2)
125126 # The main way there would be a mismatch is if AWS_VAULT is set or there are API keys in the environment
126- if [[ $profile_arn == $current_role ]]; then
127+ if [[ " $profile_arn " == " $current_role " ]]; then
127128 # If we are here, then the current role matches the assigned profile. That is a good thing.
128129 # However, the profile name may not be the best name for the role. If it is too generic, try to find a better name.
129130 # Extract profile name from config file:
130131 # 1. For default profile, look for a better name
131132 # 2. Skip identity profiles (ending with -identity), as they are too generic
132133 # 3. Use the first non-default, non-identity profile found
133134 if [[ $profile_target == " default" ]] || [[ $profile_target =~ -identity$ ]]; then
135+ local backup_name=" $profile_target "
134136 # Make some effort to find a better name for the role, but only check the config file, not credentials.
135- local config_file=" ${AWS_CONFIG_FILE:- ${GEODESIC_AWS_HOME} / .aws / config} "
137+ local config_file=" ${AWS_CONFIG_FILE:- ${GEODESIC_AWS_HOME} / config} "
136138 if [[ -r $config_file ]]; then
139+ # Is this a normal IAM role or an Identity Center permissions set role?
140+ if [[ $current_role =~ AWSReservedSSO_[^_]+_[0-9a-f]+$ ]]; then
141+ # This is an Identity Center permissions set role
142+ # current_role is "arn:aws:sts::123456789012:assumed-role/AWSReservedSSO_IdentityAdminRoleAccess_5c90026c17fbd1c2"
143+
144+ # Extract account ID using cut
145+ local account_id=$( echo " $current_role " | cut -d' :' -f5)
146+
147+ # Extract the full role part
148+ local role_part=$( echo " $current_role " | cut -d' :' -f6) # This gets everything after the 5th colon
149+
150+ # Extract the role name by isolating it from boilerplate
151+ local sso_role_name=$( echo " $role_part " | cut -d' _' -f2) # This selects the second field delimited by '_'
152+
153+ # Find all profiles that have matching role names
154+ local profile_names=($( crudini --get --format=lines " $config_file " | grep " $sso_role_name " | cut -d' ' -f 3) )
155+ local profile_name
156+ for profile_name in " ${profile_names[@]} " ; do
157+ # Skip the generic profiles
158+ if [[ " $profile_name " == " default" ]] || [[ " $profile_name " =~ -identity$ ]]; then
159+ continue
160+ fi
161+ if [[ " $account_id " == " $( crudini --get " $config_file " " profile $profile_name " sso_account_id) " ]]; then
162+ export ASSUME_ROLE=" $profile_name "
163+ return
164+ fi
165+ done
166+ export ASSUME_ROLE=" $backup_name "
167+ return
168+ fi
169+
170+ # Normal IAM role
137171 # Assumed roles in AWS config file use the role ARN, not the assumed role ARN, so adjust accordingly.
138172 local role_arn=$( printf " %s" " $current_role " | sed ' s/:sts:/:iam:/g' | sed ' s,:assumed-role/,:role/,' )
139- role_name =($( crudini --get --format=lines " $config_file " | grep " $role_arn " | cut -d' ' -f 3) )
140- for rn in " ${role_name [@]} " ; do
173+ role_names =($( crudini --get --format=lines " $config_file " | grep " $role_arn " | cut -d' ' -f 3) )
174+ for rn in " ${role_names [@]} " ; do
141175 if [[ $rn == " default" ]] || [[ $rn =~ -identity$ ]]; then
142176 continue
143177 else
@@ -176,14 +210,14 @@ function export_current_aws_role() {
176210
177211 # saml2aws will store the assumed role from sign-in as x_principal_arn in credentials file
178212 # Default values from https://awscli.amazonaws.com/v2/documentation/api/latest/topic/config-vars.html
179- local creds_file=" ${AWS_SHARED_CREDENTIALS_FILE:- ${GEODESIC_AWS_HOME} / .aws / credentials} "
213+ local creds_file=" ${AWS_SHARED_CREDENTIALS_FILE:- ${GEODESIC_AWS_HOME} / credentials} "
180214 if [[ -r $creds_file ]]; then
181215 role_name=$( crudini --get --format=lines " ${creds_file} " | grep " $current_role " | head -1 | cut -d' ' -f 2)
182216 fi
183217
184218 # Assumed roles are normally found in AWS config file, but using the role ARN,
185219 # not the assumed role ARN. google2aws also puts login role in this file.
186- local config_file=" ${AWS_CONFIG_FILE:- ${GEODESIC_AWS_HOME} / .aws / config} "
220+ local config_file=" ${AWS_CONFIG_FILE:- ${GEODESIC_AWS_HOME} / config} "
187221 if [[ -z $role_name ]] && [[ -r $config_file ]]; then
188222 local role_arn=$( printf " %s" " $current_role " | sed ' s/:sts:/:iam:/g' | sed ' s,:assumed-role/,:role/,' )
189223 role_name=$( crudini --get --format=lines " $config_file " | grep " $role_arn " | head -1 | cut -d' ' -f 3)
@@ -193,11 +227,20 @@ function export_current_aws_role() {
193227 if [[ -z $role_name ]]; then
194228 if [[ " $role_arn " =~ " role/OrganizationAccountAccessRole" ]]; then
195229 role_name=" $( printf " %s" " $role_arn " | cut -d: -f 5) :OrgAccess"
196- echo " * $( green " Could not find profile name for ${role_arn} ; calling it \" ${role_name} \" " ) " >&2
230+ elif [[ $current_role =~ AWSReservedSSO_[^_]+_[0-9a-f]+$ ]]; then
231+ # This is an Identity Center permissions set role
232+ # current_role is "arn:aws:sts::123456789012:assumed-role/AWSReservedSSO_IdentityAdminRoleAccess_5c90026c17fbd1c2"
233+ # Extract account ID using cut
234+ local account_id=$( echo " $current_role " | cut -d' :' -f5)
235+ # Extract the full role part
236+ local role_part=$( echo " $current_role " | cut -d' :' -f6) # This gets everything after the 5th colon
237+ # Extract the role name by isolating it from boilerplate
238+ local sso_role_name=$( echo " $role_part " | cut -d' _' -f2) # This selects the second field delimited by '_'
239+ role_name=" ${account_id} :${sso_role_name} "
197240 else
198241 role_name=" $( printf " %s" " $role_arn " | cut -d/ -f 2) "
199- echo " * $( green " Could not find profile name for ${role_arn} ; calling it \" ${role_name} \" " ) " >&2
200242 fi
243+ echo " * $( green " Could not find profile name for ${role_arn} ; calling it \" ${role_name} \" " ) " >&2
201244 fi
202245 export ASSUME_ROLE=" $role_name "
203246}
0 commit comments