diff --git a/packages/credential-provider-cognito-identity/src/fromCognitoIdentity.ts b/packages/credential-provider-cognito-identity/src/fromCognitoIdentity.ts index 7e8f03fb4cfeb..7b90018f43289 100644 --- a/packages/credential-provider-cognito-identity/src/fromCognitoIdentity.ts +++ b/packages/credential-provider-cognito-identity/src/fromCognitoIdentity.ts @@ -30,7 +30,7 @@ export type CognitoIdentityCredentialProvider = Provider => { - parameters.logger?.debug("@aws-sdk/credential-provider-cognito-identity", "fromCognitoIdentity"); + parameters.logger?.debug("@aws-sdk/credential-provider-cognito-identity - fromCognitoIdentity"); const { GetCredentialsForIdentityCommand, CognitoIdentityClient } = await import("./loadCognitoIdentity"); const { diff --git a/packages/credential-provider-cognito-identity/src/fromCognitoIdentityPool.ts b/packages/credential-provider-cognito-identity/src/fromCognitoIdentityPool.ts index 47a59413097a1..559b281897274 100644 --- a/packages/credential-provider-cognito-identity/src/fromCognitoIdentityPool.ts +++ b/packages/credential-provider-cognito-identity/src/fromCognitoIdentityPool.ts @@ -30,7 +30,7 @@ export function fromCognitoIdentityPool({ logger, parentClientConfig, }: FromCognitoIdentityPoolParameters): CognitoIdentityCredentialProvider { - logger?.debug("@aws-sdk/credential-provider-cognito-identity", "fromCognitoIdentity"); + logger?.debug("@aws-sdk/credential-provider-cognito-identity - fromCognitoIdentity"); const cacheKey: string | undefined = userIdentifier ? `aws:cognito-identity-credentials:${identityPoolId}:${userIdentifier}` : undefined; diff --git a/packages/credential-provider-env/src/fromEnv.ts b/packages/credential-provider-env/src/fromEnv.ts index 5dc3e86632c2e..0b9aeeb58eef7 100644 --- a/packages/credential-provider-env/src/fromEnv.ts +++ b/packages/credential-provider-env/src/fromEnv.ts @@ -35,7 +35,7 @@ export const ENV_CREDENTIAL_SCOPE = "AWS_CREDENTIAL_SCOPE"; export const fromEnv = (init?: FromEnvInit): AwsCredentialIdentityProvider => async () => { - init?.logger?.debug("@aws-sdk/credential-provider-env", "fromEnv"); + init?.logger?.debug("@aws-sdk/credential-provider-env - fromEnv"); const accessKeyId: string | undefined = process.env[ENV_KEY]; const secretAccessKey: string | undefined = process.env[ENV_SECRET]; const sessionToken: string | undefined = process.env[ENV_SESSION]; diff --git a/packages/credential-provider-http/src/fromHttp/fromHttp.browser.ts b/packages/credential-provider-http/src/fromHttp/fromHttp.browser.ts index afe5e2bd45ebb..7068a9e10b37f 100644 --- a/packages/credential-provider-http/src/fromHttp/fromHttp.browser.ts +++ b/packages/credential-provider-http/src/fromHttp/fromHttp.browser.ts @@ -11,7 +11,7 @@ import { retryWrapper } from "./retry-wrapper"; * Creates a provider that gets credentials via HTTP request. */ export const fromHttp = (options: FromHttpOptions = {}): AwsCredentialIdentityProvider => { - options.logger?.debug("@aws-sdk/credential-provider-http", "fromHttp"); + options.logger?.debug("@aws-sdk/credential-provider-http - fromHttp"); let host: string; const full = options.credentialsFullUri; diff --git a/packages/credential-provider-http/src/fromHttp/fromHttp.ts b/packages/credential-provider-http/src/fromHttp/fromHttp.ts index 54dbced62f6d2..287ab3a12a931 100644 --- a/packages/credential-provider-http/src/fromHttp/fromHttp.ts +++ b/packages/credential-provider-http/src/fromHttp/fromHttp.ts @@ -18,7 +18,7 @@ const AWS_CONTAINER_AUTHORIZATION_TOKEN = "AWS_CONTAINER_AUTHORIZATION_TOKEN"; * Creates a provider that gets credentials via HTTP request. */ export const fromHttp = (options: FromHttpOptions = {}): AwsCredentialIdentityProvider => { - options.logger?.debug("@aws-sdk/credential-provider-http", "fromHttp"); + options.logger?.debug("@aws-sdk/credential-provider-http - fromHttp"); let host: string; const relative = options.awsContainerCredentialsRelativeUri ?? process.env[AWS_CONTAINER_CREDENTIALS_RELATIVE_URI]; diff --git a/packages/credential-provider-http/src/fromHttp/requestHelpers.ts b/packages/credential-provider-http/src/fromHttp/requestHelpers.ts index d4d340f5d07ff..9fb0c0afb35de 100644 --- a/packages/credential-provider-http/src/fromHttp/requestHelpers.ts +++ b/packages/credential-provider-http/src/fromHttp/requestHelpers.ts @@ -53,8 +53,7 @@ export async function getCredentials(response: HttpResponse, logger?: Logger): P throw new CredentialsProviderError( "HTTP credential provider response not of the required format, an object matching: " + "{ AccessKeyId: string, SecretAccessKey: string, Token: string, Expiration: string(rfc3339) }", - void 0, - logger + { logger } ); } diff --git a/packages/credential-provider-ini/src/fromIni.ts b/packages/credential-provider-ini/src/fromIni.ts index 253f5b3935e2a..9fcb65e376dbb 100644 --- a/packages/credential-provider-ini/src/fromIni.ts +++ b/packages/credential-provider-ini/src/fromIni.ts @@ -56,7 +56,7 @@ export interface FromIniInit extends SourceProfileInit, CredentialProviderOption export const fromIni = (init: FromIniInit = {}): AwsCredentialIdentityProvider => async () => { - init.logger?.debug("@aws-sdk/credential-provider-ini", "fromIni"); + init.logger?.debug("@aws-sdk/credential-provider-ini - fromIni"); const profiles = await parseKnownFiles(init); return resolveProfileData(getProfileName(init), profiles, init); }; diff --git a/packages/credential-provider-ini/src/resolveAssumeRoleCredentials.ts b/packages/credential-provider-ini/src/resolveAssumeRoleCredentials.ts index c8bbca3a4f3b8..114fdd08ed185 100644 --- a/packages/credential-provider-ini/src/resolveAssumeRoleCredentials.ts +++ b/packages/credential-provider-ini/src/resolveAssumeRoleCredentials.ts @@ -1,6 +1,6 @@ import { CredentialsProviderError } from "@smithy/property-provider"; import { getProfileName } from "@smithy/shared-ini-file-loader"; -import { AwsCredentialIdentity, ParsedIniData, Profile } from "@smithy/types"; +import { AwsCredentialIdentity, Logger, ParsedIniData, Profile } from "@smithy/types"; import { FromIniInit } from "./fromIni"; import { resolveCredentialSource } from "./resolveCredentialSource"; @@ -59,20 +59,42 @@ interface AssumeRoleWithProviderProfile extends Profile { /** * @internal */ -export const isAssumeRoleProfile = (arg: any) => - Boolean(arg) && - typeof arg === "object" && - typeof arg.role_arn === "string" && - ["undefined", "string"].indexOf(typeof arg.role_session_name) > -1 && - ["undefined", "string"].indexOf(typeof arg.external_id) > -1 && - ["undefined", "string"].indexOf(typeof arg.mfa_serial) > -1 && - (isAssumeRoleWithSourceProfile(arg) || isAssumeRoleWithProviderProfile(arg)); +export const isAssumeRoleProfile = ( + arg: any, + { profile = "default", logger }: { profile: string; logger?: Logger } +) => { + return ( + Boolean(arg) && + typeof arg === "object" && + typeof arg.role_arn === "string" && + ["undefined", "string"].indexOf(typeof arg.role_session_name) > -1 && + ["undefined", "string"].indexOf(typeof arg.external_id) > -1 && + ["undefined", "string"].indexOf(typeof arg.mfa_serial) > -1 && + (isAssumeRoleWithSourceProfile(arg, { profile, logger }) || isCredentialSourceProfile(arg, { profile, logger })) + ); +}; -const isAssumeRoleWithSourceProfile = (arg: any): arg is AssumeRoleWithSourceProfile => - typeof arg.source_profile === "string" && typeof arg.credential_source === "undefined"; +const isAssumeRoleWithSourceProfile = ( + arg: any, + { profile, logger }: { profile: string; logger?: Logger } +): arg is AssumeRoleWithSourceProfile => { + const withSourceProfile = typeof arg.source_profile === "string" && typeof arg.credential_source === "undefined"; + if (withSourceProfile) { + logger?.debug?.(` ${profile} isAssumeRoleWithSourceProfile source_profile=${arg.source_profile}`); + } + return withSourceProfile; +}; -const isAssumeRoleWithProviderProfile = (arg: any): arg is AssumeRoleWithProviderProfile => - typeof arg.credential_source === "string" && typeof arg.source_profile === "undefined"; +const isCredentialSourceProfile = ( + arg: any, + { profile, logger }: { profile: string; logger?: Logger } +): arg is AssumeRoleWithProviderProfile => { + const withProviderProfile = typeof arg.credential_source === "string" && typeof arg.source_profile === "undefined"; + if (withProviderProfile) { + logger?.debug?.(` ${profile} isCredentialSourceProfile credential_source=${arg.credential_source}`); + } + return withProviderProfile; +}; /** * @internal @@ -83,7 +105,7 @@ export const resolveAssumeRoleCredentials = async ( options: FromIniInit, visitedProfiles: Record = {} ) => { - options.logger?.debug("@aws-sdk/credential-provider-ini", "resolveAssumeRoleCredentials (STS)"); + options.logger?.debug("@aws-sdk/credential-provider-ini - resolveAssumeRoleCredentials (STS)"); const data = profiles[profileName]; if (!options.roleAssumer) { @@ -109,11 +131,31 @@ export const resolveAssumeRoleCredentials = async ( ); } + options.logger?.debug( + `@aws-sdk/credential-provider-ini - finding credential resolver using ${ + source_profile ? `source_profile=[${source_profile}]` : `profile=[${profileName}]` + }` + ); + const sourceCredsProvider: Promise = source_profile - ? resolveProfileData(source_profile, profiles, options, { - ...visitedProfiles, - [source_profile]: true, - }) + ? resolveProfileData( + source_profile, + { + ...profiles, + [source_profile]: { + ...profiles[source_profile], + // This assigns the role_arn of the "root" profile + // to the credential_source profile so this recursive call knows + // what role to assume. + role_arn: data.role_arn ?? profiles[source_profile].role_arn, + }, + }, + options, + { + ...visitedProfiles, + [source_profile]: true, + } + ) : (await resolveCredentialSource(data.credential_source!, profileName, options.logger)(options))(); const params: AssumeRoleParams = { diff --git a/packages/credential-provider-ini/src/resolveCredentialSource.ts b/packages/credential-provider-ini/src/resolveCredentialSource.ts index 6c23f2a0c8351..8c4efb47617f0 100644 --- a/packages/credential-provider-ini/src/resolveCredentialSource.ts +++ b/packages/credential-provider-ini/src/resolveCredentialSource.ts @@ -20,18 +20,18 @@ export const resolveCredentialSource = ( EcsContainer: async (options?: CredentialProviderOptions) => { const { fromHttp } = await import("@aws-sdk/credential-provider-http"); const { fromContainerMetadata } = await import("@smithy/credential-provider-imds"); - logger?.debug("@aws-sdk/credential-provider-ini", "credential_source EcsContainer"); + logger?.debug("@aws-sdk/credential-provider-ini - credential_source is EcsContainer"); return chain(fromHttp(options ?? {}), fromContainerMetadata(options)); }, - Ec2InstanceMetadata: (options?: CredentialProviderOptions) => { - logger?.debug("@aws-sdk/credential-provider-ini", "credential_source Ec2InstanceMetadata"); - return import("@smithy/credential-provider-imds").then(({ fromInstanceMetadata }) => - fromInstanceMetadata(options) - ); + Ec2InstanceMetadata: async (options?: CredentialProviderOptions) => { + logger?.debug("@aws-sdk/credential-provider-ini - credential_source is Ec2InstanceMetadata"); + const { fromInstanceMetadata } = await import("@smithy/credential-provider-imds"); + return fromInstanceMetadata(options); }, - Environment: (options?: CredentialProviderOptions) => { - logger?.debug("@aws-sdk/credential-provider-ini", "credential_source Environment"); - return import("@aws-sdk/credential-provider-env").then(({ fromEnv }) => fromEnv(options)); + Environment: async (options?: CredentialProviderOptions) => { + logger?.debug("@aws-sdk/credential-provider-ini - credential_source is Environment"); + const { fromEnv } = await import("@aws-sdk/credential-provider-env"); + return fromEnv(options); }, }; if (credentialSource in sourceProvidersMap) { diff --git a/packages/credential-provider-ini/src/resolveProfileData.ts b/packages/credential-provider-ini/src/resolveProfileData.ts index e7fd6d7325ae6..ea35a74ffe2fe 100644 --- a/packages/credential-provider-ini/src/resolveProfileData.ts +++ b/packages/credential-provider-ini/src/resolveProfileData.ts @@ -28,7 +28,7 @@ export const resolveProfileData = async ( // If this is the first profile visited, role assumption keys should be // given precedence over static credentials. - if (isAssumeRoleProfile(data)) { + if (isAssumeRoleProfile(data, { profile: profileName, logger: options.logger })) { return resolveAssumeRoleCredentials(profileName, profiles, options, visitedProfiles); } @@ -60,7 +60,7 @@ export const resolveProfileData = async ( // (whether via a parameter, an environment variable, or another profile's // `source_profile` key). throw new CredentialsProviderError( - `Profile ${profileName} could not be found or parsed in shared credentials file.`, + `Could not resolve credentials using profile: [${profileName}] in configuration/credentials file(s).`, { logger: options.logger } ); }; diff --git a/packages/credential-provider-ini/src/resolveStaticCredentials.ts b/packages/credential-provider-ini/src/resolveStaticCredentials.ts index 012dda732f063..c9ced1a540c38 100644 --- a/packages/credential-provider-ini/src/resolveStaticCredentials.ts +++ b/packages/credential-provider-ini/src/resolveStaticCredentials.ts @@ -29,7 +29,7 @@ export const resolveStaticCredentials = ( profile: StaticCredsProfile, options?: FromIniInit ): Promise => { - options?.logger?.debug("@aws-sdk/credential-provider-ini", "resolveStaticCredentials"); + options?.logger?.debug("@aws-sdk/credential-provider-ini - resolveStaticCredentials"); return Promise.resolve({ accessKeyId: profile.aws_access_key_id, secretAccessKey: profile.aws_secret_access_key, diff --git a/packages/credential-provider-node/src/defaultProvider.ts b/packages/credential-provider-node/src/defaultProvider.ts index f1642875b6186..72101174ee62f 100644 --- a/packages/credential-provider-node/src/defaultProvider.ts +++ b/packages/credential-provider-node/src/defaultProvider.ts @@ -60,12 +60,12 @@ export const defaultProvider = (init: DefaultProviderInit = {}): MemoizedProvide ? [] : [ async () => { - init.logger?.debug("@aws-sdk/credential-provider-node", "defaultProvider::fromEnv"); + init.logger?.debug("@aws-sdk/credential-provider-node - defaultProvider::fromEnv"); return fromEnv(init)(); }, ]), async () => { - init.logger?.debug("@aws-sdk/credential-provider-node", "defaultProvider::fromSSO"); + init.logger?.debug("@aws-sdk/credential-provider-node - defaultProvider::fromSSO"); const { ssoStartUrl, ssoAccountId, ssoRegion, ssoRoleName, ssoSession } = init; if (!ssoStartUrl && !ssoAccountId && !ssoRegion && !ssoRoleName && !ssoSession) { throw new CredentialsProviderError( @@ -77,22 +77,22 @@ export const defaultProvider = (init: DefaultProviderInit = {}): MemoizedProvide return fromSSO(init)(); }, async () => { - init.logger?.debug("@aws-sdk/credential-provider-node", "defaultProvider::fromIni"); + init.logger?.debug("@aws-sdk/credential-provider-node - defaultProvider::fromIni"); const { fromIni } = await import("@aws-sdk/credential-provider-ini"); return fromIni(init)(); }, async () => { - init.logger?.debug("@aws-sdk/credential-provider-node", "defaultProvider::fromProcess"); + init.logger?.debug("@aws-sdk/credential-provider-node - defaultProvider::fromProcess"); const { fromProcess } = await import("@aws-sdk/credential-provider-process"); return fromProcess(init)(); }, async () => { - init.logger?.debug("@aws-sdk/credential-provider-node", "defaultProvider::fromTokenFile"); + init.logger?.debug("@aws-sdk/credential-provider-node - defaultProvider::fromTokenFile"); const { fromTokenFile } = await import("@aws-sdk/credential-provider-web-identity"); return fromTokenFile(init)(); }, async () => { - init.logger?.debug("@aws-sdk/credential-provider-node", "defaultProvider::remoteProvider"); + init.logger?.debug("@aws-sdk/credential-provider-node - defaultProvider::remoteProvider"); return (await remoteProvider(init))(); }, async () => { diff --git a/packages/credential-provider-node/src/remoteProvider.ts b/packages/credential-provider-node/src/remoteProvider.ts index 46c8dbf025617..7f64789be0828 100644 --- a/packages/credential-provider-node/src/remoteProvider.ts +++ b/packages/credential-provider-node/src/remoteProvider.ts @@ -16,7 +16,7 @@ export const remoteProvider = async (init: RemoteProviderInit): Promise async () => { - init.logger?.debug("@aws-sdk/credential-provider-process", "fromProcess"); + init.logger?.debug("@aws-sdk/credential-provider-process - fromProcess"); const profiles = await parseKnownFiles(init); return resolveProcessCredentials(getProfileName(init), profiles, init.logger); }; diff --git a/packages/credential-provider-sso/src/fromSSO.ts b/packages/credential-provider-sso/src/fromSSO.ts index 7ee590ef41e42..0e1d3ab56aae2 100644 --- a/packages/credential-provider-sso/src/fromSSO.ts +++ b/packages/credential-provider-sso/src/fromSSO.ts @@ -81,7 +81,7 @@ export interface FromSSOInit extends SourceProfileInit, CredentialProviderOption export const fromSSO = (init: FromSSOInit & Partial = {}): AwsCredentialIdentityProvider => async () => { - init.logger?.debug("@aws-sdk/credential-provider-sso", "fromSSO"); + init.logger?.debug("@aws-sdk/credential-provider-sso - fromSSO"); const { ssoStartUrl, ssoAccountId, ssoRegion, ssoRoleName, ssoSession } = init; const { ssoClient } = init; const profileName = getProfileName(init); diff --git a/packages/credential-provider-sso/src/resolveSSOCredentials.ts b/packages/credential-provider-sso/src/resolveSSOCredentials.ts index e3837d9fcbce0..b1c7a4692a64b 100644 --- a/packages/credential-provider-sso/src/resolveSSOCredentials.ts +++ b/packages/credential-provider-sso/src/resolveSSOCredentials.ts @@ -77,7 +77,10 @@ export const resolveSSOCredentials = async ({ }) ); } catch (e) { - throw CredentialsProviderError.from(e, SHOULD_FAIL_CREDENTIAL_CHAIN); + throw new CredentialsProviderError(e, { + tryNextLink: SHOULD_FAIL_CREDENTIAL_CHAIN, + logger, + }); } const { roleCredentials: { accessKeyId, secretAccessKey, sessionToken, expiration, credentialScope } = {} } = diff --git a/packages/credential-provider-web-identity/src/fromTokenFile.ts b/packages/credential-provider-web-identity/src/fromTokenFile.ts index 19d6ee0803e7a..fc39fc626e305 100644 --- a/packages/credential-provider-web-identity/src/fromTokenFile.ts +++ b/packages/credential-provider-web-identity/src/fromTokenFile.ts @@ -29,7 +29,7 @@ export interface FromTokenFileInit export const fromTokenFile = (init: FromTokenFileInit = {}): AwsCredentialIdentityProvider => async () => { - init.logger?.debug("@aws-sdk/credential-provider-web-identity", "fromTokenFile"); + init.logger?.debug("@aws-sdk/credential-provider-web-identity - fromTokenFile"); const webIdentityTokenFile = init?.webIdentityTokenFile ?? process.env[ENV_TOKEN_FILE]; const roleArn = init?.roleArn ?? process.env[ENV_ROLE_ARN]; const roleSessionName = init?.roleSessionName ?? process.env[ENV_ROLE_SESSION_NAME]; diff --git a/packages/credential-provider-web-identity/src/fromWebToken.ts b/packages/credential-provider-web-identity/src/fromWebToken.ts index c94b3725e6a60..cc550ea8f977e 100644 --- a/packages/credential-provider-web-identity/src/fromWebToken.ts +++ b/packages/credential-provider-web-identity/src/fromWebToken.ts @@ -153,7 +153,7 @@ export interface FromWebTokenInit export const fromWebToken = (init: FromWebTokenInit): AwsCredentialIdentityProvider => async () => { - init.logger?.debug("@aws-sdk/credential-provider-web-identity", "fromWebToken"); + init.logger?.debug("@aws-sdk/credential-provider-web-identity - fromWebToken"); const { roleArn, roleSessionName, webIdentityToken, providerId, policyArns, policy, durationSeconds } = init; let { roleAssumerWithWebIdentity } = init; diff --git a/packages/credential-providers/src/fromTemporaryCredentials.ts b/packages/credential-providers/src/fromTemporaryCredentials.ts index a9ecbd6a03b8a..a20ace99d1712 100644 --- a/packages/credential-providers/src/fromTemporaryCredentials.ts +++ b/packages/credential-providers/src/fromTemporaryCredentials.ts @@ -54,7 +54,7 @@ export interface FromTemporaryCredentialsOptions extends CredentialProviderOptio export const fromTemporaryCredentials = (options: FromTemporaryCredentialsOptions): AwsCredentialIdentityProvider => { let stsClient: STSClient; return async (): Promise => { - options.logger?.debug("@aws-sdk/credential-providers", "fromTemporaryCredentials (STS)"); + options.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) { diff --git a/packages/token-providers/src/fromSso.ts b/packages/token-providers/src/fromSso.ts index 91aada276a2fb..a65e6febd3efb 100644 --- a/packages/token-providers/src/fromSso.ts +++ b/packages/token-providers/src/fromSso.ts @@ -28,7 +28,7 @@ export interface FromSsoInit extends SourceProfileInit, CredentialProviderOption export const fromSso = (init: FromSsoInit = {}): TokenIdentityProvider => async () => { - init.logger?.debug("@aws-sdk/token-providers", "fromSso"); + init.logger?.debug("@aws-sdk/token-providers - fromSso"); const profiles = await parseKnownFiles(init); const profileName = getProfileName(init); diff --git a/packages/token-providers/src/fromStatic.ts b/packages/token-providers/src/fromStatic.ts index 58e738ca0c7f5..308b8e6fc927a 100644 --- a/packages/token-providers/src/fromStatic.ts +++ b/packages/token-providers/src/fromStatic.ts @@ -11,7 +11,7 @@ export interface FromStaticInit extends CredentialProviderOptions { export const fromStatic = ({ token, logger }: FromStaticInit): TokenIdentityProvider => async () => { - logger?.debug("@aws-sdk/token-providers", "fromStatic"); + logger?.debug("@aws-sdk/token-providers - fromStatic"); if (!token || !token.token) { throw new TokenProviderError(`Please pass a valid token to fromStatic`, false); }