Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support multiple login sessions for a single start url #2374

Open
tikicoder opened this issue May 1, 2021 · 36 comments
Open

Support multiple login sessions for a single start url #2374

tikicoder opened this issue May 1, 2021 · 36 comments
Labels
documentation This is a problem with documentation. feature-request This issue requests a feature. p3 This is a minor priority issue

Comments

@tikicoder
Copy link

Describe the bug
The logic around how you name the cache files is flawed.
The way the cache File name is determined is based on the SSO Start URL. What happens when you have multiple profiles with the same start_url

Steps to reproduce

View the following links,

cache_key = self._generate_cache_key(start_url)

https://github.com/aws/aws-sdk-go/blob/b9d2b59a417d8332de5d8a598976dc27416a4443/aws/credentials/ssocreds/provider.go#L117
https://github.com/aws/aws-sdk-go-v2/blob/b7d8e15425d2f86a0596e8d7db2e33bf382a21dd/credentials/ssocreds/provider.go#L103

Expected behavior
The cache file name should be based on the profile name or profilename + url

Debug logs
This could cause the the system to use the wrong creds.

@tikicoder tikicoder added the needs-triage This issue or PR still needs to be triaged. label May 1, 2021
@kdaily kdaily self-assigned this May 3, 2021
@kdaily kdaily added guidance Question that needs advice or information. and removed needs-triage This issue or PR still needs to be triaged. labels May 3, 2021
@kdaily
Copy link
Member

kdaily commented May 3, 2021

Hi @tikicoder,

The standard use case here is that all of your profiles that are SSO-enabled are using the same portal login. Each of your profiles can be configured separately to access different accounts or roles that each use the same SSO portal with whatever login credentials you use (hence the same start_url). Once you login to the SSO portal (for example in the AWS CLI v2, with aws sso login), that session is cached.

Do you mean if you had two different sets of SSO portal login credentials (e.g., whatever you do through the browser to authenticate), and each one provided different sets of accounts and roles to access? In that case you would need to logout first (like aws sso logout). Caching based on the start URL plus profile wouldn't help, because we don't know what credentials you used in the portal to log in with.

As is, this would be a feature request, but if you can provide more details about your scenario that would help others decide if this fits their use case as well. Thanks!

@kdaily kdaily added feature-request This issue requests a feature. response-requested Waiting on additional info and feedback. and removed guidance Question that needs advice or information. labels May 3, 2021
@tikicoder
Copy link
Author

Sorry for not providing more of an example.

So if I run
aws configure sso --profile admin

it will prompt me for the information region, SSO Start URL ect, and it will have me log in. Lets say this is my admin This is the first profile I created with sso start url of
https://company-sso.awsapps.com/start

I then create a second profile, with limited permissions.
so again I run
aws configure sso --profile data
It prompts me for the same basic information and I enter it. I use all the same information specifically
https://company-sso.awsapps.com/start

The issue, to me is more of a security risk.
So both profiles get created and all the cached files get created.

So now when you are logged in it creates 2 cache files
~/.aws/sso/cache/bcdabce7b87112763a8ad312f0e2f307d1f6efd5.json (for the admin profile)

then it creates another hash, and it looks like it is partially based on time.

All the code I have seen when I run this command via a profile via cli or sdk, it all seems to have similar code
run aws ec2 describe-vpcs --profile data

It looks for a hash file of
~/.aws/sso/cache/bcdabce7b87112763a8ad312f0e2f307d1f6efd5.json
Which should be incorrect, because that hash file contains the security information for the admin profile, not the data profile.
So in theory the script or command could have more access then intended.

That is why I labeled it as a bug and not a feature. It is possible I missed code so it is referencing the correct cache file, but all the code I have seen to determine what cache file to use is only referencing the lookup around the SSO URL
example
https://github.com/aws/aws-sdk-go/blob/b9d2b59a417d8332de5d8a598976dc27416a4443/aws/credentials/ssocreds/provider.go#L117
func getCacheFileName(url string) (string, error) {
hash := sha1.New()
_, err := hash.Write([]byte(url))
if err != nil {
return "", err
}
return strings.ToLower(hex.EncodeToString(hash.Sum(nil))) + ".json", nil
}

@github-actions github-actions bot removed the response-requested Waiting on additional info and feedback. label May 4, 2021
@kdaily
Copy link
Member

kdaily commented May 4, 2021

Hi @tikicoder,

Thanks for the further details. There are two separate caches in use here. The first one is for the SSO login, which stores an access token and is indexed by the SSO portal start URL. By default, this is stored in ~/.aws/sso/cache. When you run a command, temporary credentials are fetched and also cached. These are indexed per profile and are stored by default in ~/.aws/cli/cache/. You won't be using credentials that are providing access that is incorrect.

@kdaily kdaily added the response-requested Waiting on additional info and feedback. label May 4, 2021
@tikicoder
Copy link
Author

tikicoder commented May 4, 2021

