in lib/credentials/shared_ini_file_credentials.js [179:283]
loadRoleProfile: function loadRoleProfile(creds, roleProfile, callback) {
if (this.disableAssumeRole) {
throw AWS.util.error(
new Error('Role assumption profiles are disabled. ' +
'Failed to load profile ' + this.profile +
' from ' + creds.filename),
{ code: 'SharedIniFileCredentialsProviderFailure' }
);
}
var self = this;
var roleArn = roleProfile['role_arn'];
var roleSessionName = roleProfile['role_session_name'];
var externalId = roleProfile['external_id'];
var mfaSerial = roleProfile['mfa_serial'];
var sourceProfileName = roleProfile['source_profile'];
var durationSeconds = parseInt(roleProfile['duration_seconds'], 10) || undefined;
// From experimentation, the following behavior mimics the AWS CLI:
//
// 1. Use region from the profile if present.
// 2. Otherwise fall back to N. Virginia (global endpoint).
//
// It is necessary to do the fallback explicitly, because if
// 'AWS_STS_REGIONAL_ENDPOINTS=regional', the underlying STS client will
// otherwise throw an error if region is left 'undefined'.
//
// Experimentation shows that the AWS CLI (tested at version 1.18.136)
// ignores the following potential sources of a region for the purposes of
// this AssumeRole call:
//
// - The [default] profile
// - The AWS_REGION environment variable
//
// Ignoring the [default] profile for the purposes of AssumeRole is arguably
// a bug in the CLI since it does use the [default] region for service
// calls... but right now we're matching behavior of the other tool.
var profileRegion = roleProfile['region'] || ASSUME_ROLE_DEFAULT_REGION;
if (!sourceProfileName) {
throw AWS.util.error(
new Error('source_profile is not set using profile ' + this.profile),
{ code: 'SharedIniFileCredentialsProviderFailure' }
);
}
var sourceProfileExistanceTest = creds[sourceProfileName];
if (typeof sourceProfileExistanceTest !== 'object') {
throw AWS.util.error(
new Error('source_profile ' + sourceProfileName + ' using profile '
+ this.profile + ' does not exist'),
{ code: 'SharedIniFileCredentialsProviderFailure' }
);
}
var sourceCredentials = new AWS.SharedIniFileCredentials(
AWS.util.merge(this.options || {}, {
profile: sourceProfileName,
preferStaticCredentials: true
})
);
this.roleArn = roleArn;
var sts = new STS({
credentials: sourceCredentials,
region: profileRegion,
httpOptions: this.httpOptions
});
var roleParams = {
DurationSeconds: durationSeconds,
RoleArn: roleArn,
RoleSessionName: roleSessionName || 'aws-sdk-js-' + Date.now()
};
if (externalId) {
roleParams.ExternalId = externalId;
}
if (mfaSerial && self.tokenCodeFn) {
roleParams.SerialNumber = mfaSerial;
self.tokenCodeFn(mfaSerial, function(err, token) {
if (err) {
var message;
if (err instanceof Error) {
message = err.message;
} else {
message = err;
}
callback(
AWS.util.error(
new Error('Error fetching MFA token: ' + message),
{ code: 'SharedIniFileCredentialsProviderFailure' }
));
return;
}
roleParams.TokenCode = token;
sts.assumeRole(roleParams, callback);
});
return;
}
sts.assumeRole(roleParams, callback);
}