I was recently using the aws cli to test negative scenarios when doing AssumeRole in deploying resources. The negative tests were unexpectedly succeeding.
I have the following $HOME/.aws/credentials file (config file is empty).
[user1]
aws_access_key_id = ...
aws_secret_access_key = ....
[user2]
aws_access_key_id = ...
aws_secret_access_key = ...
[role-u1]
source_profile = user1
role_arn = arn:aws:iam::111111111111:role/myrole
[role-u2]
source_profile = user2
role_arn = arn:aws:iam::111111111111:role/myrole
I have a trust relationship between myrole and user1, so role-u1 works and role-u2 does not. If I use role-u1 first, then role-u2 unexpectedly succeeds.
role-u2 fails - expected (first call):
$ aws sts get-caller-identity --profile role-u2
An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:iam::222222222222:user/user2 is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::111111111111:role/myrole
role-u1 works - expected (second call):
$ aws sts get-caller-identity --profile role-u1
{
"UserId": "XXXXXXXXXXXXXXXXXXXXX:botocore-session-1752190162",
"Account": "111111111111",
"Arn": "arn:aws:sts::111111111111:assumed-role/myrole/botocore-session-1752190162"
}
role-u2 works - NOT expected (third call):
$ aws sts get-caller-identity --profile role-u2
{
"UserId": "XXXXXXXXXXXXXXXXXXXXX:botocore-session-1752190162",
"Account": "111111111111",
"Arn": "arn:aws:sts::111111111111:assumed-role/myrole/botocore-session-1752190162"
}
Why does using the "invalid" profile role-u2 not error, after using the "valid" profile role-u1?
(Sessions are cached under .aws/cli/cache)
When using the config/credentials files, subsequent calls will not issue an AssumeRole but just reuse the session details created by the first call, until the session expires. The session id used is global (botocore-session-1752190162) if not specified explicitly.
To fix, for each role profile, specify a distinct session name using role_session_name as follows:
[user1]
aws_access_key_id = ...
aws_secret_access_key = ....
[user2]
aws_access_key_id = ...
aws_secret_access_key = ...
[role-u1]
source_profile = user1
role_arn = arn:aws:iam::111111111111:role/myrole
role_session_name = role-u1
[role-u2]
source_profile = user2
role_arn = arn:aws:iam::111111111111:role/myrole
role_session_name = role-u2
Using role-u2 will now consistently fail.
role-u1 works - expected:
$ aws sts get-caller-identity --profile role-u1
{
"UserId": "XXXXXXXXXXXXXXXXXXXXX:role-u1",
"Account": "111111111111",
"Arn": "arn:aws:sts::111111111111:assumed-role/myrole/role-u1"
}
role-u2 fails - expected:
$ aws sts get-caller-identity --profile role-u2
An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:iam::222222222222:user/user2 is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::111111111111:role/myrole
Note: It is possible to tie multiple profiles to the same named session. Just use the same value for role_session_name. Then the session reuse issue will occur again.
Reference: https://docs.aws.amazon.com/cli/v1/userguide/cli-configure-files.html#cli-configure-files-settings
role_session_name
Specifies the name to attach to the role session. This value is provided to the RoleSessionName parameter when the AWS CLI calls the AssumeRole operation, and becomes part of the assumed role user ARN: arn:aws:sts::123456789012:assumed-role/role_name/role_session_name. This is an optional parameter. If you do not provide this value, a session name is generated automatically. This name appears in AWS CloudTrail logs for entries associated with this session.