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

Cannot use AWS SSO with assume role when source_profile uses the sso_session option #4757

Closed
3 tasks done
sjakthol opened this issue May 25, 2023 · 16 comments · Fixed by #4820
Closed
3 tasks done

Cannot use AWS SSO with assume role when source_profile uses the sso_session option #4757

sjakthol opened this issue May 25, 2023 · 16 comments · Fixed by #4820
Labels
bug This issue is a bug. closed-for-staleness p1 This is a high priority issue

Comments

@sjakthol
Copy link
Contributor

Checkboxes for prior research

Describe the bug

AWS SDK JS v3 is not able to resolve credentials of a profile with role_arn and source_profile fields when the source profile uses the sso_session option.

SDK version number

@aws-sdk/[email protected]

Which JavaScript Runtime is this issue in?

Node.js

Details of the browser/Node.js/ReactNative version

v18.16.0

Reproduction Steps

  1. Create file called config with following content:
[sso-session mysso]
sso_start_url = https://mysso.awsapps.com/start
sso_region = eu-west-1

[profile first_profile]
sso_session = mysso
sso_account_id = 000000000000
sso_role_name = MyRole

[profile second_profile]
source_profile = first_profile
role_arn = arn:aws:iam::000000000000:role/another_role
  1. Create file called index.js with following content:
import {GetCallerIdentityCommand, STSClient} from "@aws-sdk/client-sts"

const client = new STSClient({});
const cmd = new GetCallerIdentityCommand({})
console.log(await client.send(cmd))
  1. Execute the following command:
env AWS_CONFIG_FILE=./config AWS_REGION=eu-west-1 AWS_PROFILE=second_profile node index.js

Please note that the configuration with placeholder values for sso_start_url, sso_account_id, sso_role_name and role_arn fields is sufficient to reproduce the issue with the SDK (valid values are not required for exception to be thrown). However, to verify potential fixes you'll need to fill in real values in the configuration.

Observed Behavior

AWS SDK JS v3 fails to resolve credentials with validation error on the source profile ("first_profile" in the example):