@kdaily That makes sense. However, the credentials that are generated in the ~/.aws/cli/cache/ are based off the SSO. So those in there the cli creds should expire first, or if someone deleted the cli cache. Wouldn't the new cache file use the logic from above and determine the cache file is based on the sso url name? So when it went to regen the token it would find the cache file based on the url and give the creds from the admin setup because that has the hash based on url? If not isn't that what the sdk is doing, or am I missing some logic?

When cached info expires
sso experation
2021-05-05T01:28:39Z

cli experation
2021-05-02T01:20:58Z

(update - 2021-05-05 17:05 UTC)
The logic from above is also presuming when the cli cache was created it created based on the SSO that was just logged in. I have no reason not to think that I haven't dived in the code enough, but still wanted to call it out.

@github-actions github-actions bot removed the response-requested Waiting on additional info and feedback. label May 4, 2021
@kdaily
Copy link
Member

kdaily commented May 20, 2021

Thanks for the followup. There are so many users and accounts in these scenarios, so I want to clarify what you're expecting. For definitions, account means AWS account; user means SSO portal user; profile means the named profile in the configuration file; role means the SSO role set up for a user.

Here's the use case I set up. I have a single AWS account. I created an SSO portal and two users, userOne and userTwo. In my portal, I also created two roles, one for Admin and one for Data. userOne is able to use the Admin role, and user2 only can use the Data role. So, my CLI config file looks like the following:

[profile userOne]
sso_start_url=https://mycompany.awsapps.com/start
sso_region=us-west-2
sso_account_id=96898945XXXX
sso_role_name=Admin
region=us-west-2
output=json

[profile userTwo]
sso_start_url = https://mycompany.awsapps.com/start
sso_region = us-west-2
sso_account_id = 96898945XXXX
sso_role_name = Data
region = us-west-2
output = json

If I log in as userOne (e.g., use the web browser to login and generate access token that is exchangable for temporary credentials), then I cannot use them for userTwo. For example, if I try to do aws sts get-caller-identity --profile userTwo, I get:

botocore.exceptions.ClientError: An error occurred (ForbiddenException) when calling the GetRoleCredentials operation: No access

The converse is true as well - if I log in as userTwo I cannot successfully use the userOne profile.

Is your scenario the same, or is there a account/user/role that is changing differently?

@kdaily kdaily added the response-requested Waiting on additional info and feedback. label May 20, 2021
@tikicoder
Copy link
Author

tikicoder commented May 20, 2021

Its is similar so keeping with your example.

log in to both userOne and userTwo
aws sso login --profile userOne
aws sso login --profile userTwo

Both users should be logged in

If you look in ~/.aws/sso/cache there is only one file.
At this point you should be able to
aws sso login --profile userOne (lets just ensure it is the last one used)

when running
aws sts get-caller-identity --profile userOne
aws sts get-caller-identity --profile userTwo
You should see the results you expect

edit the ~/.aws/config using your text editor of choice
change sso_role_name from Data to Admin

then run
aws sts get-caller-identity --profile userOne
aws sts get-caller-identity --profile userTwo

userTwo is now an Admin, because userTwo is using the SSO from userOne to generate its token/creds

They way around this would be to have different start urls, so the sso cache file is different, just adding / is enough but that only gives you 2 different profiles.

Another example using python
if you run the following python (I can get you a better script if you want / need)
import boto3, botocore
from botocore.session import get_session
from botocore.config import Config

session_default = boto3.session.Session(profile_name="savvasSSODefault")
session_test = boto3.session.Session(profile_name="test")

default_client = session_default.client("sts")
test_client = session_test.client("sts")

print("main \n{}".format(default_client.get_caller_identity()))
print("\ntest \n{}".format(test_client.get_caller_identity()))

@github-actions github-actions bot removed the response-requested Waiting on additional info and feedback. label May 20, 2021
@benkehoe
Copy link

benkehoe commented Jul 9, 2021

I think there is confusion about "user" here. You've got "user" as part of the profile name, but a profile configured for an AWS SSO role does not and cannot represent a particular human. The profile represents an IAM principal that a human, who has logged in via AWS SSO, can get credentials for (if they have access to it, as configured with AWS SSO assignments). So different humans can use the same profile, but not at the same time, because only one human can be logged in for the CLI to a given AWS SSO instance (i.e., a given start URL) at a time, for a given local machine user (i.e., a given home directory). Once signed in to AWS SSO, that human can use multiple profiles (i.e., accounts and roles) without needing to log in again. If a different human needs to use the same computer (with the same home directory, i.e. the same ~/.aws/sso/cache), the previous human needs to be logged out of the AWS SSO browser session (and the federated IdP if there is one), as well as replacing the cached SSO token in ~/.aws/sso/cache by logging in again with the CLI.

