Skip to content

Commit 60b6b6f

Browse files
committed
Add support for Identity Center permission sets
1 parent 94d0e7d commit 60b6b6f

File tree

2 files changed

+56
-13
lines changed

2 files changed

+56
-13
lines changed

rootfs/etc/profile.d/aws.sh

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ fi
6262

6363
function 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
109109
function 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
}

rootfs/etc/profile.d/chamber.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
# and we will set the `CHAMBER_KMS_KEY_ALIAS` environment variable for you here.
1717
#
1818

19-
if [[ -z $CHAMBER_KMS_KEY_ALIAS ]] && [[ -n $CHAMBER_KMS_ALIAS ]]; then
20-
export CHAMBER_KMS_KEY_ALIAS=$CHAMBER_KMS_ALIAS
19+
if [[ -z "$CHAMBER_KMS_KEY_ALIAS" ]] && [[ -n "$CHAMBER_KMS_ALIAS" ]]; then
20+
export CHAMBER_KMS_KEY_ALIAS="$CHAMBER_KMS_ALIAS"
2121
unset CHAMBER_KMS_ALIAS
2222
fi

0 commit comments

Comments
 (0)