ruimarinho / gsts

Obtain and store AWS STS credentials to interact with Amazon services by authenticating via G Suite SAML.
MIT License
222 stars 38 forks source link

gsts v5.0.0 can't handle multiple profiles #84

Closed sherif-fanous closed 1 year ago

sherif-fanous commented 1 year ago

Hi

When more than 1 profile in ~/.aws/config is set up to use a gsts based credential_process the following issues are observed

  1. If the gsts credentials file doesn't exist then this file is created and the credentials are saved to the file correctly
  2. If the gsts credentials file does exist but the profile name being used is different than the initial profile through which the credentials file was created then a ProfileNotFoundError exception is thrown here.
  3. gsts always tries to overwrite the gsts credentials file in saveCredentials instead of modifying the file if it already exists.

From my perspective the 2nd and 3rd bullets are bugs.

Proposed solution for the 2nd bullet is to gracefully handle the profile not found and retrieve credentials for this profile

index.js

if (!session) {
  logger.info('Profile %s not found', argv.awsProfile);
} else if (session.isValid()) {

credentials-manager.js

if (!credentials[profile]) {
  return null;
}

Proposed fix for 3rd bullet is to create the file with the profile if the file doesn't exist. If the file exists then just update it by adding/updating the profile

credentials-manager.js

 /**
 * Save AWS credentials to a profile section.
 */

async saveCredentials(profile, session) {
  let contents;

  try {
    const credentials = ini.parse(await readFile(this.credentialsFile, 'utf-8'));

    this.logger.info(`Loaded credentials from "${this.credentialsFile}" for profile "${profile}".`);

    credentials[profile] = session.toIni(profile)[profile];

    contents = ini.encode(credentials)
  } catch (e) {
    if (e.code === 'ENOENT') {
      contents = ini.encode(session.toIni(profile));
    } else {
      throw e;
    }
  }

  await mkdir(dirname(this.credentialsFile), { recursive: true });
  await writeFile(this.credentialsFile, contents);
  await chmod(this.credentialsFile, constants.S_IRUSR | constants.S_IWUSR);

  this.logger.info('The credentials have been stored in "%s" under AWS profile "%s"', this.credentialsFile, profile);
  this.logger.debug('Contents for credentials file "%s" is: \n %o', this.credentialsFile, contents);
}
ruimarinho commented 1 year ago

Should be fixed by https://github.com/ruimarinho/gsts/pull/99.