Note that the account and role specified in an profile can only be used if the signed-in human is granted access to it through AWS SSO. So changing the role name in a profile has no effect on the access that the human is granted. You've got the phrase "userTwo is now an Admin", which is not correct. The human is now an Admin when using the "userTwo" profile, though the name "userTwo" is not a good profile name; it should have been "Data" (or similar) after the role it was configured to use. If the human has not been granted access to the Admin role through AWS SSO, this profile will not work for them! You're right that this could cause confusion, if I changed a "Data" profile to use an Admin role instead of a Data role, or more seriously, if I changed the account in a "Data-Dev" profile to the Prod account, I could get a user to accidentally make changes to Prod, but the assumption of the AWS CLI is that the user is responsible for the security and integrity of their ~/.aws/config file.

Part of the problem here is that aws sso login takes a profile as input, but does not act on the account and role in that profile! It does not retrieve credentials for the account and role specified in the profile, it only logs in to AWS SSO and caches the AWS SSO login token, which is scoped to the specific user's login session and provides access to all the accounts and roles. It represents the human, not the IAM principal. You can see the code for aws sso login here and see that the account and role are not involved.

So while it seems from looking at the command that you're logging in to the specific account and role, it's only use the profile to get the AWS SSO instance (because that's the only configuration the AWS CLI knows how to use). You do not need to call aws sso login for each different account and role you're using.

Suppose you have the following ~/.aws/config:

[profile my-profile-1]
sso_start_url = https://foo.awsapps.com/start
sso_region = us-east-2
sso_account_id = 123456789012
sso_role_name = Role1

[profile my-profile-2]
sso_start_url = https://foo.awsapps.com/start
sso_region = us-east-2
sso_account_id = 123456789012
sso_role_name = Role2

So if you do aws sso login --profile my-profile-1, you get a browser popup and sign in as Mr. Smith, there's now an SSO token in ~/.aws/sso/cache representing Mr. Smith, but no AWS credentials (access key id, secret access key, session token) on the system for Role1. If you then call aws sts get-caller-identity --profile my-profile-1, the cached SSO token representing Mr. Smith will be used to retrieve AWS credentials for Role1, which will be cached in ~/.aws/cli/cache. If you call aws sts get-caller-identity --profile my-profile-2, the cached SSO token representing Mr. Smith will be used to retrieve AWS credentials for Role2, and also cached in a separate entry in ~/.aws/cli/cache. Calling aws sts get-caller-identity --profile my-profile-1 again will use the cached credentials for Role1 in ~/.aws/cli/cache.

If you then call aws sso login again with either --profile my-profile-1 or --profile my-profile-2, it's going to pop up the browser again, because the logic in the CLI is to force a refresh of the token. But because the browser has a cookie from AWS SSO from the previous log-in, it will attempt to re-authenticate you.

If a new person, Mx. Jones, wants to use the same machine (with the same home directory), they need to be signed out in the browser first, so going to https://foo.awsapps.com/start and signing out, and if the AWS SSO instance uses a federated IdP, they need to go there and sign out as well. Then they can call aws sso login --profile my-profile-1 or aws sso login --profile my-profile-2, which will cause the browser popup (because even though there's a cached token, it always refreshes it), and because the browser session(s) has been logged out, they will get a sign-in screen where they can sign in, and the result is a new cached SSO token in ~/.aws/sso/cache representing Mx. Jones.

This is the intended behavior. The expectation for the CLI is that one human is logged in at a time, just like in the browser. If Mx. Jones wants to log in to the AWS console in the browser, they will need to log out of Mr. Jones's browser session (or more properly, Mr. Jones should have logged out when he was done using the machine 😉).

The UX problem here is that the CLI login command looks like it's logging in to a specific profile, even though that's not its purpose (and logging in to a specific profile is not a needed operation, because the CLI and SDKs* are capable of getting and refreshing credentials for an account+role the user has access to through AWS SSO at the time of usage).

The reason the CLI login command looks like this is that there's no current way to specify an AWS SSO instance (start URL and region) in any form other than a full profile. I have an open issue on that with the CLI here aws/aws-cli#5727.

In my command line utility aws-sso-util, I provide an aws-sso-util login command that will just look at your ~/.aws/config and if there's only one start URL configured in there, it'll just use that value. Note this is the way aws configure sso already works for finding the default SSO start URL to populate. Docs for aws-sso-util login are here.

* Note about the SDKs: not all SDKs have support for using AWS SSO configuration. For the ones that don't, aws-sso-util provides a mechanism to backfill support, see the docs here

@tikicoder
Copy link
Author

tikicoder commented Jul 9, 2021

@benkehoe
No my issue still stands.

When you sign in with either my-profile-1] or my-profile-2 1 sso token file is generated. So the last one logged in is the active token for BOTH profiles. To your point The token is associated with a role that has permissions ABC. So If my-profile-1 has a role with more permissions and its logged into last the token file generated that both profiles use will be using the last token generated.

The cached file for SSO is based on the start url

If you create both profiles like you mentioned and then look
/.aws/sso/cache/

