mirror of
https://github.com/jambonz/speech-utils.git
synced 2025-12-19 03:37:49 +00:00
79 lines
3.1 KiB
JavaScript
79 lines
3.1 KiB
JavaScript
const { STSClient, GetSessionTokenCommand, AssumeRoleCommand } = require('@aws-sdk/client-sts');
|
|
const {makeAwsKey, noopLogger} = require('./utils');
|
|
const debug = require('debug')('jambonz:speech-utils');
|
|
const EXPIRY = process.env.AWS_STS_SESSION_DURATION || 3600;
|
|
// by default reset aws session before expiry time 10 mins
|
|
const CACHE_EXPIRY = process.env.AWS_STS_SESSION_RESET_EXPIRY || (EXPIRY - 600);
|
|
|
|
async function getAwsAuthToken(
|
|
logger, createHash, retrieveHash,
|
|
{speech_credential_sid, accessKeyId, secretAccessKey, region, roleArn}) {
|
|
logger = logger || noopLogger;
|
|
try {
|
|
// if incase instance profile is used, speech_credential_sid will be used as key to lookup cache
|
|
const key = makeAwsKey(roleArn || accessKeyId || speech_credential_sid);
|
|
const obj = await retrieveHash(key);
|
|
if (obj) return {...obj, servedFromCache: true};
|
|
/* access token not found in cache, so generate it using STS */
|
|
let data;
|
|
let expiry = CACHE_EXPIRY;
|
|
if (roleArn) {
|
|
const stsClient = new STSClient({ region });
|
|
const roleToAssume = { RoleArn: roleArn, RoleSessionName: 'Jambonz_Speech', DurationSeconds: EXPIRY};
|
|
const command = new AssumeRoleCommand(roleToAssume);
|
|
|
|
data = await stsClient.send(command);
|
|
} else if (accessKeyId) {
|
|
const stsClient = new STSClient({
|
|
region,
|
|
credentials: {
|
|
accessKeyId,
|
|
secretAccessKey,
|
|
}
|
|
});
|
|
const command = new GetSessionTokenCommand({DurationSeconds: EXPIRY});
|
|
data = await stsClient.send(command);
|
|
} else {
|
|
// instance profile is used.
|
|
const stsClient = new STSClient({ region });
|
|
const cred = await stsClient.config.credentials();
|
|
// method in the AWS SDK automatically fetches credentials using the default credential
|
|
// provider chain. If the credentials come from an instance profile or an environment
|
|
// variable, their expiration is controlled by AWS and not explicitly by our code.
|
|
if (cred && cred.expiration) {
|
|
const currentTime = new Date();
|
|
const expiryTime = new Date(cred.expiration);
|
|
const remainingTimeInSeconds = Math.round((expiryTime - currentTime) / 1000);
|
|
expiry = remainingTimeInSeconds;
|
|
}
|
|
data = {
|
|
Credentials: {
|
|
AccessKeyId: cred.accessKeyId,
|
|
SecretAccessKey: cred.secretAccessKey,
|
|
SessionToken: cred.sessionToken
|
|
}
|
|
};
|
|
}
|
|
|
|
const credentials = {
|
|
accessKeyId: data.Credentials.AccessKeyId,
|
|
secretAccessKey: data.Credentials.SecretAccessKey,
|
|
sessionToken: data.Credentials.SessionToken,
|
|
securityToken: data.Credentials.SessionToken
|
|
};
|
|
// Only cache if expiry is good
|
|
if (expiry > 0) {
|
|
createHash(key, credentials, expiry)
|
|
.catch((err) => logger.error(err, `Error saving hash for key ${key}`));
|
|
}
|
|
|
|
return {...credentials, servedFromCache: false};
|
|
} catch (err) {
|
|
debug(err, 'getAwsAuthToken: Error retrieving AWS auth token');
|
|
logger.error(err, 'getAwsAuthToken: Error retrieving AWS auth token');
|
|
throw err;
|
|
}
|
|
}
|
|
|
|
module.exports = getAwsAuthToken;
|