Skip to content

Commit 4e56666

Browse files
committed
fix(credential-providers): use modified region resolver for inner STS clients
1 parent b8da1d2 commit 4e56666

File tree

11 files changed

+236
-28
lines changed

11 files changed

+236
-28
lines changed

clients/client-sts/src/defaultStsRoleAssumers.ts

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Please do not touch this file. It's generated from template in:
33
// https://github.com/aws/aws-sdk-js-v3/blob/main/codegen/smithy-aws-typescript-codegen/src/main/resources/software/amazon/smithy/aws/typescript/codegen/sts-client-defaultStsRoleAssumers.ts
44
import { setCredentialFeature } from "@aws-sdk/core/client";
5+
import { stsRegionDefaultResolver } from "@aws-sdk/region-config-resolver";
56
import type { CredentialProviderOptions } from "@aws-sdk/types";
67
import { AwsCredentialIdentity, Logger, Provider } from "@smithy/types";
78

@@ -28,8 +29,6 @@ export type RoleAssumer = (
2829
params: AssumeRoleCommandInput
2930
) => Promise<AwsCredentialIdentity>;
3031

31-
const ASSUME_ROLE_DEFAULT_REGION = "us-east-1";
32-
3332
interface AssumedRoleUser {
3433
/**
3534
* The ARN of the temporary security credentials that are returned from the AssumeRole action.
@@ -63,19 +62,21 @@ const getAccountIdFromAssumedRoleUser = (assumedRoleUser?: AssumedRoleUser) => {
6362
const resolveRegion = async (
6463
_region: string | Provider<string> | undefined,
6564
_parentRegion: string | Provider<string> | undefined,
66-
credentialProviderLogger?: Logger
65+
credentialProviderLogger?: Logger,
66+
loaderConfig: Parameters<typeof stsRegionDefaultResolver>[0] = {}
6767
): Promise<string> => {
6868
const region: string | undefined = typeof _region === "function" ? await _region() : _region;
6969
const parentRegion: string | undefined = typeof _parentRegion === "function" ? await _parentRegion() : _parentRegion;
70+
const stsDefaultRegion = await stsRegionDefaultResolver(loaderConfig)();
7071

7172
credentialProviderLogger?.debug?.(
7273
"@aws-sdk/client-sts::resolveRegion",
7374
"accepting first of:",
74-
`${region} (provider)`,
75-
`${parentRegion} (parent client)`,
76-
`${ASSUME_ROLE_DEFAULT_REGION} (STS default)`
75+
`${region} (credential provider clientConfig)`,
76+
`${parentRegion} (contextual client)`,
77+
`${stsDefaultRegion} (STS default: AWS_REGION, profile region, or us-east-1)`
7778
);
78-
return region ?? parentRegion ?? ASSUME_ROLE_DEFAULT_REGION;
79+
return region ?? parentRegion ?? stsDefaultRegion;
7980
};
8081

8182
/**
@@ -101,7 +102,11 @@ export const getDefaultRoleAssumer = (
101102
const resolvedRegion = await resolveRegion(
102103
region,
103104
stsOptions?.parentClientConfig?.region,
104-
credentialProviderLogger
105+
credentialProviderLogger,
106+
{
107+
logger,
108+
profile,
109+
}
105110
);
106111
const isCompatibleRequestHandler = !isH2(requestHandler);
107112

@@ -164,7 +169,11 @@ export const getDefaultRoleAssumerWithWebIdentity = (
164169
const resolvedRegion = await resolveRegion(
165170
region,
166171
stsOptions?.parentClientConfig?.region,
167-
credentialProviderLogger
172+
credentialProviderLogger,
173+
{
174+
logger,
175+
profile,
176+
}
168177
);
169178
const isCompatibleRequestHandler = !isH2(requestHandler);
170179

codegen/smithy-aws-typescript-codegen/src/main/resources/software/amazon/smithy/aws/typescript/codegen/sts-client-defaultStsRoleAssumers.ts

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { setCredentialFeature } from "@aws-sdk/core/client";
2+
import { stsRegionDefaultResolver } from "@aws-sdk/region-config-resolver";
23
import type { CredentialProviderOptions } from "@aws-sdk/types";
34
import { AwsCredentialIdentity, Logger, Provider } from "@smithy/types";
45

@@ -25,8 +26,6 @@ export type RoleAssumer = (
2526
params: AssumeRoleCommandInput
2627
) => Promise<AwsCredentialIdentity>;
2728

28-
const ASSUME_ROLE_DEFAULT_REGION = "us-east-1";
29-
3029
interface AssumedRoleUser {
3130
/**
3231
* The ARN of the temporary security credentials that are returned from the AssumeRole action.
@@ -60,19 +59,21 @@ const getAccountIdFromAssumedRoleUser = (assumedRoleUser?: AssumedRoleUser) => {
6059
const resolveRegion = async (
6160
_region: string | Provider<string> | undefined,
6261
_parentRegion: string | Provider<string> | undefined,
63-
credentialProviderLogger?: Logger
62+
credentialProviderLogger?: Logger,
63+
loaderConfig: Parameters<typeof stsRegionDefaultResolver>[0] = {}
6464
): Promise<string> => {
6565
const region: string | undefined = typeof _region === "function" ? await _region() : _region;
6666
const parentRegion: string | undefined = typeof _parentRegion === "function" ? await _parentRegion() : _parentRegion;
67+
const stsDefaultRegion = await stsRegionDefaultResolver(loaderConfig)();
6768

6869
credentialProviderLogger?.debug?.(
6970
"@aws-sdk/client-sts::resolveRegion",
7071
"accepting first of:",
71-
`${region} (provider)`,
72-
`${parentRegion} (parent client)`,
73-
`${ASSUME_ROLE_DEFAULT_REGION} (STS default)`
72+
`${region} (credential provider clientConfig)`,
73+
`${parentRegion} (contextual client)`,
74+
`${stsDefaultRegion} (STS default: AWS_REGION, profile region, or us-east-1)`
7475
);
75-
return region ?? parentRegion ?? ASSUME_ROLE_DEFAULT_REGION;
76+
return region ?? parentRegion ?? stsDefaultRegion;
7677
};
7778

7879
/**
@@ -98,7 +99,11 @@ export const getDefaultRoleAssumer = (
9899
const resolvedRegion = await resolveRegion(
99100
region,
100101
stsOptions?.parentClientConfig?.region,
101-
credentialProviderLogger
102+
credentialProviderLogger,
103+
{
104+
logger,
105+
profile,
106+
}
102107
);
103108
const isCompatibleRequestHandler = !isH2(requestHandler);
104109

@@ -161,7 +166,11 @@ export const getDefaultRoleAssumerWithWebIdentity = (
161166
const resolvedRegion = await resolveRegion(
162167
region,
163168
stsOptions?.parentClientConfig?.region,
164-
credentialProviderLogger
169+
credentialProviderLogger,
170+
{
171+
logger,
172+
profile,
173+
}
165174
);
166175
const isCompatibleRequestHandler = !isH2(requestHandler);
167176

packages/credential-provider-node/tests/credential-provider-node.integ.spec.ts

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1492,5 +1492,120 @@ describe("credential-provider-node integration test", () => {
14921492
expect(logger.debug).toHaveBeenCalled();
14931493
expect(logger.info).toHaveBeenCalled();
14941494
});
1495+
1496+
describe("uses a variant of the default region resolution where us-east-1 is the last resort", async () => {
1497+
it("no env or profile region", async () => {
1498+
delete process.env.AWS_REGION;
1499+
setIniProfileData({
1500+
assume: {
1501+
aws_access_key_id: "ASSUME_STATIC_ACCESS_KEY",
1502+
aws_secret_access_key: "ASSUME_STATIC_SECRET_KEY",
1503+
},
1504+
default: {
1505+
role_arn: "ROLE_ARN",
1506+
role_session_name: "ROLE_SESSION_NAME",
1507+
source_profile: "assume",
1508+
},
1509+
});
1510+
1511+
const provider = defaultProvider({});
1512+
const credentials = await provider();
1513+
expect(credentials).toEqual({
1514+
accessKeyId: "STS_AR_ACCESS_KEY_ID",
1515+
expiration: new Date(`3000-01-01T00:00:00.000Z`),
1516+
secretAccessKey: "STS_AR_SECRET_ACCESS_KEY",
1517+
sessionToken: "STS_AR_SESSION_TOKEN_us-east-1",
1518+
$source: {
1519+
CREDENTIALS_PROFILE_SOURCE_PROFILE: "o",
1520+
CREDENTIALS_STS_ASSUME_ROLE: "i",
1521+
},
1522+
});
1523+
});
1524+
1525+
it("env region", async () => {
1526+
process.env.AWS_REGION = "eu-north-1";
1527+
setIniProfileData({
1528+
assume: {
1529+
aws_access_key_id: "ASSUME_STATIC_ACCESS_KEY",
1530+
aws_secret_access_key: "ASSUME_STATIC_SECRET_KEY",
1531+
},
1532+
default: {
1533+
role_arn: "ROLE_ARN",
1534+
role_session_name: "ROLE_SESSION_NAME",
1535+
source_profile: "assume",
1536+
},
1537+
});
1538+
1539+
const provider = defaultProvider({});
1540+
const credentials = await provider();
1541+
expect(credentials).toEqual({
1542+
accessKeyId: "STS_AR_ACCESS_KEY_ID",
1543+
expiration: new Date(`3000-01-01T00:00:00.000Z`),
1544+
secretAccessKey: "STS_AR_SECRET_ACCESS_KEY",
1545+
sessionToken: "STS_AR_SESSION_TOKEN_eu-north-1",
1546+
$source: {
1547+
CREDENTIALS_PROFILE_SOURCE_PROFILE: "o",
1548+
CREDENTIALS_STS_ASSUME_ROLE: "i",
1549+
},
1550+
});
1551+
});
1552+
1553+
it("profile region", async () => {
1554+
setIniProfileData({
1555+
assume: {
1556+
aws_access_key_id: "ASSUME_STATIC_ACCESS_KEY",
1557+
aws_secret_access_key: "ASSUME_STATIC_SECRET_KEY",
1558+
},
1559+
default: {
1560+
region: "us-west-2",
1561+
role_arn: "ROLE_ARN",
1562+
role_session_name: "ROLE_SESSION_NAME",
1563+
source_profile: "assume",
1564+
},
1565+
});
1566+
1567+
const provider = defaultProvider({});
1568+
const credentials = await provider();
1569+
expect(credentials).toEqual({
1570+
accessKeyId: "STS_AR_ACCESS_KEY_ID",
1571+
expiration: new Date(`3000-01-01T00:00:00.000Z`),
1572+
secretAccessKey: "STS_AR_SECRET_ACCESS_KEY",
1573+
sessionToken: "STS_AR_SESSION_TOKEN_us-west-2",
1574+
$source: {
1575+
CREDENTIALS_PROFILE_SOURCE_PROFILE: "o",
1576+
CREDENTIALS_STS_ASSUME_ROLE: "i",
1577+
},
1578+
});
1579+
});
1580+
1581+
it("profile and env region conflict, it uses config region because credentials are fromIni", async () => {
1582+
process.env.AWS_REGION = "eu-north-1";
1583+
setIniProfileData({
1584+
assume: {
1585+
aws_access_key_id: "ASSUME_STATIC_ACCESS_KEY",
1586+
aws_secret_access_key: "ASSUME_STATIC_SECRET_KEY",
1587+
},
1588+
default: {
1589+
region: "us-west-2",
1590+
role_arn: "ROLE_ARN",
1591+
role_session_name: "ROLE_SESSION_NAME",
1592+
source_profile: "assume",
1593+
},
1594+
});
1595+
1596+
const provider = defaultProvider({});
1597+
const credentials = await provider();
1598+
expect(credentials).toEqual({
1599+
accessKeyId: "STS_AR_ACCESS_KEY_ID",
1600+
expiration: new Date(`3000-01-01T00:00:00.000Z`),
1601+
secretAccessKey: "STS_AR_SECRET_ACCESS_KEY",
1602+
sessionToken: "STS_AR_SESSION_TOKEN_us-west-2",
1603+
$source: {
1604+
CREDENTIALS_PROFILE_SOURCE_PROFILE: "o",
1605+
CREDENTIALS_STS_ASSUME_ROLE: "i",
1606+
},
1607+
});
1608+
});
1609+
});
14951610
});
14961611
});

packages/nested-clients/src/submodules/sts/defaultStsRoleAssumers.ts

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Please do not touch this file. It's generated from template in:
33
// https://github.com/aws/aws-sdk-js-v3/blob/main/codegen/smithy-aws-typescript-codegen/src/main/resources/software/amazon/smithy/aws/typescript/codegen/sts-client-defaultStsRoleAssumers.ts
44
import { setCredentialFeature } from "@aws-sdk/core/client";
5+
import { stsRegionDefaultResolver } from "@aws-sdk/region-config-resolver";
56
import type { CredentialProviderOptions } from "@aws-sdk/types";
67
import { AwsCredentialIdentity, Logger, Provider } from "@smithy/types";
78

@@ -28,8 +29,6 @@ export type RoleAssumer = (
2829
params: AssumeRoleCommandInput
2930
) => Promise<AwsCredentialIdentity>;
3031

31-
const ASSUME_ROLE_DEFAULT_REGION = "us-east-1";
32-
3332
interface AssumedRoleUser {
3433
/**
3534
* The ARN of the temporary security credentials that are returned from the AssumeRole action.
@@ -63,19 +62,21 @@ const getAccountIdFromAssumedRoleUser = (assumedRoleUser?: AssumedRoleUser) => {
6362
const resolveRegion = async (
6463
_region: string | Provider<string> | undefined,
6564
_parentRegion: string | Provider<string> | undefined,
66-
credentialProviderLogger?: Logger
65+
credentialProviderLogger?: Logger,
66+
loaderConfig: Parameters<typeof stsRegionDefaultResolver>[0] = {}
6767
): Promise<string> => {
6868
const region: string | undefined = typeof _region === "function" ? await _region() : _region;
6969
const parentRegion: string | undefined = typeof _parentRegion === "function" ? await _parentRegion() : _parentRegion;
70+
const stsDefaultRegion = await stsRegionDefaultResolver(loaderConfig)();
7071

7172
credentialProviderLogger?.debug?.(
7273
"@aws-sdk/client-sts::resolveRegion",
7374
"accepting first of:",
74-
`${region} (provider)`,
75-
`${parentRegion} (parent client)`,
76-
`${ASSUME_ROLE_DEFAULT_REGION} (STS default)`
75+
`${region} (credential provider clientConfig)`,
76+
`${parentRegion} (contextual client)`,
77+
`${stsDefaultRegion} (STS default: AWS_REGION, profile region, or us-east-1)`
7778
);
78-
return region ?? parentRegion ?? ASSUME_ROLE_DEFAULT_REGION;
79+
return region ?? parentRegion ?? stsDefaultRegion;
7980
};
8081

8182
/**
@@ -101,7 +102,11 @@ export const getDefaultRoleAssumer = (
101102
const resolvedRegion = await resolveRegion(
102103
region,
103104
stsOptions?.parentClientConfig?.region,
104-
credentialProviderLogger
105+
credentialProviderLogger,
106+
{
107+
logger,
108+
profile,
109+
}
105110
);
106111
const isCompatibleRequestHandler = !isH2(requestHandler);
107112

@@ -164,7 +169,11 @@ export const getDefaultRoleAssumerWithWebIdentity = (
164169
const resolvedRegion = await resolveRegion(
165170
region,
166171
stsOptions?.parentClientConfig?.region,
167-
credentialProviderLogger
172+
credentialProviderLogger,
173+
{
174+
logger,
175+
profile,
176+
}
168177
);
169178
const isCompatibleRequestHandler = !isH2(requestHandler);
170179

packages/region-config-resolver/package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"dependencies": {
2626
"@aws-sdk/types": "*",
2727
"@smithy/config-resolver": "^4.4.0",
28+
"@smithy/node-config-provider": "^4.3.3",
2829
"@smithy/types": "^4.8.0",
2930
"tslib": "^2.6.2"
3031
},
@@ -53,5 +54,9 @@
5354
"type": "git",
5455
"url": "https://github.com/aws/aws-sdk-js-v3.git",
5556
"directory": "packages/region-config-resolver"
56-
}
57+
},
58+
"browser": {
59+
"./dist-es/regionConfig/stsRegionDefaultResolver": "./dist-es/regionConfig/stsRegionDefaultResolver.browser"
60+
},
61+
"react-native": {}
5762
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export * from "./extensions";
22
export * from "./regionConfig/awsRegionConfig";
3+
export * from "./regionConfig/stsRegionDefaultResolver";
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/**
2+
* @internal
3+
*/
4+
export function stsRegionDefaultResolver() {
5+
return async () => "us-east-1";
6+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/**
2+
* @internal
3+
*/
4+
export function stsRegionDefaultResolver() {
5+
return async () => "us-east-1";
6+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { describe, expect, test as it } from "vitest";
2+
3+
import { stsRegionDefaultResolver } from "./stsRegionDefaultResolver";
4+
import { stsRegionDefaultResolver as browser } from "./stsRegionDefaultResolver.browser";
5+
import { stsRegionDefaultResolver as native } from "./stsRegionDefaultResolver.native";
6+
7+
describe("stsRegionDefaultResolver", () => {
8+
for (const impl of [stsRegionDefaultResolver, native, browser]) {
9+
it(`should default to us-east-1`, async () => {
10+
delete process.env.AWS_REGION;
11+
const regionProvider = impl({
12+
profile: "non-existent P R O F I L E",
13+
});
14+
const region = await regionProvider();
15+
expect(region).toBe("us-east-1");
16+
});
17+
}
18+
19+
it("should use AWS_REGION before fallback to us-east-1", async () => {
20+
process.env.AWS_REGION = "us-west-2";
21+
const regionProvider = stsRegionDefaultResolver({
22+
profile: "non-existent P R O F I L E",
23+
});
24+
const region = await regionProvider();
25+
expect(region).toBe("us-west-2");
26+
});
27+
});

0 commit comments

Comments
 (0)