You can log into both profile but there is only 1 cache and if you watch the cache file is updated as you switch profiles.
So as long as the sso_start_url is the same they all share the same cache file. Unless there is some other authentication or validation going on the sso tokedata can retrieve any role that the last sso login had access to. Which to me seems like a bit of a security concern.

@benkehoe
Copy link

benkehoe commented Jul 9, 2021

The token in ~/.aws/sso/cache is not associated with a role. The token is associated with the human who has logged into AWS SSO, and grants access to any of account+roles allowed through AWS SSO, which may or may not be present in ~/.aws/config, and there may be accounts and roles in ~/.aws/config that it does not have access to. This is true in the browser, if you go to the start URL, say http://foo.awsapps.com/start, you get logged in, and from there can enter any account+role you have access to. You do not need to re-log in to access any of the other account+roles you have access to. The equivalent of the token in ~/.aws/sso/cache is stored in a browser cookie.

Let me put it this way: imagine instead that the command was aws sso login --start-url https://foo.awsapps.com/start, with no mention of profiles. Your expectation would be that the resulting session is not scoped to a particular profile, because no profile is mentioned. This is how the CLI code works, it does not actually deal with anything related to the specific profile you pass in, it just reads the start URL and SSO region. The reason that cache file gets updated is that, as I mentioned above, the CLI always refreshes the token when you use aws sso login regardless of whether the existing token is valid or not. If the same user is logged in, the updated token just has a different expiration, not a different scope (by design). Note also that if you call aws sso login with the same profile, it will also update the cache, for the reason just mentioned.

The CLI makes an explicit assumption, just as the AWS web console does, that there is one human using the system at a time, and therefore when they are logged in, they have access to all the things they have access to. The purpose of AWS SSO is that you should only have to enter your credentials once, i.e., sign on a single time, to use all of AWS that you have access to. With the assumption just mentioned, this is not a security problem, just as in the browser.

I think what you want to argue is that it is confusing that a profile is the input to aws sso login, because the login is not scoped to the account and role in the profile. I agree completely with that, but the answer in my opinion is that the input to aws sso login should be something that is only a start URL and SSO region, without an account and role, because it would make it clearer that the scope of the login is not to a particular account and role.

@tikicoder
Copy link
Author

@benkehoe
Here is my understanding of how it works.
I run
aws sso login --profile my-profile-1
It opens up a browser and caches a token for me for about 24 hours.
Then I run
aws ec2 describe-instances --profile my-profile-1
it uses the cache token

I do the same
aws sso login --profile my-profile-2
it does the same thing
aws ec2 describe-instances --profile my-profile-2

It now uses the token from my-profile-2
Lets be honest now that you are logged in its all about the token/secret combination

its been a couple hours and I run
aws sso login --profile my-profile-1
I Wanted to ensure I Was still logged in.

not thinking about it I run
aws ec2 describe-instances --profile my-profile-2

what happens?

aws ec2 describe-instances --profile my-profile-2 will use the token from my-profile-1
The token for both profiles share the same file and there is nothing in the file to separate them.

I have done the above and not had any issues running any commands.

Unless I am mistaken, once you have the token/secret. How you logged in doesn't matter, or how it was generated doesn't matter. You have it. You have access to whatever that combination has access to.

But at the end of the day when you have 2 profiles with the same start url they share the same cache file. In doing so, unless again there is anther validation that happens, they will share the same token/secret. Which that really is what matters.

If you haven't tried it and have sso try it. Check the cache file. You will see you only have 1 regardless the number of profiles you create. Try running commands they should be using the token/secret for the last profile logged in with that has that start url.

look at the code link below, you can see that it uses the start url for the hash.
https://github.com/aws/aws-sdk-go-v2/blob/b7d8e15425d2f86a0596e8d7db2e33bf382a21dd/credentials/ssocreds/provider.go#L103

If aws doesn't feel its an issue or a feature request they can close it. Or if you have power you can close it. To me, could just be me being stubborn, multiple profiles with the same start url all share the same token/secret. The last one logged in is the access you have.

@benkehoe
Copy link

benkehoe commented Jul 9, 2021

To repeat, you are misunderstanding the relationship between the token in ~/.aws/sso/cache and the profile: the token in ~/.aws/sso/cache is not "for" the profile used in aws sso login, it is "for" the start URL

You are saying the expected flow is:

aws sso login --profile my-profile-1
aws ec2 describe-instances --profile my-profile-1

aws sso login --profile my-profile-2
aws ec2 describe-instances --profile my-profile-2

but this is incorrect. The intended flow by the AWS SSO and CLI teams is:

aws sso login --profile my-profile-1

aws ec2 describe-instances --profile my-profile-1

aws ec2 describe-instances --profile my-profile-2

aws ec2 describe-instances --profile profile-with-different-start-url
Error loading SSO Token

