Open nbbeeken opened 1 year ago
Hi @nbbeeken, I can confirm that the default STS client, used internally to resolve credentials with web identity token, does not consider the AWS_DEFAULT_REGION variable to populate the region, instead it considers just either a region passed as parameter or the default one which is us-east-1. This can be confirmed in the following implementation here. However, I need to discuss with the team regarding if this is the expected behavior or not. As workaround, you have the option to explicitly provide the region you want the STS client to use, as follow:
import {ListBucketsCommand, S3Client} from "@aws-sdk/client-s3";
import {fromNodeProviderChain} from "@aws-sdk/credential-providers";
const credProvider = fromNodeProviderChain({
clientConfig: {
region: "YOUR-DESIRED-STS-REGION"
}
});
const client = new S3Client({
region: "us-east-2",
credentials: credProvider
})
const response = await client.send(new ListBucketsCommand({}));
console.log(response)
Please let me know if that helps!
Thanks!
Thank you for looking into this @yenfryherrerafeliz! As a library author providing direct control over these options means adding more knobs to our public API (ex. a pass-through object for users to provide their own options). It would be nice to avoid the need for bespoke controls like this when the docs point to these environment variables as the proper controls.
Thanks for the code sample, good to know I am on the right track with the workaround! You can see https://github.com/mongodb/node-mongodb-native/pull/3831 we have translated the environment variables to options in the MongoDB driver since we need this to apply to existing versions of the SDK.
This is definitely surprising behavior. At the very least, this needs to be documented. From what I can tell, it's not documented anywhere.
I would go a step further and say that this is documented as "supported", and the fact that it does not work is a bug. Please at least update the documentation to reflect the actual behavior
I verified from internal documentation that STS Regional Endpoints are not required to be supported in major version bump
SDK major version bumps SHOULD ignore the STS Regional Endpoints option, and only resolve STS endpoints to the partition's STS regional endpoints. A major version bump SDK MAY choose to keep the STS Regional Endpoints option, but the option's default value must be
regional
.
I'll check the behavior in JS SDK v2 vs v3 in subsequent comments.
Behavior in JS SDK v2
import AWS from "aws-sdk"; // v2.1659.0
const client = new AWS.STS();
const req = client.getCallerIdentity();
await req.promise();
console.log(req.httpRequest.endpoint.href);
The legacy and regional endpoints are different, as required.
$ AWS_REGION=us-west-2 AWS_STS_REGIONAL_ENDPOINTS=legacy node index.v2.mjs
https://sts.amazonaws.com/
$ AWS_REGION=us-west-2 AWS_STS_REGIONAL_ENDPOINTS=regional node index.v2.mjs
https://sts.us-west-2.amazonaws.com/
The legacy and regional endpoints are same, as required.
$ AWS_REGION=us-west-2-fips AWS_STS_REGIONAL_ENDPOINTS=legacy node index.v2.mjs
https://sts-fips.us-west-2.amazonaws.com/
$ AWS_REGION=us-west-2-fips AWS_STS_REGIONAL_ENDPOINTS=regional node index.v2.mjs
https://sts-fips.us-west-2.amazonaws.com/
Behavior in JS SDK v3
import { STS, GetCallerIdentityCommand } from "@aws-sdk/client-sts"; // v3.614.0
import { getEndpointFromInstructions } from "@smithy/middleware-endpoint";
const client = new STS();
const command = new GetCallerIdentityCommand();
const endpoint = await getEndpointFromInstructions(
command.input,
GetCallerIdentityCommand,
client.config
);
console.log(endpoint.url.href);
Ignores AWS_STS_REGIONAL_ENDPOINTS
and returns regional
behavior, as required by major version.
$ AWS_REGION=us-west-2 AWS_STS_REGIONAL_ENDPOINTS=legacy node index.v3.mjs
https://sts.us-west-2.amazonaws.com/
$ AWS_REGION=us-west-2 AWS_STS_REGIONAL_ENDPOINTS=regional node index.v3.mjs
https://sts.us-west-2.amazonaws.com/
Ignores AWS_STS_REGIONAL_ENDPOINTS
and returns regional
behavior, as required by major version.
$ AWS_REGION=us-west-2-fips AWS_STS_REGIONAL_ENDPOINTS=legacy node index.v3.mjs
https://sts-fips.us-west-2.amazonaws.com/
$ AWS_REGION=us-west-2-fips AWS_STS_REGIONAL_ENDPOINTS=regional node index.v3.mjs
https://sts-fips.us-west-2.amazonaws.com/
I would go a step further and say that this is documented as "supported", and the fact that it does not work is a bug. Please at least update the documentation to reflect the actual behavior
I've created an internal ticket at V1453005105 to update the Developer Guide, and have followed up on the internal ticket. This issue can be resolved once Developer Guide is updated.
Hey @trivikr thanks for taking a look at this! The original issue was focused on the @aws-sdk/credential-providers
package and the fromNodeProviderChain
API it provides, which isn't mentioned in your code snippets. It still appears as though that API does not respond to the environment variables, is that intentional?
@trivikr Here is a code snippet showing the behavior change from v2 to v3, it might be worth it to mention in the v2 to v3 differences document:
v3 sample
const { S3Client, ListBucketsCommand } = require("@aws-sdk/client-s3");
const { fromTokenFile } = require("@aws-sdk/credential-providers");
const listBuckets = async () => {
try {
const s3Client = new S3Client({
credentials: fromTokenFile(),
});
const data = await s3Client.send(new ListBucketsCommand({}));
console.log("Success", data.Buckets);
} catch (err) {
console.log("Error", err);
}
};
listBuckets();
v3 behavior: ignores env variables (must use fromTokenFile({region: process.env.AWS_REGION})
for example).
v2 sample:
const AWS = require('aws-sdk');
const credentials = new AWS.TokenFileWebIdentityCredentials();
const s3 = new AWS.S3({ credentials });
s3.listBuckets((err, data) => {
if (err) {
console.log('Error', err);
} else {
console.log('Bucket List', data.Buckets);
}
});
v2 behavior: does NOT ignore env vars
Checkboxes for prior research
Describe the bug
When invoking
fromNodeProviderChain
using IAM AssumeRoleWithWebIdentity I expect environment variablesAWS_REGION
/AWS_DEFAULT_REGION
/AWS_STS_REGIONAL_ENDPOINTS
to control the region that theSTSClient
uses to send the http request. However, it can be observed that the request is always routed tous-east-1
unless the region is programmatically set.Documentation References:
SDK version number
@aws-sdk/credential-providers@3.391.0
Which JavaScript Runtime is this issue in?
Node.js
Details of the browser/Node.js/ReactNative version
v20.2.0
Reproduction Steps
Running the
fromNodeProviderChain
function with http debugging turned on, like so:Observed Behavior
Logs
to the terminal, indicating the region variable and the sts_regional_endpoints are not having the desired effect.
Expected Behavior
The
AWS_REGION
variable along with theAWS_STS_REGIONAL_ENDPOINTS
setting should have made the API call contactsts.us-west-2.amazonaws.com:443
Possible Solution
No response
Additional Information/Context
No response