Skip to content

Commit 8c0b29e

Browse files
authored
fix(credential-provider-node): pass client region to inner credential client region (#5758)
test: sts does not resolve aws auth config
1 parent 4e0c0fc commit 8c0b29e

File tree

13 files changed

+268
-102
lines changed

13 files changed

+268
-102
lines changed

clients/client-sts/src/defaultRoleAssumers.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
getDefaultRoleAssumerWithWebIdentity as StsGetDefaultRoleAssumerWithWebIdentity,
1010
RoleAssumer,
1111
RoleAssumerWithWebIdentity,
12+
STSRoleAssumerOptions,
1213
} from "./defaultStsRoleAssumers";
1314
import { ServiceInputTypes, ServiceOutputTypes, STSClient, STSClientConfig } from "./STSClient";
1415

@@ -32,15 +33,15 @@ const getCustomizableStsClientCtor = (
3233
* The default role assumer that used by credential providers when sts:AssumeRole API is needed.
3334
*/
3435
export const getDefaultRoleAssumer = (
35-
stsOptions: Pick<STSClientConfig, "logger" | "region" | "requestHandler"> = {},
36+
stsOptions: STSRoleAssumerOptions = {},
3637
stsPlugins?: Pluggable<ServiceInputTypes, ServiceOutputTypes>[]
3738
): RoleAssumer => StsGetDefaultRoleAssumer(stsOptions, getCustomizableStsClientCtor(STSClient, stsPlugins));
3839

3940
/**
4041
* The default role assumer that used by credential providers when sts:AssumeRoleWithWebIdentity API is needed.
4142
*/
4243
export const getDefaultRoleAssumerWithWebIdentity = (
43-
stsOptions: Pick<STSClientConfig, "logger" | "region" | "requestHandler"> = {},
44+
stsOptions: STSRoleAssumerOptions = {},
4445
stsPlugins?: Pluggable<ServiceInputTypes, ServiceOutputTypes>[]
4546
): RoleAssumerWithWebIdentity =>
4647
StsGetDefaultRoleAssumerWithWebIdentity(stsOptions, getCustomizableStsClientCtor(STSClient, stsPlugins));

clients/client-sts/src/defaultStsRoleAssumers.ts

+56-18
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
// smithy-typescript generated code
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
4-
import { AwsCredentialIdentity, Provider } from "@smithy/types";
4+
import type { CredentialProviderOptions } from "@aws-sdk/types";
5+
import { partition } from "@aws-sdk/util-endpoints";
6+
import { AwsCredentialIdentity, Logger, Provider } from "@smithy/types";
57

68
import { AssumeRoleCommand, AssumeRoleCommandInput } from "./commands/AssumeRoleCommand";
79
import {
@@ -10,6 +12,14 @@ import {
1012
} from "./commands/AssumeRoleWithWebIdentityCommand";
1113
import type { STSClient, STSClientConfig, STSClientResolvedConfig } from "./STSClient";
1214

15+
/**
16+
* @public
17+
*/
18+
export type STSRoleAssumerOptions = Pick<STSClientConfig, "logger" | "region" | "requestHandler"> & {
19+
credentialProviderLogger?: Logger;
20+
parentClientConfig?: CredentialProviderOptions["parentClientConfig"];
21+
};
22+
1323
/**
1424
* @internal
1525
*/
@@ -21,40 +31,63 @@ export type RoleAssumer = (
2131
const ASSUME_ROLE_DEFAULT_REGION = "us-east-1";
2232

2333
/**
24-
* Inject the fallback STS region of us-east-1.
34+
* @internal
35+
*
36+
* Default to the us-east-1 region for aws partition,
37+
* or default to the parent client region otherwise.
2538
*/
26-
const decorateDefaultRegion = (region: string | Provider<string> | undefined): string | Provider<string> => {
27-
if (typeof region !== "function") {
28-
return region === undefined ? ASSUME_ROLE_DEFAULT_REGION : region;
39+
const resolveRegion = async (
40+
_region: string | Provider<string> | undefined,
41+
_parentRegion: string | Provider<string> | undefined,
42+
credentialProviderLogger?: Logger
43+
): Promise<string> => {
44+
const region: string | undefined = typeof _region === "function" ? await _region() : _region;
45+
const parentRegion: string | undefined = typeof _parentRegion === "function" ? await _parentRegion() : _parentRegion;
46+
47+
if (!parentRegion || partition(parentRegion).name === "aws") {
48+
credentialProviderLogger?.debug?.(
49+
"@aws-sdk/client-sts::resolveRegion",
50+
"accepting first of:",
51+
`${region} (provider)`,
52+
`${ASSUME_ROLE_DEFAULT_REGION} (STS default)`
53+
);
54+
return region ?? ASSUME_ROLE_DEFAULT_REGION;
55+
} else {
56+
credentialProviderLogger?.debug?.(
57+
"@aws-sdk/client-sts::resolveRegion",
58+
"accepting first of:",
59+
`${region} (provider)`,
60+
`${parentRegion} (parent client)`,
61+
`${ASSUME_ROLE_DEFAULT_REGION} (STS default)`
62+
);
63+
return region ?? parentRegion ?? ASSUME_ROLE_DEFAULT_REGION;
2964
}
30-
return async () => {
31-
try {
32-
return await region();
33-
} catch (e) {
34-
return ASSUME_ROLE_DEFAULT_REGION;
35-
}
36-
};
3765
};
3866

3967
/**
4068
* The default role assumer that used by credential providers when sts:AssumeRole API is needed.
4169
* @internal
4270
*/
4371
export const getDefaultRoleAssumer = (
44-
stsOptions: Pick<STSClientConfig, "logger" | "region" | "requestHandler">,
72+
stsOptions: STSRoleAssumerOptions,
4573
stsClientCtor: new (options: STSClientConfig) => STSClient
4674
): RoleAssumer => {
4775
let stsClient: STSClient;
4876
let closureSourceCreds: AwsCredentialIdentity;
4977
return async (sourceCreds, params) => {
5078
closureSourceCreds = sourceCreds;
5179
if (!stsClient) {
52-
const { logger, region, requestHandler } = stsOptions;
80+
const { logger, region, requestHandler, credentialProviderLogger } = stsOptions;
81+
const resolvedRegion = await resolveRegion(
82+
region,
83+
stsOptions?.parentClientConfig?.region,
84+
credentialProviderLogger
85+
);
5386
stsClient = new stsClientCtor({
5487
logger,
5588
// A hack to make sts client uses the credential in current closure.
5689
credentialDefaultProvider: () => async () => closureSourceCreds,
57-
region: decorateDefaultRegion(region || stsOptions.region),
90+
region: resolvedRegion,
5891
...(requestHandler ? { requestHandler } : {}),
5992
});
6093
}
@@ -85,16 +118,21 @@ export type RoleAssumerWithWebIdentity = (
85118
* @internal
86119
*/
87120
export const getDefaultRoleAssumerWithWebIdentity = (
88-
stsOptions: Pick<STSClientConfig, "logger" | "region" | "requestHandler">,
121+
stsOptions: STSRoleAssumerOptions,
89122
stsClientCtor: new (options: STSClientConfig) => STSClient
90123
): RoleAssumerWithWebIdentity => {
91124
let stsClient: STSClient;
92125
return async (params) => {
93126
if (!stsClient) {
94-
const { logger, region, requestHandler } = stsOptions;
127+
const { logger, region, requestHandler, credentialProviderLogger } = stsOptions;
128+
const resolvedRegion = await resolveRegion(
129+
region,
130+
stsOptions?.parentClientConfig?.region,
131+
credentialProviderLogger
132+
);
95133
stsClient = new stsClientCtor({
96134
logger,
97-
region: decorateDefaultRegion(region || stsOptions.region),
135+
region: resolvedRegion,
98136
...(requestHandler ? { requestHandler } : {}),
99137
});
100138
}

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

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
getDefaultRoleAssumerWithWebIdentity as StsGetDefaultRoleAssumerWithWebIdentity,
77
RoleAssumer,
88
RoleAssumerWithWebIdentity,
9+
STSRoleAssumerOptions,
910
} from "./defaultStsRoleAssumers";
1011
import { ServiceInputTypes, ServiceOutputTypes, STSClient, STSClientConfig } from "./STSClient";
1112

@@ -29,15 +30,15 @@ const getCustomizableStsClientCtor = (
2930
* The default role assumer that used by credential providers when sts:AssumeRole API is needed.
3031
*/
3132
export const getDefaultRoleAssumer = (
32-
stsOptions: Pick<STSClientConfig, "logger" | "region" | "requestHandler"> = {},
33+
stsOptions: STSRoleAssumerOptions = {},
3334
stsPlugins?: Pluggable<ServiceInputTypes, ServiceOutputTypes>[]
3435
): RoleAssumer => StsGetDefaultRoleAssumer(stsOptions, getCustomizableStsClientCtor(STSClient, stsPlugins));
3536

3637
/**
3738
* The default role assumer that used by credential providers when sts:AssumeRoleWithWebIdentity API is needed.
3839
*/
3940
export const getDefaultRoleAssumerWithWebIdentity = (
40-
stsOptions: Pick<STSClientConfig, "logger" | "region" | "requestHandler"> = {},
41+
stsOptions: STSRoleAssumerOptions = {},
4142
stsPlugins?: Pluggable<ServiceInputTypes, ServiceOutputTypes>[]
4243
): RoleAssumerWithWebIdentity =>
4344
StsGetDefaultRoleAssumerWithWebIdentity(stsOptions, getCustomizableStsClientCtor(STSClient, stsPlugins));

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

+56-18
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
import { AwsCredentialIdentity, Provider } from "@smithy/types";
1+
import type { CredentialProviderOptions } from "@aws-sdk/types";
2+
import { partition } from "@aws-sdk/util-endpoints";
3+
import { AwsCredentialIdentity, Logger, Provider } from "@smithy/types";
24

35
import { AssumeRoleCommand, AssumeRoleCommandInput } from "./commands/AssumeRoleCommand";
46
import {
@@ -7,6 +9,14 @@ import {
79
} from "./commands/AssumeRoleWithWebIdentityCommand";
810
import type { STSClient, STSClientConfig, STSClientResolvedConfig } from "./STSClient";
911

12+
/**
13+
* @public
14+
*/
15+
export type STSRoleAssumerOptions = Pick<STSClientConfig, "logger" | "region" | "requestHandler"> & {
16+
credentialProviderLogger?: Logger;
17+
parentClientConfig?: CredentialProviderOptions["parentClientConfig"];
18+
};
19+
1020
/**
1121
* @internal
1222
*/
@@ -18,40 +28,63 @@ export type RoleAssumer = (
1828
const ASSUME_ROLE_DEFAULT_REGION = "us-east-1";
1929

2030
/**
21-
* Inject the fallback STS region of us-east-1.
31+
* @internal
32+
*
33+
* Default to the us-east-1 region for aws partition,
34+
* or default to the parent client region otherwise.
2235
*/
23-
const decorateDefaultRegion = (region: string | Provider<string> | undefined): string | Provider<string> => {
24-
if (typeof region !== "function") {
25-
return region === undefined ? ASSUME_ROLE_DEFAULT_REGION : region;
36+
const resolveRegion = async (
37+
_region: string | Provider<string> | undefined,
38+
_parentRegion: string | Provider<string> | undefined,
39+
credentialProviderLogger?: Logger
40+
): Promise<string> => {
41+
const region: string | undefined = typeof _region === "function" ? await _region() : _region;
42+
const parentRegion: string | undefined = typeof _parentRegion === "function" ? await _parentRegion() : _parentRegion;
43+
44+
if (!parentRegion || partition(parentRegion).name === "aws") {
45+
credentialProviderLogger?.debug?.(
46+
"@aws-sdk/client-sts::resolveRegion",
47+
"accepting first of:",
48+
`${region} (provider)`,
49+
`${ASSUME_ROLE_DEFAULT_REGION} (STS default)`
50+
);
51+
return region ?? ASSUME_ROLE_DEFAULT_REGION;
52+
} else {
53+
credentialProviderLogger?.debug?.(
54+
"@aws-sdk/client-sts::resolveRegion",
55+
"accepting first of:",
56+
`${region} (provider)`,
57+
`${parentRegion} (parent client)`,
58+
`${ASSUME_ROLE_DEFAULT_REGION} (STS default)`
59+
);
60+
return region ?? parentRegion ?? ASSUME_ROLE_DEFAULT_REGION;
2661
}
27-
return async () => {
28-
try {
29-
return await region();
30-
} catch (e) {
31-
return ASSUME_ROLE_DEFAULT_REGION;
32-
}
33-
};
3462
};
3563

3664
/**
3765
* The default role assumer that used by credential providers when sts:AssumeRole API is needed.
3866
* @internal
3967
*/
4068
export const getDefaultRoleAssumer = (
41-
stsOptions: Pick<STSClientConfig, "logger" | "region" | "requestHandler">,
69+
stsOptions: STSRoleAssumerOptions,
4270
stsClientCtor: new (options: STSClientConfig) => STSClient
4371
): RoleAssumer => {
4472
let stsClient: STSClient;
4573
let closureSourceCreds: AwsCredentialIdentity;
4674
return async (sourceCreds, params) => {
4775
closureSourceCreds = sourceCreds;
4876
if (!stsClient) {
49-
const { logger, region, requestHandler } = stsOptions;
77+
const { logger, region, requestHandler, credentialProviderLogger } = stsOptions;
78+
const resolvedRegion = await resolveRegion(
79+
region,
80+
stsOptions?.parentClientConfig?.region,
81+
credentialProviderLogger
82+
);
5083
stsClient = new stsClientCtor({
5184
logger,
5285
// A hack to make sts client uses the credential in current closure.
5386
credentialDefaultProvider: () => async () => closureSourceCreds,
54-
region: decorateDefaultRegion(region || stsOptions.region),
87+
region: resolvedRegion,
5588
...(requestHandler ? { requestHandler } : {}),
5689
});
5790
}
@@ -82,16 +115,21 @@ export type RoleAssumerWithWebIdentity = (
82115
* @internal
83116
*/
84117
export const getDefaultRoleAssumerWithWebIdentity = (
85-
stsOptions: Pick<STSClientConfig, "logger" | "region" | "requestHandler">,
118+
stsOptions: STSRoleAssumerOptions,
86119
stsClientCtor: new (options: STSClientConfig) => STSClient
87120
): RoleAssumerWithWebIdentity => {
88121
let stsClient: STSClient;
89122
return async (params) => {
90123
if (!stsClient) {
91-
const { logger, region, requestHandler } = stsOptions;
124+
const { logger, region, requestHandler, credentialProviderLogger } = stsOptions;
125+
const resolvedRegion = await resolveRegion(
126+
region,
127+
stsOptions?.parentClientConfig?.region,
128+
credentialProviderLogger
129+
);
92130
stsClient = new stsClientCtor({
93131
logger,
94-
region: decorateDefaultRegion(region || stsOptions.region),
132+
region: resolvedRegion,
95133
...(requestHandler ? { requestHandler } : {}),
96134
});
97135
}

packages/core/src/httpAuthSchemes/aws_sdk/resolveAwsSdkSigV4Config.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,17 @@ export const resolveAwsSdkSigV4Config = <T>(
111111
// credentialDefaultProvider should always be populated, but in case
112112
// it isn't, set a default identity provider that throws an error
113113
if (config.credentialDefaultProvider) {
114-
normalizedCreds = normalizeProvider(config.credentialDefaultProvider(config as any));
114+
normalizedCreds = normalizeProvider(
115+
config.credentialDefaultProvider(
116+
Object.assign({}, config as any, {
117+
parentClientConfig: config,
118+
})
119+
)
120+
);
115121
} else {
116-
normalizedCreds = async () => { throw new Error("`credentials` is missing") };
122+
normalizedCreds = async () => {
123+
throw new Error("`credentials` is missing");
124+
};
117125
}
118126
}
119127

packages/credential-provider-cognito-identity/src/fromCognitoIdentity.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,14 @@ export function fromCognitoIdentity(parameters: FromCognitoIdentityParameters):
4040
SecretKey = throwOnMissingSecretKey(),
4141
SessionToken,
4242
} = throwOnMissingCredentials(),
43-
} = await (parameters.client ?? new CognitoIdentityClient(parameters.clientConfig ?? {})).send(
43+
} = await (
44+
parameters.client ??
45+
new CognitoIdentityClient(
46+
Object.assign({}, parameters.clientConfig ?? {}, {
47+
region: parameters.clientConfig?.region ?? parameters.parentClientConfig?.region,
48+
})
49+
)
50+
).send(
4451
new GetCredentialsForIdentityCommand({
4552
CustomRoleArn: parameters.customRoleArn,
4653
IdentityId: parameters.identityId,

packages/credential-provider-cognito-identity/src/fromCognitoIdentityPool.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export function fromCognitoIdentityPool({
2727
logins,
2828
userIdentifier = !logins || Object.keys(logins).length === 0 ? "ANONYMOUS" : undefined,
2929
logger,
30+
parentClientConfig,
3031
}: FromCognitoIdentityPoolParameters): CognitoIdentityCredentialProvider {
3132
logger?.debug("@aws-sdk/credential-provider-cognito-identity", "fromCognitoIdentity");
3233
const cacheKey: string | undefined = userIdentifier
@@ -35,7 +36,11 @@ export function fromCognitoIdentityPool({
3536

3637
let provider: CognitoIdentityCredentialProvider = async () => {
3738
const { GetIdCommand, CognitoIdentityClient } = await import("./loadCognitoIdentity");
38-
const _client = client ?? new CognitoIdentityClient(clientConfig ?? {});
39+
const _client =
40+
client ??
41+
new CognitoIdentityClient(
42+
Object.assign({}, clientConfig ?? {}, { region: clientConfig?.region ?? parentClientConfig?.region })
43+
);
3944

4045
let identityId: string | undefined = (cacheKey && (await cache.getItem(cacheKey))) as string | undefined;
4146
if (!identityId) {

packages/credential-provider-ini/src/resolveAssumeRoleCredentials.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,14 @@ export const resolveAssumeRoleCredentials = async (
8888

8989
if (!options.roleAssumer) {
9090
const { getDefaultRoleAssumer } = await import("./loadSts");
91-
options.roleAssumer = getDefaultRoleAssumer(options.clientConfig, options.clientPlugins);
91+
options.roleAssumer = getDefaultRoleAssumer(
92+
{
93+
...options.clientConfig,
94+
credentialProviderLogger: options.logger,
95+
parentClientConfig: options?.parentClientConfig,
96+
},
97+
options.clientPlugins
98+
);
9299
}
93100

94101
const { source_profile } = data;

packages/credential-provider-ini/src/resolveWebIdentityCredentials.ts

+1
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,6 @@ export const resolveWebIdentityCredentials = async (
3535
roleSessionName: profile.role_session_name,
3636
roleAssumerWithWebIdentity: options.roleAssumerWithWebIdentity,
3737
logger: options.logger,
38+
parentClientConfig: options.parentClientConfig,
3839
})()
3940
);

0 commit comments

Comments
 (0)