/example/node_modules/@aws-sdk/credential-provider-sso/dist-cjs/validateSsoProfile.js:8
        throw new property_provider_1.CredentialsProviderError(`Profile is configured with invalid SSO credentials. Required parameters "sso_account_id", ` +
              ^

CredentialsProviderError: Profile is configured with invalid SSO credentials. Required parameters "sso_account_id", "sso_region", "sso_role_name", "sso_start_url". Got sso_session, sso_account_id, sso_role_name
Reference: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html
    at validateSsoProfile (/example/node_modules/@aws-sdk/credential-provider-sso/dist-cjs/validateSsoProfile.js:8:15)
    at resolveSsoCredentials (/example/node_modules/@aws-sdk/credential-provider-ini/dist-cjs/resolveSsoCredentials.js:8:136)
    at resolveProfileData (/example/node_modules/@aws-sdk/credential-provider-ini/dist-cjs/resolveProfileData.js:28:66)
    at resolveAssumeRoleCredentials (/example/node_modules/@aws-sdk/credential-provider-ini/dist-cjs/resolveAssumeRoleCredentials.js:30:55)
    at resolveProfileData (/example/node_modules/@aws-sdk/credential-provider-ini/dist-cjs/resolveProfileData.js:16:80)
    at /example/node_modules/@aws-sdk/credential-provider-ini/dist-cjs/fromIni.js:8:56
    at async coalesceProvider (/example/node_modules/@aws-sdk/property-provider/dist-cjs/memoize.js:14:24)
    at async SignatureV4.credentialProvider (/example/node_modules/@aws-sdk/property-provider/dist-cjs/memoize.js:33:24)
    at async SignatureV4.signRequest (/example/node_modules/@aws-sdk/signature-v4/dist-cjs/SignatureV4.js:87:29)
    at async /example/node_modules/@aws-sdk/middleware-signing/dist-cjs/middleware.js:16:18 {
  tryNextLink: false,
  '$metadata': { attempts: 1, totalRetryDelay: 0 }
}

Expected Behavior

AWS SDK JS v3 is able to resolve credentials for the profile that assumes a role using a profile that for which an SSO session provides some of the SSO related configuration values. Here's how the same config works with AWS CLI v2:

 env AWS_CONFIG_FILE=./config AWS_REGION=eu-west-1 AWS_PROFILE=second_profile aws sts get-caller-identity
{
    "UserId": "AROA3KHW7455TPABCRXHN:botocore-session-1684992352",
    "Account": "000000000000",
    "Arn": "arn:aws:sts::000000000000:assumed-role/another_role/botocore-session-1684992352"
}

Possible Solution

No response

Additional Information/Context

No response

@sjakthol sjakthol added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels May 25, 2023
@yenfryherrerafeliz yenfryherrerafeliz self-assigned this May 25, 2023
sjakthol added a commit to sjakthol/aws-sdk-js-v3 that referenced this issue Jun 10, 2023
…urce_profile

Previously, when credential-provider-ini resolved credentials for a
source profile, it loaded the profile properties, checked if the profile
was an SSO profile, validated that all required sso_* properties were
present and then resolved credentials with credential-provider-sso
module.

When source profile was an SSO profile that did not use an SSO session,
this logic worked fine as the profile must include all the sso_*
properties for SSO to succeed. However, when source profile was an SSO
profile that used an SSO session, credential-provider-ini only resolved
profile properties directly from the profile but not from the related
SSO session.

This caused sso-session based profiles to fail validation as some of the
required sso_* properties are only defined in the referenced sso-session
section. And hence the provider failed to resolve credentials for SSO
session based source_profiles.

This commit changes credential-provider-ini module to not resolve or
validate SSO profile properties but delegate that all to the
credential-provider-sso module that already contains all the logic
needed to load and resolve profile properties and AWS credentials for
both sso-session and non-sso-session based profiles.

Instead of passing profile properties to credential-provider-sso
fromSSO() method, new version only passes the profile name there and
lets the credential-provider-sso module load and resolve the SSO
profile with the logic that already exist in that module.

Unit tests have been adjusted to function with the updated behavior.

Following scenarios were also tested manually:

* Resolve credentials for SSO profile without sso_session option
* Resolve credentials for SSO profile with sso_session option
* Resolve credentials for an assumed role profile whose source profile
  is an SSO profile without sso_session option
* Resolve credentials for an assumed role profile whose source profile
  is an SSO profile with sso_session option

AWS SDK resolved credentials correctly in all four cases.

Fixes aws#4757.
@gastonsilva
Copy link

I need this fixed. I have a terminal cli that uses AWS SDK for several tasks and allows to specify a profile with a --profile argument (similar to AWS cli). In that case fromIni tries to load the credentials and it fails for profiles that use sso-session.
For anyone facing a similar issue, a workaround I found is to use AWS_PROFILE env.
Eg:

AWS_PROFILE=some-sso-session-profile my-cli

@RanVaknin RanVaknin added workaround-available This issue has a work around available. p2 This is a standard priority issue labels Jul 3, 2023
@sjakthol
Copy link
Contributor Author

sjakthol commented Jul 26, 2023

I believe the issue and the workaround you describe are not exactly the same that is described here.

The SDK is able to load credentials for profiles that use sso-session option. Setting AWS_PROFILE to an sso-session based profile works just fine with the default credential provider. There's no issue with that.

This issue is specifically about using an sso-session based profile as a source_profile for a profile with role_arn option (profile that assumes a role using credentials of the source profile). The SDK is unable to resolve the source_profile correctly when the source profile is sso-session based.

If you set AWS_PROFILE to a profile whose source_profile points to sso-session based profile, the SDK fails to resolve credentials regardless of how the SDK is used.

Using AWS_PROFILE variable is not a workaround for the issue with the SDK itself. But it can work around the sso-session profile loading issue in CLI apps depending on how they are using the SDK.

@millermatt
Copy link

@RanVaknin Please remove the workaround-available label. As @sjakthol notes, the stated work around does not work for the issue described here.

@asibs
Copy link

asibs commented Aug 11, 2023

I am also experiencing this issue. I get the following error if ~/.aws/config has profiles which use sessions:

CredentialsProviderError: Profile is configured with invalid SSO credentials. Required parameters "sso_account_id", "sso_region", "sso_role_name", "sso_start_url". Got sso_session, sso_account_id, sso_role_name, region, output

This format does not work:

[profile connection-platform-qa]
sso_session = default
sso_account_id = 123
sso_role_name = RoleA
region = eu-west-2
output = json
[sso-session default]
sso_start_url = https://mysso.awsapps.com/start#/
sso_region = eu-west-2
sso_registration_scopes = sso:account:access

This format (which I believe is equivalent, but does not use sessions) works fine:

[profile connection-platform-qa]
sso_start_url = https://mysso.awsapps.com/start#/
sso_region = eu-west-2
sso_account_id = 123
sso_role_name = RoleA
region = eu-west-2
output = json

@yenfryherrerafeliz
Copy link
Contributor

Hi @sjakthol, @gastonsilva, @asibs, this seems to be a limitation for JS SDK v3, where if we use a profile that references to another profile that uses sso_session then, the required fields for sso will not be resolved from that referenced profile, and hence it will complain about it. I tested this with JS and PHP SDKs and I got the same issue.
For example, if we define our profiles as follow:

[sso-session mysso]
sso_start_url = https://mysso.awsapps.com/start
sso_region = eu-west-1

[profile first_profile]
sso_session = mysso
sso_account_id = 000000000000
sso_role_name = MyRole
role_arn = arn:aws:iam::000000000000:role/another_role

and we use the profile first_profile then, we will not have any issues.

I will mark this issue with a needs-review label so we can analyze this further.

Code to reproduce:

import {GetCallerIdentityCommand, STSClient} from "@aws-sdk/client-sts"

process.env.AWS_CONFIG_FILE="../config"
process.env.AWS_PROFILE="second_profile"
process.env.AWS_SDK_LOAD_CONFIG=1
const client = new STSClient({
    region : "us-east-2"
});
const cmd = new GetCallerIdentityCommand({})
console.log(await client.send(cmd))

config

[sso-session mysso]
sso_start_url = https://mysso.awsapps.com/start
sso_region = eu-west-1

[profile first_profile]
sso_session = mysso
sso_account_id = 000000000000
sso_role_name = MyRole

[profile second_profile]
source_profile = first_profile
role_arn = arn:aws:iam::000000000000:role/another_role

Thanks!

@yenfryherrerafeliz yenfryherrerafeliz added needs-review This issue/pr needs review from an internal developer. p2 This is a standard priority issue queued This issues is on the AWS team's backlog and removed needs-triage This issue or PR still needs to be triaged. p2 This is a standard priority issue needs-review This issue/pr needs review from an internal developer. labels Aug 22, 2023
@sjakthol
Copy link
Contributor Author

sjakthol commented Oct 7, 2023

@yenfryherrerafeliz: Any chance to get some eyes from the team to check this issue? There's an open pull request with a fix to this issue available: #4820. Would be great if you or someone else from the SDK team would have some time to review that. Thanks!

@yenfryherrerafeliz yenfryherrerafeliz removed their assignment Nov 7, 2023
sjakthol added a commit to sjakthol/cfn-monitor that referenced this issue Nov 17, 2023
AWS SDK JS v3 is unable to resolve credentials when a source_profile
points to a profile using sso_session option:
aws/aws-sdk-js-v3#4757.

This commit monkeypatches the problematic function, catches failure and
tries to load credentials again using fromSSO() method that has more
extensive logic for resolving credentials for SSO profiles.

Versions of involved packages have been pinned to exact versions to
avoid sudden breakage if the methods in question change.
sjakthol added a commit to sjakthol/cfn-monitor that referenced this issue Nov 17, 2023
AWS SDK JS v3 is unable to resolve credentials when a source_profile
points to a profile using sso_session option:
aws/aws-sdk-js-v3#4757.

This commit monkeypatches the problematic function, catches failure and
tries to load credentials again using fromSSO() method that has more
extensive logic for resolving credentials for SSO profiles.

Versions of involved packages have been pinned to exact versions to
avoid sudden breakage if the methods in question change.
sjakthol added a commit to sjakthol/cfn-execute-change-set that referenced this issue Nov 17, 2023
AWS SDK JS v3 is unable to resolve credentials when a source_profile
points to a profile using sso_session option:
aws/aws-sdk-js-v3#4757.

This commit monkeypatches the problematic function, catches failure and
tries to load credentials again using fromSSO() method that has more
extensive logic for resolving credentials for SSO profiles.

Versions of involved packages have been pinned to exact versions to
avoid sudden breakage if the methods in question change.
sjakthol added a commit to sjakthol/cfn-monitor that referenced this issue Nov 17, 2023
AWS SDK JS v3 is unable to resolve credentials when a source_profile
points to a profile using sso_session option:
aws/aws-sdk-js-v3#4757.

This commit monkeypatches the problematic function, catches failure and
tries to load credentials again using fromSSO() method that has more
extensive logic for resolving credentials for SSO profiles.

Versions of involved packages have been pinned to exact versions to
avoid sudden breakage if the methods in question change.
sjakthol added a commit to sjakthol/cfn-execute-change-set that referenced this issue Nov 17, 2023
AWS SDK JS v3 is unable to resolve credentials when a source_profile
points to a profile using sso_session option:
aws/aws-sdk-js-v3#4757.

This commit monkeypatches the problematic function, catches failure and
tries to load credentials again using fromSSO() method that has more
extensive logic for resolving credentials for SSO profiles.

Versions of involved packages have been pinned to exact versions to
avoid sudden breakage if the methods in question change.
@pcholakov
Copy link

Gentle bump – any chance someone from the SDK team can take a look at the proposed fix in #4820?

@RanVaknin
Copy link
Contributor

Hi everyone on the thread. I appreciate your patience on this. I will re-review this with the team and see if we can assign a higher priority to this.

Thanks again,
Ran~

@RanVaknin RanVaknin added p1 This is a high priority issue and removed workaround-available This issue has a work around available. p2 This is a standard priority issue labels Jan 29, 2024
sjakthol added a commit to sjakthol/aws-sdk-js-v3 that referenced this issue Jan 29, 2024
…urce_profile

Previously, when credential-provider-ini resolved credentials for a
source profile, it loaded the profile properties, checked if the profile
was an SSO profile, validated that all required sso_* properties were
present and then resolved credentials with credential-provider-sso
module.

When source profile was an SSO profile that did not use an SSO session,
this logic worked fine as the profile must include all the sso_*
properties for SSO to succeed. However, when source profile was an SSO
profile that used an SSO session, credential-provider-ini only resolved
profile properties directly from the profile but not from the related
SSO session.

This caused sso-session based profiles to fail validation as some of the
required sso_* properties are only defined in the referenced sso-session
section. And hence the provider failed to resolve credentials for SSO
session based source_profiles.

This commit changes credential-provider-ini module to not resolve or
validate SSO profile properties but delegate that all to the
credential-provider-sso module that already contains all the logic
needed to load and resolve profile properties and AWS credentials for
both sso-session and non-sso-session based profiles.

Instead of passing profile properties to credential-provider-sso
fromSSO() method, new version only passes the profile name there and
lets the credential-provider-sso module load and resolve the SSO
profile with the logic that already exist in that module.

Unit tests have been adjusted to function with the updated behavior.

Following scenarios were also tested manually:

* Resolve credentials for SSO profile without sso_session option
* Resolve credentials for SSO profile with sso_session option
* Resolve credentials for an assumed role profile whose source profile
  is an SSO profile without sso_session option
* Resolve credentials for an assumed role profile whose source profile
  is an SSO profile with sso_session option

AWS SDK resolved credentials correctly in all four cases.

Fixes aws#4757.
sjakthol added a commit to sjakthol/aws-sdk-js-v3 that referenced this issue Jan 29, 2024
…urce_profile

Previously, when credential-provider-ini resolved credentials for a
source profile, it loaded the profile properties, checked if the profile
was an SSO profile, validated that all required sso_* properties were
present and then resolved credentials with credential-provider-sso
module.

When source profile was an SSO profile that did not use an SSO session,
this logic worked fine as the profile must include all the sso_*
properties for SSO to succeed. However, when source profile was an SSO
profile that used an SSO session, credential-provider-ini only resolved
profile properties directly from the profile but not from the related
SSO session.

This caused sso-session based profiles to fail validation as some of the
required sso_* properties are only defined in the referenced sso-session
section. And hence the provider failed to resolve credentials for SSO
session based source_profiles.

This commit changes credential-provider-ini module to not resolve or
validate SSO profile properties but delegate that all to the
credential-provider-sso module that already contains all the logic
needed to load and resolve profile properties and AWS credentials for
both sso-session and non-sso-session based profiles.

Instead of passing profile properties to credential-provider-sso
fromSSO() method, new version only passes the profile name there and
lets the credential-provider-sso module load and resolve the SSO
profile with the logic that already exist in that module.

Unit tests have been adjusted to function with the updated behavior.

Following scenarios were also tested manually:

* Resolve credentials for SSO profile without sso_session option
* Resolve credentials for SSO profile with sso_session option
* Resolve credentials for an assumed role profile whose source profile
  is an SSO profile without sso_session option
* Resolve credentials for an assumed role profile whose source profile
  is an SSO profile with sso_session option

AWS SDK resolved credentials correctly in all four cases.

Fixes aws#4757.
siddsriv pushed a commit that referenced this issue Jan 30, 2024
…urce_profile (#4820)

Previously, when credential-provider-ini resolved credentials for a
source profile, it loaded the profile properties, checked if the profile
was an SSO profile, validated that all required sso_* properties were
present and then resolved credentials with credential-provider-sso
module.

When source profile was an SSO profile that did not use an SSO session,
this logic worked fine as the profile must include all the sso_*
properties for SSO to succeed. However, when source profile was an SSO
profile that used an SSO session, credential-provider-ini only resolved
profile properties directly from the profile but not from the related
SSO session.

This caused sso-session based profiles to fail validation as some of the
required sso_* properties are only defined in the referenced sso-session
section. And hence the provider failed to resolve credentials for SSO
session based source_profiles.

This commit changes credential-provider-ini module to not resolve or
validate SSO profile properties but delegate that all to the
credential-provider-sso module that already contains all the logic
needed to load and resolve profile properties and AWS credentials for
both sso-session and non-sso-session based profiles.

Instead of passing profile properties to credential-provider-sso
fromSSO() method, new version only passes the profile name there and
lets the credential-provider-sso module load and resolve the SSO
profile with the logic that already exist in that module.

Unit tests have been adjusted to function with the updated behavior.

Following scenarios were also tested manually:

* Resolve credentials for SSO profile without sso_session option
* Resolve credentials for SSO profile with sso_session option
* Resolve credentials for an assumed role profile whose source profile
  is an SSO profile without sso_session option
* Resolve credentials for an assumed role profile whose source profile
  is an SSO profile with sso_session option

AWS SDK resolved credentials correctly in all four cases.

Fixes #4757.
@chlorophant
Copy link

Is there any reason I would suddenly start experiencing this issue? As of today?

@nick-kang
Copy link

Reverting the sdk version from 3.502.0 to 3.501.0 fixed it for me.

@kuhe kuhe reopened this Jan 30, 2024
@kuhe
Copy link
Contributor

kuhe commented Jan 30, 2024

@chlorophant @nick-kang Could you show your configuration of profiles and the error message?

@chlorophant
Copy link

@chlorophant @nick-kang Could you show your configuration of profiles and the error message?

My Profile looks like:

[profile dev]
sso_session = mysso
sso_account_id = 000000000000
sso_role_name = MyRole

[sso-session mysso]
sso_start_url = https://mysso.awsapps.com/start#
sso_region = us-east-2
sso_registration_scopes = sso:account:access

As for the error, it presented itself when using the aws-sdk bedrock-runtime package in my app

@kuhe
Copy link
Contributor

kuhe commented Jan 30, 2024

What is the error message in your case? And you are using the default credential lookup chain by initializing the client with no credential configuration?

@sjakthol
Copy link
Contributor Author

sjakthol commented Jan 30, 2024

I am able to reproduce the issue with index.js sample code from the issue description and first_profile of the example configuration.

My guess is that the following extra check added yesterday in d27301d is causing the trouble here:

if (!ssoStartUrl || !ssoAccountId || !ssoRegion || !ssoRoleName) {
throw new CredentialsProviderError(
"Skipping SSO provider in default chain (inputs do not include SSO fields)."
);
}

Before that check, the default provider would always call @aws-sdk/credential-provider-sso fromSSO for the profile that was being resolved regardless of its options. fromSSO has extra logic that is missing from the new check to resolve ssoStartUrl and ssoRegion variables from the linked ssoSession instead of expecting them to be defined in the profile directly.

Now with that extra check in place, the default provider no longer invokes fromSSO method for profiles that use the ssoSession option to provide ssoStartUrl and ssoRegion options. If all SSO related options are not defined in the profile directly, the provider moves over to @aws-sdk/credential-provider-ini fromIni method as the next provider in the chain. Unfortunately that provider is not able to resolve ssoSession based profiles and thus credential resolution fails.

This is not exactly the same issue that was originally discussed here. But it's actually very close and the fix for this issue also fixes this fresh issue by accident.

The commit that was meant to fix this issue (b87f5e0) was not part of SDK version 3.502.0. I did not notice this fresh issue in my testing yesterday as the fix I made here also happened to fix the issue introduced by d27301d. As part of b87f5e0, fromIni method got the ability to resolve credentials for ssoSession backed profiles. And now that ssoSession backed profiles fall through to fromIni based resolution, it works when commit b87f5e0 is in (next SDK release) but fails if that's missing (latest SDK release).

Anyway, the fix from commit b87f5e0 to this fresh issue is a pure accident. Probably a better fix for the fresh issue is to amend the check at

if (!ssoStartUrl || !ssoAccountId || !ssoRegion || !ssoRoleName) {
throw new CredentialsProviderError(
"Skipping SSO provider in default chain (inputs do not include SSO fields)."
);
}
const { fromSSO } = await import("@aws-sdk/credential-provider-sso");
return fromSSO(init)();
to pass profiles using ssoSession option to fromSSO method as well. This would restore the earlier logic where ssoSession backed profiles are resolved with the fromSSO method.

@kuhe
Copy link
Contributor

kuhe commented Jan 30, 2024

I've opened a PR to modify the skip condition in the defaultProvider #5746.

The defaultProvider chain contains two (2) paths to the SSO provider. One is at the top level, if the user inputs SSO related fields in code. The second is in a later step via the INI provider.

With the added skip-check, it was incorrectly abandoning the direct SSO provider if any single field was missing. This is incompatible because there are two different sets of information that constitute a valid SSO initialization, one of which is the session based configuration. If the profile still had SSO information, the second path to the SSO provider via INI would still work.

@kuhe kuhe added pending-release This issue will be fixed by an approved PR that hasn't been released yet. closing-soon This issue will automatically close in 4 days unless further comments are made. and removed queued This issues is on the AWS team's backlog pending-release This issue will be fixed by an approved PR that hasn't been released yet. labels Jan 30, 2024
@github-actions github-actions bot added closed-for-staleness and removed closing-soon This issue will automatically close in 4 days unless further comments are made. labels Feb 4, 2024
@github-actions github-actions bot closed this as completed Feb 4, 2024
Copy link

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs and link to relevant comments in this thread.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 18, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug This issue is a bug. closed-for-staleness p1 This is a high priority issue
Projects
None yet
10 participants