aws-eks-token
Version:
Generate EKS token with signature v4 signing process.
91 lines (85 loc) • 4.11 kB
JavaScript
const AWS = require('aws-sdk');
const Promise = require("bluebird");
const crypto = require("crypto-js");
const { SHA256, HmacSHA256 } = crypto;
const { Hex, Base64, Utf8 } = crypto.enc;
const dayjs = require('dayjs');
const utc = require('dayjs/plugin/utc')
dayjs.extend(utc)
module.exports = class EKSToken {
static _config = new AWS.Config();
static preInspection() {
return Promise.fromCallback((cb) => {
this._config.getCredentials(cb);
});
}
static renew(clusterName = 'eks-cluster', expires = '60', formatTime) {
return this.preInspection().then((resolve) => {
const [accessKeyId, secretAccessKey, sessionToken, region] = [
this._config.credentials.accessKeyId,
this._config.credentials.secretAccessKey,
this._config.credentials.sessionToken,
this._config.region
];
if (!accessKeyId || !secretAccessKey || !region) {
throw new Error('Lose the accessKeyId, secretAccessKey or region');
}
// YYYYMMDD'T'HHMMSS'Z'
const fullDate = formatTime || dayjs.utc().format('YYYYMMDDTHHmmss[Z]');
const subDate = fullDate.substring(0, 8);
const tokenHeader = sessionToken ? `X-Amz-Security-Token=${encodeURIComponent(sessionToken)}&` : '';
const canonicalRequest =
'GET' + '\n' +
'/' + '\n' +
'Action=GetCallerIdentity&' +
'Version=2011-06-15&' +
'X-Amz-Algorithm=AWS4-HMAC-SHA256&' +
`X-Amz-Credential=${accessKeyId}%2F${subDate}%2F${region}%2Fsts%2Faws4_request&` +
`X-Amz-Date=${fullDate}&` +
`X-Amz-Expires=${expires}&` +
tokenHeader +
`X-Amz-SignedHeaders=host%3Bx-k8s-aws-id` + '\n' +
`host:sts.${region}.amazonaws.com\nx-k8s-aws-id:${clusterName}\n` + '\n' +
'host;x-k8s-aws-id' + '\n' +
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855';
const hashedCanonicalRequest = Hex.stringify(SHA256(canonicalRequest));
const stringToSign =
'AWS4-HMAC-SHA256' + '\n' +
fullDate + '\n' +
`${subDate}/${region}/sts/aws4_request` + '\n' +
hashedCanonicalRequest;
const signingKey = ((key, dateStamp, regionName, serviceName) => {
var kDate = HmacSHA256(dateStamp, "AWS4" + key);
var kRegion = HmacSHA256(regionName, kDate);
var kService = HmacSHA256(serviceName, kRegion);
var kSigning = HmacSHA256("aws4_request", kService);
return kSigning;
})(secretAccessKey, subDate, region, 'sts');
const signature = Hex.stringify(HmacSHA256(stringToSign, signingKey));
const presignedURL =
`https://sts.${region}.amazonaws.com/?` +
'Action=GetCallerIdentity&' +
'Version=2011-06-15&' +
'X-Amz-Algorithm=AWS4-HMAC-SHA256&' +
`X-Amz-Credential=${accessKeyId}%2F${subDate}%2F${region}%2Fsts%2Faws4_request&` +
`X-Amz-Date=${fullDate}&` +
`X-Amz-Expires=${expires}&` +
tokenHeader +
'X-Amz-SignedHeaders=host%3Bx-k8s-aws-id&' +
`X-Amz-Signature=${signature}`;
const base64Encoding = Base64.stringify(Utf8.parse(presignedURL))
// for url safe
.replace(/\+/g, '-') // Convert '+' to '-'
.replace(/\//g, '_') // Convert '/' to '_'
.replace(/=+$/, ''); // Remove ending '='
const eksToken = 'k8s-aws-v1.' + base64Encoding;
return eksToken;
})
}
static get config() {
return this._config;
}
static set config(option) {
option && this._config.update(option);
}
}