The entire purpose of AWS SSO is that the aws sso login call only needs to happen once, for any profiles with the same start URL. I am fully onboard with the fact that it is confusing that the input to aws sso login is a profile, because it appears to indicate that aws sso login should be called once for each profile that is being used, but this is not the case.

The cache entry in ~/.aws/sso/cache is the start URL by design: when you log in, you are logging in once to the AWS SSO instance (i.e., the start URL). The point is that you do not need to log in again to use a different account+role for the same start URL.

When you say "The token for both profiles share the same file and there is nothing in the file to separate them." you are misunderstanding the design of the system. Instead, think of it this way: "Both profiles share the same start URL, so they are both able to use the token for a session with that start URL to get credentials for the role in the profile". You fed this start URL to aws sso login by telling it one of the profiles that has the start URL, but the login, and the token, is "for" the start URL, not for the profile.

It would be less confusing if the flow was:

aws sso login --start-url https://foo.awsapps.com/start

aws ec2 describe-instances --profile my-profile-1

aws ec2 describe-instances --profile my-profile-2

aws ec2 describe-instances --profile profile-with-different-start-url
Error loading SSO Token

which is essentially what's happening.

@tikicoder
Copy link
Author

"The entire purpose of AWS SSO is that the aws sso login call only needs to happen once, for any profiles with the same start URL. I am fully onboard with the fact that it is confusing that the input to aws sso login is a profile, because it appears to indicate that aws sso login should be called once for each profile that is being used, but this is not the case."

If it only needs to happen once, then how do you set different permissions. My point the problem with that logic is you could have multiple profiles so you are using least permissions. I could have user a or user b. User b could be my day to day user and have separate login information. User a could be my I need admin access to do something. So I only log in when needed.

With the logic above that can't happen. I understand why its happening I strongly disagree with "The entire purpose of AWS SSO is that the aws sso login call only needs to happen once, for any profiles with the same start URL."

Since you could have 5 different profile for 5 different users all in your same setup for various scripts. Each user could have its own set of permissions. So that means to run each script you would have to log in before each script, or run the risk that you are using the wrong information. I will stand firm on this, and we will have to agree to disagree. Call it what you like but the ability for multiple accounts to use the same cred is a security issue. You are asking for a script to get ran with permissions it shouldn't or people are running with higher permissions then they need. Again to your point, "The entire purpose of AWS SSO is that the aws sso login call only needs to happen once, for any profiles with the same start URL". To me that is a horrible fundamental flaw in the system.

If you have 5 profiles all with the same start url with 5 different role_names (since profiles are not tied to a user but a role) do you except that you can log in with 5 different users if you want or do you expect that the system just wants you to log in once. For me they are separate profiles and should be treated as such. The start url is a horrible way to group them. If they were grouped by start url and role name at least then you could be ensured that if you are using multiple users for each role, they are not sharing.

We will have to probably agree to disagree on this, but AWS @kdaily or anyone else can close it if they want.

@benkehoe
Copy link

benkehoe commented Jul 9, 2021

When you say "you can log in with 5 different users", I don't understand what you mean by "users". There's the human, and there are the roles that the human can assume. If we think about the browser, you log in once through AWS SSO using your start URL, and you get to a page that lists all the accounts you have access to, and all the roles under each account. You can click "management console" under each of those roles, and a new tab pops up, giving you a console session with that role. You can return to the tab and click "management console" for a different role, without signing in again, or going to your start URL again. This open tab with all of your roles is like what you have after calling aws sso login: access to all the roles you have access to. As a user, in the browser you click to go into your day-to-day role, or, only when you need it, you click to go into your admin role. In the CLI, you use the day-to-day profile, or only when you need it, you use the admin profile.

When you say "multiple accounts use the same cred", again I don't understand what you mean by accounts. Multiple people aren't using the same SSO token, nor the same AWS role credentials. A single person is using multiple IAM roles, which may be in the same or different AWS accounts.

@tikicoder
Copy link
Author

Lets say I have 2 logins
admin
day to day activities

I have 2 profiles
admin
default

When I do
aws sso login --profile default
I log in using the user
[email protected]

when I login as admin I use the user
[email protected]

each user only have access to a subset of roles. The admin has full access to everything.

The default user only has limited access to the things I normally need to do.

Under what you describe.
since both profiles use the same start url its ok. But in this case its not. (I do not agree it is ok in the other situation but again agree to disagree).

Each user would return its own token and have its own roles to limit what you can do.
So if I log in with default run a script, then I realize I have to make a new account or fix something and I run aws sso login --profile admin.
I have not elevated my default profile unless I log back in as that other user.

@benkehoe
Copy link

benkehoe commented Jul 10, 2021

Those different emails would be different users within AWS SSO, which means they do not share the same permissions. The user id for [email protected] could be granted the Normal role, and [email protected] could be granted the Admin role and not the Normal role.

When you call aws sso login with either profile, the browser pops up, and you must sign in. If you sign in as [email protected], the token in ~/.aws/sso/cache represents [email protected], and only has access to the Normal role. If you sign in as [email protected], the token in ~/.aws/sso/cache represents [email protected], and only has access to the normal role. Here are some examples:

aws sso login --profile default
# signs in as [email protected]
aws ec2 describe-instances --profile default # works
aws ec2 describe-instances --profile admin # error, no access
aws sso login --profile admin
# signs in as [email protected]
aws ec2 describe-instances --profile default # works
aws ec2 describe-instances --profile admin # error, no access
aws sso login --profile admin
# signs in as [email protected]
aws ec2 describe-instances --profile default # error, no access
aws ec2 describe-instances --profile admin # works
aws sso login --profile default
# signs in as [email protected]
aws ec2 describe-instances --profile default # error, no access
aws ec2 describe-instances --profile admin # works

Note that aws sso login doesn't actually check if the signed-in user has access to the profile that's being given to it. It doesn't even check that the account and role in the profile are even valid.

Note that if you do the following though:

aws sso login --profile default
# signs in as [email protected]
aws ec2 describe-instances --profile default # works
aws ec2 describe-instances --profile admin # error, no access

# want to sign in as admin now
aws sso login --profile admin # or aws sso login --profile default, it doesn't matter

if you have not signed out of AWS SSO in your browser, by going to the start URL and clicking "sign out" (and, if you're using a federated identity provider, you need to sign out of that too), you won't get the chance when doing the second aws sso login to sign in as a different user; the browser cookie is already there, and it will go straight to "sign in to the AWS CLI?" and when you click OK, you will get a token representing the user who is already signed in in the browser, in this case [email protected]. The expectation in the system is that all your access is provided to a single identity (which is common for single sign-on systems).

All that said, this is not really a "single sign-on" setup, if you are using multiple email addresses for the same person. AWS SSO has been designed with the assumption that a given person has a single identity in the system, and so I think there's going to be friction if that's not true, which makes it valid to complain about that friction (e.g., that it takes a bunch of clicks to actually get fully signed out in the example above)

Edit: it actually looks like if you aren't using a federated identity provider, aws sso logout does invalidate your browser session.

@tikicoder
Copy link
Author

Again agree to disagree about its not single sign on. The point of single sign on is to have an account that can log into several things.

The only thing I am saying here is I have 2 users depending on the access I want to give, which again isn't unheard of, and even AWS recommends that your Admin account is separate from user accounts.

To your point typically you would just have a user a and then if you needed more permissions you could make an elevation request. Which in itself has its own risks and downfalls.

Which bring it back full circle. even looking at 1 user if the profile I log in with is connected to a user that has admin role and normal role. I personally expect that if I have 2 different roles I would have 2 different tokens/secrets. If nothing more to give me the façade that they are a bit separate. I just have a problem with the fact that 2 roles with potentially highly different permissions are using the same base token/secret to generate from. Instead of 2 different tokens/secrets to ensure that they do not cross streams.

@benkehoe
Copy link

There are separate cache entries for every profile, in ~/.aws/cli/cache, each entry corresponding to an account+role combination, containing the AWS credentials (access key id, secret key, session token).

You can only be logged in through aws sso login as a single user identity at a time, and so there's only one cache entry, in ~/.aws/sso/cache for the token corresponding to the user identity. aws sso logout clears both caches. If you log in as a different user identity, it overwrites the cache, so the token representing the previous user is gone. That is, you can't be both [email protected] and [email protected] at the same time. But when you are [email protected], you can use any role that [email protected] has access to, and when you're [email protected], you can use any role that [email protected] has access to.

@benkehoe
Copy link

Can you tell me if the browsers-side experience for AWS SSO, with the AWS web console, matches your expectations, or do you have similar feelings about it?

@tikicoder
Copy link
Author

When I use the browser I only have access to what the user has access and I am presuming the token is based as such. It regens based on the user that logs in. Which is 100% what I expect. But with AWS you can only be in 1 user in 1 account. at a time.
A script you could be using multiple profile multiple accounts all at various things all at the same time. or close to it.

To your point there are some extras that the cli is doing.
From my point and someone who is scripting a lot of things to work in boto. I am using the profile as a starting point to make the creds that I need. This way I can touch accounts easier. CLI is nice but its a pain to do things across regions or accounts at times. a lot of commands will allow for a --region but no --account. The cli creds to your point are account_role specific which is create. Someone could easily script something based on that SSO profile to do some nasty things because its not limited.

@tikicoder
Copy link
Author

You can argue that it requires access to the computer and then someone has larger issues. But still shouldn't some things try to mitigate that risk. The goal of things is to make scripts that can do the work for you. I shouldn't have to worry that I created a script to use boto so I can touch multiple accounts easily instead of cli, since with cli if I have 100 accounts I would have to have a profile for each account. With boto, I can use the profile cache and generate creds to touch any account I Want.

@benkehoe
Copy link

benkehoe commented Jul 10, 2021

I'm confused; there isn't a difference between the access or scripting you could do with boto3 vs the CLI. The AWS SSO API explictly allows enumeration of the access a user has; this is what powers the autocompletion of aws configure sso.

If your complaint is that you'd like the ability to have the AWS SSO token when you're logging in have smaller scope, that's a completely valid request, and is supported in theory by the authentication API, which allows the specification of scope when getting a token though as far as I know this is not currently usable for anything. However, even in that case, the design is that you can have one of those tokens at a time, which is why there's only the single cache entry for a given start URL. If you wanted to change the scope you have access to, you'd call aws sso login again with some scope specification, and that would result in a new token that overwrites the existing token in the cache, so now you can only use the new scope. If you wanted to change the user identity you're logged in as, possible with a scope of its own, you'd call aws sso login again, specifying that you want to change identity and use whatever scope you want, and that'd result in a token that overwrites the existing token in the cache, so now you can only be that new identity with that new scope.

None of that changes that the cache key for the SSO token cache would be the start URL, because there should only be one of these tokens at a time. And I think you in particular actually want that, because it would mean you couldn't use two different profiles that you expect to use with two different identities at the same time.

@benkehoe
Copy link

benkehoe commented Jul 10, 2021

It's also a valid complaint that the implied scope of aws sso login --profile my-profile is only the access used by my-profile. I agree with that, but I think the answer there is to change the aws sso login command to take inputs that align with the scope of the current token (which is what I did with aws-sso-util login).

@tikicoder
Copy link
Author

If you wanted to list all ec2 instances across 10 accounts and you were using SSO
how would you do it.
https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-instances.html

the following fails
aws ec2 describe-instances --profile default--region us-east-1 --account 000000000000

So you would need 2 different profiles
With boto, I can create custom configs in code on the fly.

@tikicoder
Copy link
Author

I have created my own util that allows me to read the sso cached data and create tokens/secrets per account based on a role I Want to make.

It is easy for someone to pass in admin and just get full access since the main sso token/secret is not scoped to be limited.

@tikicoder
Copy link
Author

@benkehoe
thank you this has been an interesting and enjoyable conversation.

@benkehoe
Copy link

benkehoe commented Jul 10, 2021

For the CLI, I can create a bash script that uses jq to read from the file in ~/.aws/sso/cache, aws sso list-accounts and aws sso list-account-roles to determine all the access, and aws configure set to write new profiles to ~/.aws/config before using them with aws ec2 describe-instances. All the same things are possible.

I do agree it's easier in Python, and I too wrote utilities for it 🙂, available on PyPI as aws-sso-lib.

It is easy for someone to pass in admin and just get full access since the main sso token/secret is not scoped to be limited.

I think this is the crux of your issue, and as I said, it's a completely valid complaint that I agree with, but is not solved by modifying the AWS CLI's cache design for SSO tokens, only by changing the SSO authentication API to be able to return tokens with smaller scopes.

@tikicoder
Copy link
Author

Yup, your util is what got me started, I figured there had to be a simpler way
https://github.com/tikicoder/samples/blob/main/aws_samples/scripts/python/common/awsSSO.py

Which then lead me down a horrible rabbit hole.
I had the base presumption that the login might have handled some of the scope already, but it sounds like it doesn't so I would agree this is a 2 part request.

Fix the SSO Authentication API so it can return smaller scopes, and to separate out the sso cache tokens.

@benkehoe
Copy link

I'm not clear about how cache full of small-scoped tokens is substantially better than a cache with one token with all the same access. You mentioned the browser only being able to be one role at a time as a positive thing, wouldn't it be a positive thing for the CLI only to be logged in as one scoped access at a time? That is, if you went from being logged in as Normal to be logged in as Admin, you'd have to re-login as Normal to use it again?

@tikicoder
Copy link
Author

tikicoder commented Jul 10, 2021

I like how the browser feels like it has that limited scope, but that is only a facade because it only lets you be in 1 account, with 1 role at a time.

The difference is each SSO profile is now scoped to the limit the permissions at the main token/secret level. So if I have 2 profiles one with normal access and one with admin access. No one can use the normal one to get admin access.

I can invalidate the admin one without invalidating the normal one. So if I have a script that calls other scripts. 10 of the other scripts all run as normal, but 1 script needs admin that 1 that needs admin can still get it without breaking the session on the others and I know the others still have a hard scope.

If I tried to do something mailouts with a master token/secret that was scoped to a normal role I couldn't. It could also mean that as a developer you could set a normal login cache for longer than an admin one. My admin Token I would want to expire after 30 minutes, but the normal one is ok that its once a day.

Again, it leads to its own wormhole. But it starts with being able to limit the scope at the main token/secret level.

Where should the requirement to ensure my access is limited be enforced.
Both the script and the auth, but I would say the auth has a larger responsibility.

With the separate I can have my script auto log out of the admin but leave the normal alone and continue my daily activities without missing a beat. Which should I have to log back into normal I didn't elevate it I used a different profile and different scope.

@benkehoe
Copy link

I see where you're coming from, but it seems like a weird place to put those constraints, given the upstream browser cookies still have the broad access. There's still no re-authentication with you, the human, required to get the Admin-scoped token back. So AWS SSO should have rules about re-authentication for given scopes. Even then, I'd say I'd want more like "get a new elevated token that includes the Admin scope" followed by "get a new token that excludes the Admin scope", rather than manage multiple tokens. But we can come back to that debate once the API has the feature we want 😄.

@tikicoder
Copy link
Author

@benkehoe I am good with that.
Cause regardless we both at least want the SSO Token/Secret to be limited in scope.

I would say that some of this could apply at the upstream browser level. But again, an interesting conversation once the API is updated

@kdaily
Copy link
Member

kdaily commented Jul 16, 2021

Thanks @benkehoe for your superb engagement here! I appreciate the callout of what 'user', profile, and 'human currently using the computer' mean here to help clarify.

@tikicoder, given all of this discussion I hope you're in a place that you understand what the AWS CLI and the Python SDK allows you to do with SSO and why. There are some improvements to the documentation that I can take away from here, marking this one as such.

With respect to feature changes, is there still anything other the scope of tokens (which isn't for Python SDK directly to solve), or the user experience with how you login (covered by aws/aws-cli#5727, I think)?

@kdaily kdaily added the documentation This is a problem with documentation. label Jul 16, 2021
@tikicoder
Copy link
Author

@kdaily I think there is still a conversation about also the whole multi profile with the same starturl. Again if I am running 2 users even if the roles are the same I should be able to track them separately or as you go from one profile to the next does that log you out of the other profile. To me I have 2 profiles regardless and I should be able to ensured they are tracked/treated separate. I will stand firm on that, but again I understand if people disagree.

I mean if I was living in an apartment and I had roommates they shouldn't be able to call up my cell provider and be treated as me just because we live under the same roof. I understand everything, so I get why, but I can disagree.

But again the scope is a win.

@kdaily kdaily removed their assignment Jul 21, 2021
@joguSD joguSD changed the title SSO Cache File Name Support multiple login sessions for a single start url Feb 16, 2022
@joguSD
Copy link
Contributor

joguSD commented Feb 19, 2022

We've definitely seen a lot of confusion around how an aws sso login is cached and reflecting on this I believe most of the confusion stems from the fact that it's being configured at the profile level. It's reasonable that some might expect two profiles that share the same SSO Start URL would be cached separately. However, It doesn't work this way to avoid requiring an aws sso login for every sso_account_id + sso_role_name pair. For now, we'll be keeping this restriction. That is, a single start URL only ever has one active session at a time (think browser cookie jar).

That being said, having this configuration alongside the sso_account_id + sso_role_name inline with the profile pushes the cognitive burden of understanding where an SSO login session boundary lies. Right now it's not too difficult to understand since it's just the start URL but the specifics of deriving an access token may potentially be more complex in the future. This makes something like an explicit section for a named SSO configuration make a lot more sense since it will be very obvious where the session boundaries lie.

For example something similar to @benkehoe's suggestion in aws/aws-cli#5727:

[sso-session session1]
sso_start_url = https://d-2e69cb2b10.awsapps.com/start
sso_region = us-east-2

[sso-session session2]
sso_start_url = https://d-2e69cb2b10.awsapps.com/start
sso_region = us-east-2

Would make it clear that session1 and session2 can be cached independently, while still allowing multiple profiles with different sso_account_id + sso_role_name pairs to share a single cached token.

@benkehoe
Copy link

This would become very relevant if AWS SSO starts supporting scopes and custom expirations for the token. I could imagine a config file like

[sso-session admin]
start_url = https://example.awsapps.com/start
region = us-east-2
scope = admin
duration = 1 hour

[sso-session dev]
start_url = https://example.awsapps.com/start
region = us-east-2
scope = not-admin
duration = 8 hours

[profile admin-A]
sso_session = admin
sso_account_id = 111122223333 # admin in account A
sso_role_name = Administrator

[profile admin-B]
sso_session = admin
sso_account_id = 222233334444
sso_role_name = Administrator

[profile dev-A]
sso_session = dev
sso_account_id = 111122223333
sso_role_name = Developer

[profile dev-B]
sso_session = dev
sso_account_id = 222233334444
sso_role_name = Developer

@villelahdenvuo
Copy link

Thank you for getting me in this rabbit hole. 😄

I noticed that the sso cache expiresAt value is not updated for a while when I run aws sso login and for that reason the SDK fails to load credentials after the session has expired. aws/aws-sdk#531

But reading this thread made me understand better how the SSO works.

@RyanFitzSimmonsAK RyanFitzSimmonsAK added the p3 This is a minor priority issue label Nov 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation This is a problem with documentation. feature-request This issue requests a feature. p3 This is a minor priority issue
Projects
None yet
Development

No branches or pull requests

6 participants