From 0d0b14e8558299109eb98bdcd0fabd473728f548 Mon Sep 17 00:00:00 2001 From: George Fu Date: Wed, 22 Jan 2025 16:35:29 -0500 Subject: [PATCH] feat(credential-providers): pass caller client options to fromTemporaryCredentials inner STSClient (#6838) * feat(credential-providers): pass caller client options to fromTemporaryCredentials inner STSClient * chore: update lockfile * chore(client-sts): rename variable * test(credential-providers): add unit test fromTempCreds --- .prettierignore | 1 + .../client-sts/src/defaultStsRoleAssumers.ts | 10 +- .../sts-client-defaultStsRoleAssumers.ts | 10 +- packages/credential-providers/package.json | 1 + .../src/fromTemporaryCredentials.base.ts | 99 +++++++- .../src/fromTemporaryCredentials.spec.ts | 42 ++++ .../submodules/sso-oidc/endpoint/ruleset.ts | 149 +++--------- .../submodules/sts/defaultStsRoleAssumers.ts | 10 +- .../src/submodules/sts/endpoint/ruleset.ts | 212 +++--------------- .../src/identity/AwsCredentialIdentity.ts | 22 +- yarn.lock | 1 + 11 files changed, 231 insertions(+), 326 deletions(-) diff --git a/.prettierignore b/.prettierignore index 644973bb5ce6e..f5a3951ab33bd 100644 --- a/.prettierignore +++ b/.prettierignore @@ -4,4 +4,5 @@ CHANGELOG.md **/*.hbs **/*/report.md clients/*/src/endpoint/ruleset.ts +packages/nested-clients/src/submodules/*/endpoint/ruleset.ts **/*.java \ No newline at end of file diff --git a/clients/client-sts/src/defaultStsRoleAssumers.ts b/clients/client-sts/src/defaultStsRoleAssumers.ts index d29c654f66b87..9eaec4f7051c4 100644 --- a/clients/client-sts/src/defaultStsRoleAssumers.ts +++ b/clients/client-sts/src/defaultStsRoleAssumers.ts @@ -84,7 +84,7 @@ const resolveRegion = async ( */ export const getDefaultRoleAssumer = ( stsOptions: STSRoleAssumerOptions, - stsClientCtor: new (options: STSClientConfig) => STSClient + STSClient: new (options: STSClientConfig) => STSClient ): RoleAssumer => { let stsClient: STSClient; let closureSourceCreds: AwsCredentialIdentity; @@ -104,7 +104,8 @@ export const getDefaultRoleAssumer = ( ); const isCompatibleRequestHandler = !isH2(requestHandler); - stsClient = new stsClientCtor({ + stsClient = new STSClient({ + profile: stsOptions?.parentClientConfig?.profile, // A hack to make sts client uses the credential in current closure. credentialDefaultProvider: () => async () => closureSourceCreds, region: resolvedRegion, @@ -146,7 +147,7 @@ export type RoleAssumerWithWebIdentity = ( */ export const getDefaultRoleAssumerWithWebIdentity = ( stsOptions: STSRoleAssumerOptions, - stsClientCtor: new (options: STSClientConfig) => STSClient + STSClient: new (options: STSClientConfig) => STSClient ): RoleAssumerWithWebIdentity => { let stsClient: STSClient; return async (params) => { @@ -164,7 +165,8 @@ export const getDefaultRoleAssumerWithWebIdentity = ( ); const isCompatibleRequestHandler = !isH2(requestHandler); - stsClient = new stsClientCtor({ + stsClient = new STSClient({ + profile: stsOptions?.parentClientConfig?.profile, region: resolvedRegion, requestHandler: isCompatibleRequestHandler ? (requestHandler as any) : undefined, logger: logger as any, diff --git a/codegen/smithy-aws-typescript-codegen/src/main/resources/software/amazon/smithy/aws/typescript/codegen/sts-client-defaultStsRoleAssumers.ts b/codegen/smithy-aws-typescript-codegen/src/main/resources/software/amazon/smithy/aws/typescript/codegen/sts-client-defaultStsRoleAssumers.ts index dd21da12895ef..9c613ad981bfc 100644 --- a/codegen/smithy-aws-typescript-codegen/src/main/resources/software/amazon/smithy/aws/typescript/codegen/sts-client-defaultStsRoleAssumers.ts +++ b/codegen/smithy-aws-typescript-codegen/src/main/resources/software/amazon/smithy/aws/typescript/codegen/sts-client-defaultStsRoleAssumers.ts @@ -81,7 +81,7 @@ const resolveRegion = async ( */ export const getDefaultRoleAssumer = ( stsOptions: STSRoleAssumerOptions, - stsClientCtor: new (options: STSClientConfig) => STSClient + STSClient: new (options: STSClientConfig) => STSClient ): RoleAssumer => { let stsClient: STSClient; let closureSourceCreds: AwsCredentialIdentity; @@ -101,7 +101,8 @@ export const getDefaultRoleAssumer = ( ); const isCompatibleRequestHandler = !isH2(requestHandler); - stsClient = new stsClientCtor({ + stsClient = new STSClient({ + profile: stsOptions?.parentClientConfig?.profile, // A hack to make sts client uses the credential in current closure. credentialDefaultProvider: () => async () => closureSourceCreds, region: resolvedRegion, @@ -143,7 +144,7 @@ export type RoleAssumerWithWebIdentity = ( */ export const getDefaultRoleAssumerWithWebIdentity = ( stsOptions: STSRoleAssumerOptions, - stsClientCtor: new (options: STSClientConfig) => STSClient + STSClient: new (options: STSClientConfig) => STSClient ): RoleAssumerWithWebIdentity => { let stsClient: STSClient; return async (params) => { @@ -161,7 +162,8 @@ export const getDefaultRoleAssumerWithWebIdentity = ( ); const isCompatibleRequestHandler = !isH2(requestHandler); - stsClient = new stsClientCtor({ + stsClient = new STSClient({ + profile: stsOptions?.parentClientConfig?.profile, region: resolvedRegion, requestHandler: isCompatibleRequestHandler ? (requestHandler as any) : undefined, logger: logger as any, diff --git a/packages/credential-providers/package.json b/packages/credential-providers/package.json index 5db0f6f3e7404..b65592a2944fe 100644 --- a/packages/credential-providers/package.json +++ b/packages/credential-providers/package.json @@ -42,6 +42,7 @@ "@aws-sdk/credential-provider-web-identity": "*", "@aws-sdk/nested-clients": "*", "@aws-sdk/types": "*", + "@smithy/core": "^3.0.0", "@smithy/credential-provider-imds": "^4.0.0", "@smithy/property-provider": "^4.0.0", "@smithy/types": "^4.0.0", diff --git a/packages/credential-providers/src/fromTemporaryCredentials.base.ts b/packages/credential-providers/src/fromTemporaryCredentials.base.ts index 28c92364070de..c379958e9b156 100644 --- a/packages/credential-providers/src/fromTemporaryCredentials.base.ts +++ b/packages/credential-providers/src/fromTemporaryCredentials.base.ts @@ -4,24 +4,31 @@ import type { CredentialProviderOptions, RuntimeConfigAwsCredentialIdentityProvider, } from "@aws-sdk/types"; +import { normalizeProvider } from "@smithy/core"; import { CredentialsProviderError } from "@smithy/property-provider"; -import { AwsCredentialIdentity, AwsCredentialIdentityProvider, Pluggable } from "@smithy/types"; +import { AwsCredentialIdentity, AwsCredentialIdentityProvider, Logger, Pluggable, RequestHandler } from "@smithy/types"; export interface FromTemporaryCredentialsOptions extends CredentialProviderOptions { params: Omit & { RoleSessionName?: string }; masterCredentials?: AwsCredentialIdentity | AwsCredentialIdentityProvider; clientConfig?: STSClientConfig; + logger?: Logger; clientPlugins?: Pluggable[]; mfaCodeProvider?: (mfaSerial: string) => Promise; } +const ASSUME_ROLE_DEFAULT_REGION = "us-east-1"; + export const fromTemporaryCredentials = ( options: FromTemporaryCredentialsOptions, credentialDefaultProvider?: () => AwsCredentialIdentityProvider ): RuntimeConfigAwsCredentialIdentityProvider => { let stsClient: STSClient; return async (awsIdentityProperties: AwsIdentityProperties = {}): Promise => { - options.logger?.debug("@aws-sdk/credential-providers - fromTemporaryCredentials (STS)"); + const { callerClientConfig } = awsIdentityProperties; + const logger = options.logger ?? callerClientConfig?.logger; + logger?.debug("@aws-sdk/credential-providers - fromTemporaryCredentials (STS)"); + const params = { ...options.params, RoleSessionName: options.params.RoleSessionName ?? "aws-sdk-js-" + Date.now() }; if (params?.SerialNumber) { if (!options.mfaCodeProvider) { @@ -29,7 +36,7 @@ export const fromTemporaryCredentials = ( `Temporary credential requires multi-factor authentication, but no MFA code callback was provided.`, { tryNextLink: false, - logger: options.logger, + logger, } ); } @@ -42,14 +49,68 @@ export const fromTemporaryCredentials = ( const defaultCredentialsOrError = typeof credentialDefaultProvider === "function" ? credentialDefaultProvider() : undefined; - const { callerClientConfig } = awsIdentityProperties; + const credentialSources = [ + options.masterCredentials, + options.clientConfig?.credentials, + /** + * Important (!): callerClientConfig?.credentials is not a valid + * credential source for this provider, because this function + * is the caller client's credential provider function. + */ + void callerClientConfig?.credentials, + callerClientConfig?.credentialDefaultProvider?.(), + defaultCredentialsOrError, + ]; + let credentialSource = "STS client default credentials"; + if (credentialSources[0]) { + credentialSource = "options.masterCredentials"; + } else if (credentialSources[1]) { + credentialSource = "options.clientConfig.credentials"; + } else if (credentialSources[2]) { + // This branch is not possible, see above void note. + // This code is here to prevent accidental attempts to utilize + // the invalid credential source. + credentialSource = "caller client's credentials"; + throw new Error("fromTemporaryCredentials recursion in callerClientConfig.credentials"); + } else if (credentialSources[3]) { + credentialSource = "caller client's credentialDefaultProvider"; + } else if (credentialSources[4]) { + credentialSource = "AWS SDK default credentials"; + } + + const regionSources = [options.clientConfig?.region, callerClientConfig?.region, ASSUME_ROLE_DEFAULT_REGION]; + let regionSource = "default partition's default region"; + if (regionSources[0]) { + regionSource = "options.clientConfig.region"; + } else if (regionSources[1]) { + regionSource = "caller client's region"; + } + + const requestHandlerSources = [ + filterRequestHandler(options.clientConfig?.requestHandler), + filterRequestHandler(callerClientConfig?.requestHandler), + ]; + let requestHandlerSource = "STS default requestHandler"; + if (requestHandlerSources[0]) { + requestHandlerSource = "options.clientConfig.requestHandler"; + } else if (requestHandlerSources[1]) { + requestHandlerSource = "caller client's requestHandler"; + } + + logger?.debug?.( + `@aws-sdk/credential-providers - fromTemporaryCredentials STS client init with ` + + `${regionSource}=${await normalizeProvider( + coalesce(regionSources) + )()}, ${credentialSource}, ${requestHandlerSource}.` + ); + stsClient = new STSClient({ ...options.clientConfig, - credentials: - options.masterCredentials ?? - options.clientConfig?.credentials ?? - callerClientConfig?.credentialDefaultProvider?.() ?? - defaultCredentialsOrError, + credentials: coalesce(credentialSources), + logger, + profile: options.clientConfig?.profile ?? callerClientConfig?.profile, + region: coalesce(regionSources), + requestHandler: coalesce(requestHandlerSources), }); } if (options.clientPlugins) { @@ -60,7 +121,7 @@ export const fromTemporaryCredentials = ( const { Credentials } = await stsClient.send(new AssumeRoleCommand(params)); if (!Credentials || !Credentials.AccessKeyId || !Credentials.SecretAccessKey) { throw new CredentialsProviderError(`Invalid response from STS.assumeRole call with role ${params.RoleArn}`, { - logger: options.logger, + logger, }); } return { @@ -73,3 +134,21 @@ export const fromTemporaryCredentials = ( }; }; }; + +/** + * @internal + */ +const filterRequestHandler = (requestHandler: STSClientConfig["requestHandler"]): undefined | typeof requestHandler => { + return (requestHandler as RequestHandler)?.metadata?.handlerProtocol === "h2" ? undefined : requestHandler; +}; + +/** + * @internal + */ +const coalesce = (args: any) => { + for (const item of args) { + if (item !== undefined) { + return item; + } + } +}; diff --git a/packages/credential-providers/src/fromTemporaryCredentials.spec.ts b/packages/credential-providers/src/fromTemporaryCredentials.spec.ts index f9bc202a27910..edc7d76dd0c6a 100644 --- a/packages/credential-providers/src/fromTemporaryCredentials.spec.ts +++ b/packages/credential-providers/src/fromTemporaryCredentials.spec.ts @@ -89,6 +89,10 @@ describe("fromTemporaryCredentials", () => { await provider(); expect(vi.mocked(STSClient as any)).toHaveBeenCalledWith({ credentials: masterCredentials, + logger: void 0, + profile: void 0, + region: "us-east-1", + requestHandler: void 0, }); expect(mockUsePlugin).toHaveBeenCalledTimes(1); expect(mockUsePlugin).toHaveBeenNthCalledWith(1, plugin); @@ -193,6 +197,44 @@ describe("fromTemporaryCredentials", () => { }); }); + it("uses caller client options if not overridden with provider client options", async () => { + const provider = fromTemporaryCredentialsNode({ + params: { + RoleArn, + RoleSessionName, + }, + }); + const logger = { + debug() {}, + info() {}, + warn() {}, + error() {}, + }; + const credentials = { + accessKeyId: "", + secretAccessKey: "", + }; + const credentialProvider = async () => credentials; + const regionProvider = async () => "B"; + await provider({ + callerClientConfig: { + profile: "A", + region: regionProvider, + logger, + requestHandler: Symbol.for("requestHandler") as any, + credentialDefaultProvider: () => credentialProvider, + }, + }); + expect(vi.mocked(STSClient as any).mock.calls[0][0]).toEqual({ + profile: "A", + region: regionProvider, + logger, + requestHandler: Symbol.for("requestHandler") as any, + // mockImpl resolved the credentials. + credentials, + }); + }); + it("should allow assume roles assuming roles assuming roles ad infinitum", async () => { const roleArnOf = (id: string) => `arn:aws:iam::123456789:role/${id}`; const idOf = (roleArn: string) => roleArn.split("/")?.[1] ?? "UNKNOWN"; diff --git a/packages/nested-clients/src/submodules/sso-oidc/endpoint/ruleset.ts b/packages/nested-clients/src/submodules/sso-oidc/endpoint/ruleset.ts index 790dcb48a3ba3..9248889d064e0 100644 --- a/packages/nested-clients/src/submodules/sso-oidc/endpoint/ruleset.ts +++ b/packages/nested-clients/src/submodules/sso-oidc/endpoint/ruleset.ts @@ -6,128 +6,29 @@ import { RuleSetObject } from "@smithy/types"; or see "smithy.rules#endpointRuleSet" in codegen/sdk-codegen/aws-models/sso-oidc.json */ -const u = "required", - v = "fn", - w = "argv", - x = "ref"; -const a = true, - b = "isSet", - c = "booleanEquals", - d = "error", - e = "endpoint", - f = "tree", - g = "PartitionResult", - h = "getAttr", - i = { [u]: false, type: "String" }, - j = { [u]: true, default: false, type: "Boolean" }, - k = { [x]: "Endpoint" }, - l = { [v]: c, [w]: [{ [x]: "UseFIPS" }, true] }, - m = { [v]: c, [w]: [{ [x]: "UseDualStack" }, true] }, - n = {}, - o = { [v]: h, [w]: [{ [x]: g }, "supportsFIPS"] }, - p = { [x]: g }, - q = { [v]: c, [w]: [true, { [v]: h, [w]: [p, "supportsDualStack"] }] }, - r = [l], - s = [m], - t = [{ [x]: "Region" }]; -const _data = { - version: "1.0", - parameters: { Region: i, UseDualStack: j, UseFIPS: j, Endpoint: i }, - rules: [ - { - conditions: [{ [v]: b, [w]: [k] }], - rules: [ - { conditions: r, error: "Invalid Configuration: FIPS and custom endpoint are not supported", type: d }, - { conditions: s, error: "Invalid Configuration: Dualstack and custom endpoint are not supported", type: d }, - { endpoint: { url: k, properties: n, headers: n }, type: e }, - ], - type: f, - }, - { - conditions: [{ [v]: b, [w]: t }], - rules: [ - { - conditions: [{ [v]: "aws.partition", [w]: t, assign: g }], - rules: [ - { - conditions: [l, m], - rules: [ - { - conditions: [{ [v]: c, [w]: [a, o] }, q], - rules: [ - { - endpoint: { - url: "https://oidc-fips.{Region}.{PartitionResult#dualStackDnsSuffix}", - properties: n, - headers: n, - }, - type: e, - }, - ], - type: f, - }, - { error: "FIPS and DualStack are enabled, but this partition does not support one or both", type: d }, - ], - type: f, - }, - { - conditions: r, - rules: [ - { - conditions: [{ [v]: c, [w]: [o, a] }], - rules: [ - { - conditions: [{ [v]: "stringEquals", [w]: [{ [v]: h, [w]: [p, "name"] }, "aws-us-gov"] }], - endpoint: { url: "https://oidc.{Region}.amazonaws.com", properties: n, headers: n }, - type: e, - }, - { - endpoint: { - url: "https://oidc-fips.{Region}.{PartitionResult#dnsSuffix}", - properties: n, - headers: n, - }, - type: e, - }, - ], - type: f, - }, - { error: "FIPS is enabled but this partition does not support FIPS", type: d }, - ], - type: f, - }, - { - conditions: s, - rules: [ - { - conditions: [q], - rules: [ - { - endpoint: { - url: "https://oidc.{Region}.{PartitionResult#dualStackDnsSuffix}", - properties: n, - headers: n, - }, - type: e, - }, - ], - type: f, - }, - { error: "DualStack is enabled but this partition does not support DualStack", type: d }, - ], - type: f, - }, - { - endpoint: { url: "https://oidc.{Region}.{PartitionResult#dnsSuffix}", properties: n, headers: n }, - type: e, - }, - ], - type: f, - }, - ], - type: f, - }, - { error: "Invalid Configuration: Missing Region", type: d }, - ], -}; +const u="required", +v="fn", +w="argv", +x="ref"; +const a=true, +b="isSet", +c="booleanEquals", +d="error", +e="endpoint", +f="tree", +g="PartitionResult", +h="getAttr", +i={[u]:false,"type":"String"}, +j={[u]:true,"default":false,"type":"Boolean"}, +k={[x]:"Endpoint"}, +l={[v]:c,[w]:[{[x]:"UseFIPS"},true]}, +m={[v]:c,[w]:[{[x]:"UseDualStack"},true]}, +n={}, +o={[v]:h,[w]:[{[x]:g},"supportsFIPS"]}, +p={[x]:g}, +q={[v]:c,[w]:[true,{[v]:h,[w]:[p,"supportsDualStack"]}]}, +r=[l], +s=[m], +t=[{[x]:"Region"}]; +const _data={version:"1.0",parameters:{Region:i,UseDualStack:j,UseFIPS:j,Endpoint:i},rules:[{conditions:[{[v]:b,[w]:[k]}],rules:[{conditions:r,error:"Invalid Configuration: FIPS and custom endpoint are not supported",type:d},{conditions:s,error:"Invalid Configuration: Dualstack and custom endpoint are not supported",type:d},{endpoint:{url:k,properties:n,headers:n},type:e}],type:f},{conditions:[{[v]:b,[w]:t}],rules:[{conditions:[{[v]:"aws.partition",[w]:t,assign:g}],rules:[{conditions:[l,m],rules:[{conditions:[{[v]:c,[w]:[a,o]},q],rules:[{endpoint:{url:"https://oidc-fips.{Region}.{PartitionResult#dualStackDnsSuffix}",properties:n,headers:n},type:e}],type:f},{error:"FIPS and DualStack are enabled, but this partition does not support one or both",type:d}],type:f},{conditions:r,rules:[{conditions:[{[v]:c,[w]:[o,a]}],rules:[{conditions:[{[v]:"stringEquals",[w]:[{[v]:h,[w]:[p,"name"]},"aws-us-gov"]}],endpoint:{url:"https://oidc.{Region}.amazonaws.com",properties:n,headers:n},type:e},{endpoint:{url:"https://oidc-fips.{Region}.{PartitionResult#dnsSuffix}",properties:n,headers:n},type:e}],type:f},{error:"FIPS is enabled but this partition does not support FIPS",type:d}],type:f},{conditions:s,rules:[{conditions:[q],rules:[{endpoint:{url:"https://oidc.{Region}.{PartitionResult#dualStackDnsSuffix}",properties:n,headers:n},type:e}],type:f},{error:"DualStack is enabled but this partition does not support DualStack",type:d}],type:f},{endpoint:{url:"https://oidc.{Region}.{PartitionResult#dnsSuffix}",properties:n,headers:n},type:e}],type:f}],type:f},{error:"Invalid Configuration: Missing Region",type:d}]}; export const ruleSet: RuleSetObject = _data; diff --git a/packages/nested-clients/src/submodules/sts/defaultStsRoleAssumers.ts b/packages/nested-clients/src/submodules/sts/defaultStsRoleAssumers.ts index d29c654f66b87..9eaec4f7051c4 100644 --- a/packages/nested-clients/src/submodules/sts/defaultStsRoleAssumers.ts +++ b/packages/nested-clients/src/submodules/sts/defaultStsRoleAssumers.ts @@ -84,7 +84,7 @@ const resolveRegion = async ( */ export const getDefaultRoleAssumer = ( stsOptions: STSRoleAssumerOptions, - stsClientCtor: new (options: STSClientConfig) => STSClient + STSClient: new (options: STSClientConfig) => STSClient ): RoleAssumer => { let stsClient: STSClient; let closureSourceCreds: AwsCredentialIdentity; @@ -104,7 +104,8 @@ export const getDefaultRoleAssumer = ( ); const isCompatibleRequestHandler = !isH2(requestHandler); - stsClient = new stsClientCtor({ + stsClient = new STSClient({ + profile: stsOptions?.parentClientConfig?.profile, // A hack to make sts client uses the credential in current closure. credentialDefaultProvider: () => async () => closureSourceCreds, region: resolvedRegion, @@ -146,7 +147,7 @@ export type RoleAssumerWithWebIdentity = ( */ export const getDefaultRoleAssumerWithWebIdentity = ( stsOptions: STSRoleAssumerOptions, - stsClientCtor: new (options: STSClientConfig) => STSClient + STSClient: new (options: STSClientConfig) => STSClient ): RoleAssumerWithWebIdentity => { let stsClient: STSClient; return async (params) => { @@ -164,7 +165,8 @@ export const getDefaultRoleAssumerWithWebIdentity = ( ); const isCompatibleRequestHandler = !isH2(requestHandler); - stsClient = new stsClientCtor({ + stsClient = new STSClient({ + profile: stsOptions?.parentClientConfig?.profile, region: resolvedRegion, requestHandler: isCompatibleRequestHandler ? (requestHandler as any) : undefined, logger: logger as any, diff --git a/packages/nested-clients/src/submodules/sts/endpoint/ruleset.ts b/packages/nested-clients/src/submodules/sts/endpoint/ruleset.ts index 2bb38c0332d53..d78ef4811151e 100644 --- a/packages/nested-clients/src/submodules/sts/endpoint/ruleset.ts +++ b/packages/nested-clients/src/submodules/sts/endpoint/ruleset.ts @@ -6,179 +6,41 @@ import { RuleSetObject } from "@smithy/types"; or see "smithy.rules#endpointRuleSet" in codegen/sdk-codegen/aws-models/sts.json */ -const F = "required", - G = "type", - H = "fn", - I = "argv", - J = "ref"; -const a = false, - b = true, - c = "booleanEquals", - d = "stringEquals", - e = "sigv4", - f = "sts", - g = "us-east-1", - h = "endpoint", - i = "https://sts.{Region}.{PartitionResult#dnsSuffix}", - j = "tree", - k = "error", - l = "getAttr", - m = { [F]: false, [G]: "String" }, - n = { [F]: true, default: false, [G]: "Boolean" }, - o = { [J]: "Endpoint" }, - p = { [H]: "isSet", [I]: [{ [J]: "Region" }] }, - q = { [J]: "Region" }, - r = { [H]: "aws.partition", [I]: [q], assign: "PartitionResult" }, - s = { [J]: "UseFIPS" }, - t = { [J]: "UseDualStack" }, - u = { - url: "https://sts.amazonaws.com", - properties: { authSchemes: [{ name: e, signingName: f, signingRegion: g }] }, - headers: {}, - }, - v = {}, - w = { conditions: [{ [H]: d, [I]: [q, "aws-global"] }], [h]: u, [G]: h }, - x = { [H]: c, [I]: [s, true] }, - y = { [H]: c, [I]: [t, true] }, - z = { [H]: l, [I]: [{ [J]: "PartitionResult" }, "supportsFIPS"] }, - A = { [J]: "PartitionResult" }, - B = { [H]: c, [I]: [true, { [H]: l, [I]: [A, "supportsDualStack"] }] }, - C = [{ [H]: "isSet", [I]: [o] }], - D = [x], - E = [y]; -const _data = { - version: "1.0", - parameters: { Region: m, UseDualStack: n, UseFIPS: n, Endpoint: m, UseGlobalEndpoint: n }, - rules: [ - { - conditions: [ - { [H]: c, [I]: [{ [J]: "UseGlobalEndpoint" }, b] }, - { [H]: "not", [I]: C }, - p, - r, - { [H]: c, [I]: [s, a] }, - { [H]: c, [I]: [t, a] }, - ], - rules: [ - { conditions: [{ [H]: d, [I]: [q, "ap-northeast-1"] }], endpoint: u, [G]: h }, - { conditions: [{ [H]: d, [I]: [q, "ap-south-1"] }], endpoint: u, [G]: h }, - { conditions: [{ [H]: d, [I]: [q, "ap-southeast-1"] }], endpoint: u, [G]: h }, - { conditions: [{ [H]: d, [I]: [q, "ap-southeast-2"] }], endpoint: u, [G]: h }, - w, - { conditions: [{ [H]: d, [I]: [q, "ca-central-1"] }], endpoint: u, [G]: h }, - { conditions: [{ [H]: d, [I]: [q, "eu-central-1"] }], endpoint: u, [G]: h }, - { conditions: [{ [H]: d, [I]: [q, "eu-north-1"] }], endpoint: u, [G]: h }, - { conditions: [{ [H]: d, [I]: [q, "eu-west-1"] }], endpoint: u, [G]: h }, - { conditions: [{ [H]: d, [I]: [q, "eu-west-2"] }], endpoint: u, [G]: h }, - { conditions: [{ [H]: d, [I]: [q, "eu-west-3"] }], endpoint: u, [G]: h }, - { conditions: [{ [H]: d, [I]: [q, "sa-east-1"] }], endpoint: u, [G]: h }, - { conditions: [{ [H]: d, [I]: [q, g] }], endpoint: u, [G]: h }, - { conditions: [{ [H]: d, [I]: [q, "us-east-2"] }], endpoint: u, [G]: h }, - { conditions: [{ [H]: d, [I]: [q, "us-west-1"] }], endpoint: u, [G]: h }, - { conditions: [{ [H]: d, [I]: [q, "us-west-2"] }], endpoint: u, [G]: h }, - { - endpoint: { - url: i, - properties: { authSchemes: [{ name: e, signingName: f, signingRegion: "{Region}" }] }, - headers: v, - }, - [G]: h, - }, - ], - [G]: j, - }, - { - conditions: C, - rules: [ - { conditions: D, error: "Invalid Configuration: FIPS and custom endpoint are not supported", [G]: k }, - { conditions: E, error: "Invalid Configuration: Dualstack and custom endpoint are not supported", [G]: k }, - { endpoint: { url: o, properties: v, headers: v }, [G]: h }, - ], - [G]: j, - }, - { - conditions: [p], - rules: [ - { - conditions: [r], - rules: [ - { - conditions: [x, y], - rules: [ - { - conditions: [{ [H]: c, [I]: [b, z] }, B], - rules: [ - { - endpoint: { - url: "https://sts-fips.{Region}.{PartitionResult#dualStackDnsSuffix}", - properties: v, - headers: v, - }, - [G]: h, - }, - ], - [G]: j, - }, - { error: "FIPS and DualStack are enabled, but this partition does not support one or both", [G]: k }, - ], - [G]: j, - }, - { - conditions: D, - rules: [ - { - conditions: [{ [H]: c, [I]: [z, b] }], - rules: [ - { - conditions: [{ [H]: d, [I]: [{ [H]: l, [I]: [A, "name"] }, "aws-us-gov"] }], - endpoint: { url: "https://sts.{Region}.amazonaws.com", properties: v, headers: v }, - [G]: h, - }, - { - endpoint: { - url: "https://sts-fips.{Region}.{PartitionResult#dnsSuffix}", - properties: v, - headers: v, - }, - [G]: h, - }, - ], - [G]: j, - }, - { error: "FIPS is enabled but this partition does not support FIPS", [G]: k }, - ], - [G]: j, - }, - { - conditions: E, - rules: [ - { - conditions: [B], - rules: [ - { - endpoint: { - url: "https://sts.{Region}.{PartitionResult#dualStackDnsSuffix}", - properties: v, - headers: v, - }, - [G]: h, - }, - ], - [G]: j, - }, - { error: "DualStack is enabled but this partition does not support DualStack", [G]: k }, - ], - [G]: j, - }, - w, - { endpoint: { url: i, properties: v, headers: v }, [G]: h }, - ], - [G]: j, - }, - ], - [G]: j, - }, - { error: "Invalid Configuration: Missing Region", [G]: k }, - ], -}; +const F="required", +G="type", +H="fn", +I="argv", +J="ref"; +const a=false, +b=true, +c="booleanEquals", +d="stringEquals", +e="sigv4", +f="sts", +g="us-east-1", +h="endpoint", +i="https://sts.{Region}.{PartitionResult#dnsSuffix}", +j="tree", +k="error", +l="getAttr", +m={[F]:false,[G]:"String"}, +n={[F]:true,"default":false,[G]:"Boolean"}, +o={[J]:"Endpoint"}, +p={[H]:"isSet",[I]:[{[J]:"Region"}]}, +q={[J]:"Region"}, +r={[H]:"aws.partition",[I]:[q],"assign":"PartitionResult"}, +s={[J]:"UseFIPS"}, +t={[J]:"UseDualStack"}, +u={"url":"https://sts.amazonaws.com","properties":{"authSchemes":[{"name":e,"signingName":f,"signingRegion":g}]},"headers":{}}, +v={}, +w={"conditions":[{[H]:d,[I]:[q,"aws-global"]}],[h]:u,[G]:h}, +x={[H]:c,[I]:[s,true]}, +y={[H]:c,[I]:[t,true]}, +z={[H]:l,[I]:[{[J]:"PartitionResult"},"supportsFIPS"]}, +A={[J]:"PartitionResult"}, +B={[H]:c,[I]:[true,{[H]:l,[I]:[A,"supportsDualStack"]}]}, +C=[{[H]:"isSet",[I]:[o]}], +D=[x], +E=[y]; +const _data={version:"1.0",parameters:{Region:m,UseDualStack:n,UseFIPS:n,Endpoint:m,UseGlobalEndpoint:n},rules:[{conditions:[{[H]:c,[I]:[{[J]:"UseGlobalEndpoint"},b]},{[H]:"not",[I]:C},p,r,{[H]:c,[I]:[s,a]},{[H]:c,[I]:[t,a]}],rules:[{conditions:[{[H]:d,[I]:[q,"ap-northeast-1"]}],endpoint:u,[G]:h},{conditions:[{[H]:d,[I]:[q,"ap-south-1"]}],endpoint:u,[G]:h},{conditions:[{[H]:d,[I]:[q,"ap-southeast-1"]}],endpoint:u,[G]:h},{conditions:[{[H]:d,[I]:[q,"ap-southeast-2"]}],endpoint:u,[G]:h},w,{conditions:[{[H]:d,[I]:[q,"ca-central-1"]}],endpoint:u,[G]:h},{conditions:[{[H]:d,[I]:[q,"eu-central-1"]}],endpoint:u,[G]:h},{conditions:[{[H]:d,[I]:[q,"eu-north-1"]}],endpoint:u,[G]:h},{conditions:[{[H]:d,[I]:[q,"eu-west-1"]}],endpoint:u,[G]:h},{conditions:[{[H]:d,[I]:[q,"eu-west-2"]}],endpoint:u,[G]:h},{conditions:[{[H]:d,[I]:[q,"eu-west-3"]}],endpoint:u,[G]:h},{conditions:[{[H]:d,[I]:[q,"sa-east-1"]}],endpoint:u,[G]:h},{conditions:[{[H]:d,[I]:[q,g]}],endpoint:u,[G]:h},{conditions:[{[H]:d,[I]:[q,"us-east-2"]}],endpoint:u,[G]:h},{conditions:[{[H]:d,[I]:[q,"us-west-1"]}],endpoint:u,[G]:h},{conditions:[{[H]:d,[I]:[q,"us-west-2"]}],endpoint:u,[G]:h},{endpoint:{url:i,properties:{authSchemes:[{name:e,signingName:f,signingRegion:"{Region}"}]},headers:v},[G]:h}],[G]:j},{conditions:C,rules:[{conditions:D,error:"Invalid Configuration: FIPS and custom endpoint are not supported",[G]:k},{conditions:E,error:"Invalid Configuration: Dualstack and custom endpoint are not supported",[G]:k},{endpoint:{url:o,properties:v,headers:v},[G]:h}],[G]:j},{conditions:[p],rules:[{conditions:[r],rules:[{conditions:[x,y],rules:[{conditions:[{[H]:c,[I]:[b,z]},B],rules:[{endpoint:{url:"https://sts-fips.{Region}.{PartitionResult#dualStackDnsSuffix}",properties:v,headers:v},[G]:h}],[G]:j},{error:"FIPS and DualStack are enabled, but this partition does not support one or both",[G]:k}],[G]:j},{conditions:D,rules:[{conditions:[{[H]:c,[I]:[z,b]}],rules:[{conditions:[{[H]:d,[I]:[{[H]:l,[I]:[A,"name"]},"aws-us-gov"]}],endpoint:{url:"https://sts.{Region}.amazonaws.com",properties:v,headers:v},[G]:h},{endpoint:{url:"https://sts-fips.{Region}.{PartitionResult#dnsSuffix}",properties:v,headers:v},[G]:h}],[G]:j},{error:"FIPS is enabled but this partition does not support FIPS",[G]:k}],[G]:j},{conditions:E,rules:[{conditions:[B],rules:[{endpoint:{url:"https://sts.{Region}.{PartitionResult#dualStackDnsSuffix}",properties:v,headers:v},[G]:h}],[G]:j},{error:"DualStack is enabled but this partition does not support DualStack",[G]:k}],[G]:j},w,{endpoint:{url:i,properties:v,headers:v},[G]:h}],[G]:j}],[G]:j},{error:"Invalid Configuration: Missing Region",[G]:k}]}; export const ruleSet: RuleSetObject = _data; diff --git a/packages/types/src/identity/AwsCredentialIdentity.ts b/packages/types/src/identity/AwsCredentialIdentity.ts index 1e7e87fccddaf..6fe23d7071ccb 100644 --- a/packages/types/src/identity/AwsCredentialIdentity.ts +++ b/packages/types/src/identity/AwsCredentialIdentity.ts @@ -1,21 +1,33 @@ -import type { AwsCredentialIdentity, AwsCredentialIdentityProvider } from "@smithy/types"; +import type { AwsCredentialIdentity, AwsCredentialIdentityProvider, Logger, RequestHandler } from "@smithy/types"; import type { AwsSdkCredentialsFeatures } from "../feature-ids"; - export { AwsCredentialIdentity, AwsCredentialIdentityProvider, IdentityProvider } from "@smithy/types"; /** * @public */ export interface AwsIdentityProperties { + /** + * These are resolved client config values, and may be async providers. + */ callerClientConfig?: { - region(): Promise; - profile?: string; + /** + * It is likely a programming error if you use + * the caller client config credentials in a credential provider, since + * it will recurse. + * + * @deprecated do not use. + */ + credentials?: AwsCredentialIdentity | AwsCredentialIdentityProvider; /** * @internal - * @deprecated + * @deprecated minimize use. */ credentialDefaultProvider?: (input?: any) => AwsCredentialIdentityProvider; + logger?: Logger; + profile?: string; + region(): Promise; + requestHandler?: RequestHandler; }; } diff --git a/yarn.lock b/yarn.lock index 3cc909fc0113e..0d0a3620df505 100644 --- a/yarn.lock +++ b/yarn.lock @@ -22577,6 +22577,7 @@ __metadata: "@aws-sdk/credential-provider-web-identity": "npm:*" "@aws-sdk/nested-clients": "npm:*" "@aws-sdk/types": "npm:*" + "@smithy/core": "npm:^3.0.0" "@smithy/credential-provider-imds": "npm:^4.0.0" "@smithy/property-provider": "npm:^4.0.0" "@smithy/types": "npm:^4.0.0"