44 */
55
66import * as AWS from '@aws-sdk/types'
7- import { AssumeRoleParams , fromIni } from '@aws-sdk/credential-provider-ini'
87import { fromProcess } from '@aws-sdk/credential-provider-process'
9- import { ParsedIniData , SharedConfigFiles } from '@smithy/shared-ini-file-loader '
8+ import { ParsedIniData } from '@smithy/types '
109import { chain } from '@aws-sdk/property-provider'
1110import { fromInstanceMetadata , fromContainerMetadata } from '@aws-sdk/credential-provider-imds'
1211import { fromEnv } from '@aws-sdk/credential-provider-env'
@@ -32,6 +31,8 @@ import {
3231import { SectionName , SharedCredentialsKeys } from '../credentials/types'
3332import { SsoProfile , hasScopes , scopesSsoAccountAccess } from '../connection'
3433import { builderIdStartUrl } from '../sso/constants'
34+ import { ToolkitError } from '../../shared'
35+ import { STS } from 'aws-sdk'
3536
3637const credentialSources = {
3738 ECS_CONTAINER : 'EcsContainer' ,
@@ -378,18 +379,6 @@ export class SharedCredentialsProvider implements CredentialsProvider {
378379 }
379380
380381 private makeSharedIniFileCredentialsProvider ( loadedCreds ?: ParsedIniData ) : AWS . CredentialProvider {
381- const assumeRole = async ( credentials : AWS . Credentials , params : AssumeRoleParams ) => {
382- const region = this . getDefaultRegion ( ) ?? 'us-east-1'
383- const stsClient = new DefaultStsClient ( region , credentials )
384- const response = await stsClient . assumeRole ( params )
385- return {
386- accessKeyId : response . Credentials ! . AccessKeyId ! ,
387- secretAccessKey : response . Credentials ! . SecretAccessKey ! ,
388- sessionToken : response . Credentials ?. SessionToken ,
389- expiration : response . Credentials ?. Expiration ,
390- }
391- }
392-
393382 // Our credentials logic merges profiles from the credentials and config files but SDK v3 does not
394383 // This can cause odd behavior where the Toolkit can switch to a profile but not authenticate with it
395384 // So the workaround is to do give the SDK the merged profiles directly
@@ -399,15 +388,40 @@ export class SharedCredentialsProvider implements CredentialsProvider {
399388 ( k ) => this . getProfile ( k )
400389 )
401390
402- return fromIni ( {
403- profile : this . profileName ,
404- mfaCodeProvider : async ( mfaSerial ) => await getMfaTokenFromUser ( mfaSerial , this . profileName ) ,
405- roleAssumer : assumeRole ,
406- loadedConfig : Promise . resolve ( {
407- credentialsFile : loadedCreds ?? profiles ,
408- configFile : { } ,
409- } as SharedConfigFiles ) ,
410- } )
391+ return async ( ) => {
392+ const profile = ( loadedCreds ?? profiles ) [ this . profileName ]
393+ if ( ! profile ) {
394+ throw new ToolkitError ( `auth: Profile ${ this . profileName } not found` )
395+ }
396+ // No role to assume, return static credentials.
397+ if ( ! profile . role_arn ) {
398+ return {
399+ accessKeyId : profile . aws_access_key_id ! ,
400+ secretAccessKey : profile . aws_secret_access_key ! ,
401+ sessionToken : profile . aws_session_token ,
402+ }
403+ }
404+
405+ const stsClient = new DefaultStsClient ( this . getDefaultRegion ( ) ?? 'us-east-1' )
406+ const assumeRoleReq : STS . AssumeRoleRequest = profile . aws_mfa_serial
407+ ? {
408+ RoleArn : profile . role_arn ,
409+ RoleSessionName : 'AssumeRoleSession' ,
410+ SerialNumber : profile . aws_mfa_serial ,
411+ TokenCode : await getMfaTokenFromUser ( profile . aws_mfa_serial , this . profileName ) ,
412+ }
413+ : {
414+ RoleArn : profile . role_arn ,
415+ RoleSessionName : 'AssumeRoleSession' ,
416+ }
417+ const assumeRoleRsp = await stsClient . assumeRole ( assumeRoleReq )
418+ return {
419+ accessKeyId : assumeRoleRsp . Credentials ! . AccessKeyId ! ,
420+ secretAccessKey : assumeRoleRsp . Credentials ! . AccessKeyId ! ,
421+ sessionToken : assumeRoleRsp . Credentials ?. AccessKeyId ,
422+ expiration : assumeRoleRsp . Credentials ?. Expiration ,
423+ }
424+ }
411425 }
412426
413427 private makeSourcedCredentialsProvider ( ) : AWS . CredentialProvider {
0 commit comments