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

SharedIniFileCredentials/AWS_STS_REGIONAL_ENDPOINTS=regional fails if there's no '[default]' profile #3418

Closed
rix0rrr opened this issue Aug 27, 2020 · 2 comments
Labels
bug This issue is a bug. investigating Issue has been looked at and needs deep dive work by OSDS.

Comments

@rix0rrr
Copy link
Contributor

rix0rrr commented Aug 27, 2020

Describe the bug

When using SharedIniFileCredentials with:

  • A profile name supplied as argument (not via AWS_PROFILE).
  • A profile that uses assumerole credentials
  • AWS_STS_REGIONAL_ENDPOINTS=regional

Then the credential retrieval fails if there's not a [default] profile with a region (even if both profiles involved in the AssumeRole operation do have a region in them). I'm assuming if there is a [default] profile then the provider will use the wrong region--I did not try to confirm that.

The problem does not appear when I configure AWS_PROFILE which makes me think there's some code that's forgetting to pass on the profile constructor argument to the right object.

Is the issue in the browser/Node.js?
Node.js

If on Node.js, are you running this on AWS Lambda?
No

Details of the browser/Node.js version
v12.12.0

SDK version number
2.713.0

To Reproduce (observed behavior)

The following code:

process.env.AWS_SDK_LOAD_CONFIG = '1';
process.env.AWS_STS_REGIONAL_ENDPOINTS = 'regional';

const AWS = require('aws-sdk');

const creds = new AWS.SharedIniFileCredentials({ profile: 'huijbers-admin-role' });

const chain = new AWS.CredentialProviderChain([creds]);
chain.resolvePromise().then(console.log);

Fails when given the following config:

============ ~/.aws/credentials =======================
[huijbers-admin-user]
aws_access_key_id = AKIA****************
aws_secret_access_key = YASbc2*****************

[huijbers-admin-role]
role_arn = arn:aws:iam::993655754359:role/Assumable
source_profile = huijbers-admin-user

============ ~/.aws/config =======================
[profile huijbers-admin-role]
region = eu-west-1

[profile huijbers-admin-user]
region = eu-west-1

The error is the following:

(node:66546) UnhandledPromiseRejectionWarning: ConfigError: Missing region in config
    at Request.optInRegionalEndpoint (/Users/huijbers/Temp/repro/node_modules/aws-sdk/lib/services/sts.js:75:30)
    at Request.callListeners (/Users/huijbers/Temp/repro/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
    at Request.emit (/Users/huijbers/Temp/repro/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
    at Request.emit (/Users/huijbers/Temp/repro/node_modules/aws-sdk/lib/request.js:688:14)
    at Request.transition (/Users/huijbers/Temp/repro/node_modules/aws-sdk/lib/request.js:22:10)
    at AcceptorStateMachine.runTo (/Users/huijbers/Temp/repro/node_modules/aws-sdk/lib/state_machine.js:14:12)
    at Request.runTo (/Users/huijbers/Temp/repro/node_modules/aws-sdk/lib/request.js:408:15)
    at Request.send (/Users/huijbers/Temp/repro/node_modules/aws-sdk/lib/request.js:372:10)
    at features.constructor.makeRequest (/Users/huijbers/Temp/repro/node_modules/aws-sdk/lib/service.js:205:27)
    at features.constructor.svc.<computed> [as assumeRole] (/Users/huijbers/Temp/repro/node_modules/aws-sdk/lib/service.js:677:23)

And succeeds when the following is added to ~/.aws/config:

[default]
region = eu-west-1

Expected behavior
I would have expected the region from the huijbers-admin-role profile to be used.

Additional context

Originally reported in aws/aws-cdk#9937

@rix0rrr rix0rrr added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Aug 27, 2020
@rix0rrr
Copy link
Contributor Author

rix0rrr commented Aug 27, 2020

Isn't the solution to change this:

var sts = new STS({
credentials: sourceCredentials,
httpOptions: this.httpOptions
});

To read:

    var sts = new STS({
      region: roleProfile['region'],
      credentials: sourceCredentials,
      httpOptions: this.httpOptions
    });

@ajredniwja ajredniwja added investigating Issue has been looked at and needs deep dive work by OSDS. and removed needs-triage This issue or PR still needs to be triaged. labels Aug 27, 2020
@rix0rrr
Copy link
Contributor Author

rix0rrr commented Aug 28, 2020

Oh, what I proposed won't actually work because of this piece of code:

aws-sdk-js/lib/util.js

Lines 969 to 974 in 5ae5a7d

for (var i = 0, profileNames = Object.keys(profilesFromConfig); i < profileNames.length; i++) {
profiles[profileNames[i]] = profilesFromConfig[profileNames[i]];
}
for (var i = 0, profileNames = Object.keys(profilesFromCreds); i < profileNames.length; i++) {
profiles[profileNames[i]] = profilesFromCreds[profileNames[i]];
}

Given:

========== config ===============
[profile foo]
region = us-east-1

========= credentials ==============
[foo]
aws_access_key_id = 123

The "config" profile will be completely overwritten (not merged) by the credentials profile and the end result will be:

{
  "foo": {
    "aws_access_key_id": "123"
  }
}

So "region" will have been dropped from it.

Is this on purpose?

rix0rrr added a commit to aws/aws-cdk that referenced this issue Aug 28, 2020
This works around a bug in the AWS SDK for JS that only surfaced when
we switched to `AWS_STS_REGIONAL_ENDPOINTS=regional`, requiring a
`[default]` profile with a region for all users.

The bug was that the INI-file AssumeRole provider would ignore the
region in the profile, and always fall back to the region in:

* The profile specified using `$AWS_PROFILE` (which we don't use).
* Otherwise the region in the `[default]` profile (which a user
  may or may not have).

Traditionally it didn't really matter whether the STS client got a
region or not because it would always connect to `us-east-1` no matter
what, but when we switched to `AWS_STS_REGIONAL_ENDPOINTS=regional`, it
became illegal to not have a region.

Fix the upstream bug by basically replicating the important parts of
`SharedIniFileCredentials` of the AWS SDK in our codebase and patching
the bug.

Reported upstreeam as aws/aws-sdk-js#3418
mergify bot pushed a commit to aws/aws-cdk that referenced this issue Aug 28, 2020
This works around a bug in the AWS SDK for JS that only surfaced when
we switched to `AWS_STS_REGIONAL_ENDPOINTS=regional`, requiring a
`[default]` profile with a region for all users.

The bug was that the INI-file AssumeRole provider would ignore the
region in the profile, and always fall back to the region in:

* The profile specified using `$AWS_PROFILE` (which we don't use).
* Otherwise the region in the `[default]` profile (which a user
  may or may not have).

Traditionally it didn't really matter whether the STS client got a
region or not because it would always connect to `us-east-1` no matter
what, but when we switched to `AWS_STS_REGIONAL_ENDPOINTS=regional`, it
became illegal to not have a region.

Fix the upstream bug by basically replicating the important parts of
`SharedIniFileCredentials` of the AWS SDK in our codebase and patching
the bug.

Reported upstreeam as aws/aws-sdk-js#3418

Fixes #9937


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
@rix0rrr rix0rrr closed this as completed Dec 11, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This issue is a bug. investigating Issue has been looked at and needs deep dive work by OSDS.
Projects
None yet
Development

No branches or pull requests

2 participants