Repository: aws/aws-cli

Issue:
[v2] `aws sso login` should not require a fully-configured profile
Currently, `aws sso login` operates on a particular profile, even [requiring that `sso_account_id` and `sso_role_name` be present in the profile](https://github.com/aws/aws-cli/blob/f2788558422dac42a5ebe37c7e5a3d24b19dee9f/awscli/customizations/sso/login.py#L32) even though it does not use them, [only fetching the token](https://github.com/aws/aws-cli/blob/f2788558422dac42a5ebe37c7e5a3d24b19dee9f/awscli/customizations/sso/utils.py#L45) (as it should, because AWS SSO-capable SDKs can use the token to get credentials for the appropriate account and role).

At the very least, `sso_account_id` and `sso_role_name` should be removed from the list of required config variables, which would allow a profile like:
```ini
[profile login]
sso_start_url = https://d-2e69cb2b10.awsapps.com/start
sso_region = us-east-2
```
and then `aws sso login --profile login` would just work without requiring a specific account and role that won't be used anyway.

This matters because not all users in an organization have the same permissions, so there's not a good way to provide them all with a single working config file to start from.

A better alternative would be to have AWS SSO configuration be explicit in the config file, perhaps with a new section type:
```ini
[sso default]
sso_start_url = https://d-2e69cb2b10.awsapps.com/start
sso_region = us-east-2
```

Or, `aws sso login` should check the configured profiles and if there's only one AWS SSO configuration (i.e., they all use the same start URL and region), it should just use that.

I've implemented the latter in [`aws-sso-util login`](https://github.com/benkehoe/aws-sso-util#logging-in-and-out).


Discussion:
I think relaxing the required configurations for a 'properly' configured profile to perform an `aws sso login` makes sense, and has some nice properties around default configuration as you mention. Providing a default `.aws/config` that has the `sso_start_url` and `sso_region` preloaded makes it easier to run `aws configure sso` as it can do some of the profile scanning you mention for the auto-completions. 

Rather than some sso specific configuration defaults section I think I'm still more inclined to go for a profile inheritance approach in the long term. I could see something like this being just as convenient in most cases but more generally applicable outside of the sso use case:

**For clarity, this configuration does not work as of writing but `base_profile` (or similar) is something we'd like to do**

```ini
[default]
sso_start_url = https://d-1234abcd.awsapps.com/start
sso_region = us-east-2
region = us-east-2
output = json

[profile RoleA]
base_profile = default
sso_account_id = 1234
sso_role_name = 'RoleA'

[profile RoleB]
base_profile = default
sso_account_id = 1234
sso_role_name = 'RoleB'
```

Then `aws sso login` without a profile would work, and profiles that want to share configuration can. This also seems like it would extend to multiple directories a bit more naturally than an additional, explicit `sso` section.
Instead of a new attribute `base_profile`, is this functionality that the already-existing `source_profile` could provide? 
@joguSD With 100s of accounts and dozens of roles, I specifically choose not to have a valid default profile, so that I always explicitly have to set a profile name, and if I haven't, I get an error. Additionally, not all my profiles are SSO profiles.

I think there's danger in using the `default` section to mean *both* default values to be used by other sections, and a default profile that the CLI/SDKs will pick up.

The thing about AWS SSO is, I guess, it sort of feels like a separate layer before the profiles.
@lorengordon `source_profile` right now is only used as a credential source for an assume role chain. I'd have to think it through a little more but my gut says that inheriting other aspects of the `source_profile` is probably a breaking change in some cases.

@benkehoe Do note that in the example I gave the `default` profile isn't completely valid as it doesn't have a complete configuration for credentials. 

~~I suppose it could work on an EC2 instance where IMDS is available but I believe that's already the case even without a configuration file when using the V2 CLI. It's unlikely someone would be using SSO in that scenario anyways~~. **EDIT**: Actually, it fails validation due to the incorrect SSO profile so it wouldn't be usable for any service calls as is.

I didn't intend for `default` to mean "defaults for other sections". That linkage requires an explicit note in the profile that's inheriting it (e.g. `base_profile` or something). I could also write that example like:

```
[profile base]
sso_start_url = https://d-1234abcd.awsapps.com/start
sso_region = us-east-2
region = us-east-2
output = json

[profile RoleA]
base_profile = base
sso_account_id = 1234
sso_role_name = 'RoleA'

[profile RoleB]
base_profile = base
sso_account_id = 1234
sso_role_name = 'RoleB'
```

The only downside is that now `aws sso login` wouldn't work without a profile.

Resolving patch:
diff --git a/awscli/customizations/sso/login.py b/awscli/customizations/sso/login.py
--- a/awscli/customizations/sso/login.py
+++ b/awscli/customizations/sso/login.py
@@ -26,14 +26,15 @@ class LoginCommand(BasicCommand):
         'Retrieves and caches an AWS SSO access token to exchange for AWS '
         'credentials. To login, the requested profile must have first been '
         'setup using ``aws configure sso``. Each time the ``login`` command '
-        'is called, a new SSO access token will be retrieved.'
+        'is called, a new SSO access token will be retrieved. Please note '
+        'that only one login session can be active for a given SSO Start URL '
+        'and creating multiple profiles does not allow for multiple users to '
+        'be authenticated against the same SSO Start URL.'
     )
     ARG_TABLE = []
     _REQUIRED_SSO_CONFIG_VARS = [
         'sso_start_url',
         'sso_region',
-        'sso_role_name',
-        'sso_account_id',
     ]
 
     def _run_main(self, parsed_args, parsed_globals):


Test patch:
diff --git a/tests/functional/sso/test_login.py b/tests/functional/sso/test_login.py
--- a/tests/functional/sso/test_login.py
+++ b/tests/functional/sso/test_login.py
@@ -145,6 +145,21 @@ def test_login_no_sso_configuration(self):
             stderr
         )
 
+    def test_login_minimal_sso_configuration(self):
+        content = (
+            '[default]\n'
+            'sso_start_url={start_url}\n'
+            'sso_region={sso_region}\n'
+        ).format(start_url=self.start_url, sso_region=self.sso_region)
+        self.set_config_file_content(content=content)
+        self.add_oidc_workflow_responses(self.access_token)
+        self.run_cmd('sso login')
+        self.assert_used_expected_sso_region(expected_region=self.sso_region)
+        self.assert_cache_contains_token(
+            start_url=self.start_url,
+            expected_token=self.access_token
+        )
+
     def test_login_partially_missing_sso_configuration(self):
         content = (
             '[default]\n'
@@ -158,6 +173,8 @@ def test_login_partially_missing_sso_configuration(self):
         )
         self.assertIn('sso_region', stderr)
         self.assertNotIn('sso_start_url', stderr)
+        self.assertNotIn('sso_account_id', stderr)
+        self.assertNotIn('sso_role_name', stderr)
 
     def test_token_cache_datetime_format(self):
         self.add_oidc_workflow_responses(self.access_token)