-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Token file web identity credentials (#2737)
- Loading branch information
Showing
8 changed files
with
311 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"type": "feature", | ||
"category": "Credentials", | ||
"description": "Added TokenFileWebIdentityCredentials" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import {Credentials} from '../credentials'; | ||
import {AWSError} from '../error'; | ||
import {ConfigurationOptions} from '../config'; | ||
export class TokenFileWebIdentityCredentials extends Credentials { | ||
/** | ||
* Creates a new credentials object with optional configuraion. | ||
* @param {Object} clientConfig - a map of configuration options to pass to the underlying STS client. | ||
*/ | ||
constructor(clientConfig?: ConfigurationOptions); | ||
/** | ||
* Refreshes credentials using AWS.STS.assumeRoleWithWebIdentity(). | ||
*/ | ||
refresh(callback: (err: AWSError) => void): void; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
var AWS = require('../core'); | ||
var fs = require('fs'); | ||
var STS = require('../../clients/sts'); | ||
var iniLoader = AWS.util.iniLoader; | ||
|
||
/** | ||
* Represents OIDC credentials from a file on disk | ||
* If the credentials expire, the SDK can {refresh} the credentials | ||
* from the file. | ||
* | ||
* ## Using the web identity token file | ||
* | ||
* This provider is checked by default in the Node.js environment. To use | ||
* the provider simply add your OIDC token to a file (ASCII encoding) and | ||
* share the filename in either AWS_WEB_IDENTITY_TOKEN_FILE environment | ||
* variable or web_identity_token_file shared config variable | ||
* | ||
* The file contains encoded OIDC token and the characters are | ||
* ASCII encoded. OIDC tokens are JSON Web Tokens (JWT). | ||
* JWT's are 3 base64 encoded strings joined by the '.' character. | ||
* | ||
* This class will read filename from AWS_WEB_IDENTITY_TOKEN_FILE | ||
* environment variable or web_identity_token_file shared config variable, | ||
* and get the OIDC token from filename. | ||
* It will also read IAM role to be assumed from AWS_IAM_ROLE_ARN | ||
* environment variable or role_arn shared config variable. | ||
* This provider gets credetials using the {AWS.STS.assumeRoleWithWebIdentity} | ||
* service operation | ||
* | ||
* @!macro nobrowser | ||
*/ | ||
AWS.TokenFileWebIdentityCredentials = AWS.util.inherit(AWS.Credentials, { | ||
|
||
/** | ||
* @example Creating a new credentials object | ||
* AWS.config.credentials = new AWS.TokenFileWebIdentityCredentials( | ||
* // optionally provide configuration to apply to the underlying AWS.STS service client | ||
* // if configuration is not provided, then configuration will be pulled from AWS.config | ||
* { | ||
* // specify timeout options | ||
* httpOptions: { | ||
* timeout: 100 | ||
* } | ||
* }); | ||
* @see AWS.Config | ||
*/ | ||
constructor: function TokenFileWebIdentityCredentials(clientConfig) { | ||
AWS.Credentials.call(this); | ||
this.data = null; | ||
this.clientConfig = AWS.util.copy(clientConfig || {}); | ||
}, | ||
|
||
/** | ||
* Returns params from environment variables | ||
* | ||
* @api private | ||
*/ | ||
getParamsFromEnv: function getParamsFromEnv() { | ||
var ENV_TOKEN_FILE = 'AWS_WEB_IDENTITY_TOKEN_FILE', | ||
ENV_ROLE_ARN = 'AWS_IAM_ROLE_ARN'; | ||
if (process.env[ENV_TOKEN_FILE] && process.env[ENV_ROLE_ARN]) { | ||
return { | ||
envTokenFile: process.env[ENV_TOKEN_FILE], | ||
roleArn: process.env[ENV_ROLE_ARN], | ||
roleSessionName: process.env['AWS_IAM_ROLE_SESSION_NAME'] | ||
}; | ||
} | ||
}, | ||
|
||
/** | ||
* Returns params from shared config variables | ||
* | ||
* @api private | ||
*/ | ||
getParamsFromSharedConfig: function getParamsFromSharedConfig() { | ||
var profiles = AWS.util.getProfilesFromSharedConfig(iniLoader); | ||
var profileName = process.env.AWS_PROFILE || AWS.util.defaultProfile; | ||
var profile = profiles[profileName] || {}; | ||
|
||
if (Object.keys(profile).length === 0) { | ||
throw AWS.util.error( | ||
new Error('Profile ' + profileName + ' not found'), | ||
{ code: 'TokenFileWebIdentityCredentialsProviderFailure' } | ||
); | ||
} | ||
|
||
return { | ||
envTokenFile: profile['web_identity_token_file'], | ||
roleArn: profile['role_arn'], | ||
roleSessionName: profile['role_session_name'] | ||
}; | ||
}, | ||
|
||
/** | ||
* Refreshes credentials using {AWS.STS.assumeRoleWithWebIdentity} | ||
* | ||
* @callback callback function(err) | ||
* Called when the STS service responds (or fails). When | ||
* this callback is called with no error, it means that the credentials | ||
* information has been loaded into the object (as the `accessKeyId`, | ||
* `secretAccessKey`, and `sessionToken` properties). | ||
* @param err [Error] if an error occurred, this value will be filled | ||
* @see AWS.Credentials.get | ||
*/ | ||
refresh: function refresh(callback) { | ||
this.coalesceRefresh(callback || AWS.util.fn.callback); | ||
}, | ||
|
||
/** | ||
* @api private | ||
*/ | ||
load: function load(callback) { | ||
var self = this; | ||
try { | ||
var params = self.getParamsFromEnv(); | ||
if (!params) { | ||
params = self.getParamsFromSharedConfig(); | ||
} | ||
if (params) { | ||
var oidcToken = fs.readFileSync(params.envTokenFile, {encoding: 'ascii'}); | ||
if (self.service) { | ||
self.service.config.params.WebIdentityToken = oidcToken; | ||
} else { | ||
self.createClients({ | ||
WebIdentityToken: oidcToken, | ||
RoleArn: params.roleArn, | ||
RoleSessionName: params.roleSessionName || 'token-file-web-identity' | ||
}); | ||
} | ||
self.service.assumeRoleWithWebIdentity(function (err, data) { | ||
self.data = null; | ||
if (!err) { | ||
self.data = data; | ||
self.service.credentialsFrom(data, self); | ||
} | ||
callback(err); | ||
}); | ||
} | ||
} catch (err) { | ||
callback(err); | ||
} | ||
}, | ||
|
||
/** | ||
* @api private | ||
*/ | ||
createClients: function(params) { | ||
if (!this.service) { | ||
var stsConfig = AWS.util.merge({}, this.clientConfig); | ||
stsConfig.params = params; | ||
this.service = new STS(stsConfig); | ||
|
||
// Retry in case of IDPCommunicationErrorException or InvalidIdentityToken | ||
this.service.retryableError = function(error) { | ||
if (error.code === 'IDPCommunicationErrorException' || error.code === 'InvalidIdentityToken') { | ||
return true; | ||
} else { | ||
return AWS.Service.prototype.retryableError.call(this, error); | ||
} | ||
}; | ||
} | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.