@smithy/credential-provider-imds
Advanced tools
Comparing version 2.1.5 to 2.2.0
@@ -1,8 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Endpoint = void 0; | ||
var Endpoint; | ||
(function (Endpoint) { | ||
Endpoint["IPv4"] = "http://169.254.169.254"; | ||
Endpoint["IPv6"] = "http://[fd00:ec2::254]"; | ||
})(Endpoint = exports.Endpoint || (exports.Endpoint = {})); | ||
module.exports = require("../index.js"); |
@@ -1,10 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ENDPOINT_CONFIG_OPTIONS = exports.CONFIG_ENDPOINT_NAME = exports.ENV_ENDPOINT_NAME = void 0; | ||
exports.ENV_ENDPOINT_NAME = "AWS_EC2_METADATA_SERVICE_ENDPOINT"; | ||
exports.CONFIG_ENDPOINT_NAME = "ec2_metadata_service_endpoint"; | ||
exports.ENDPOINT_CONFIG_OPTIONS = { | ||
environmentVariableSelector: (env) => env[exports.ENV_ENDPOINT_NAME], | ||
configFileSelector: (profile) => profile[exports.CONFIG_ENDPOINT_NAME], | ||
default: undefined, | ||
}; | ||
module.exports = require("../index.js"); |
@@ -1,8 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.EndpointMode = void 0; | ||
var EndpointMode; | ||
(function (EndpointMode) { | ||
EndpointMode["IPv4"] = "IPv4"; | ||
EndpointMode["IPv6"] = "IPv6"; | ||
})(EndpointMode = exports.EndpointMode || (exports.EndpointMode = {})); | ||
module.exports = require("../index.js"); |
@@ -1,11 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ENDPOINT_MODE_CONFIG_OPTIONS = exports.CONFIG_ENDPOINT_MODE_NAME = exports.ENV_ENDPOINT_MODE_NAME = void 0; | ||
const EndpointMode_1 = require("./EndpointMode"); | ||
exports.ENV_ENDPOINT_MODE_NAME = "AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE"; | ||
exports.CONFIG_ENDPOINT_MODE_NAME = "ec2_metadata_service_endpoint_mode"; | ||
exports.ENDPOINT_MODE_CONFIG_OPTIONS = { | ||
environmentVariableSelector: (env) => env[exports.ENV_ENDPOINT_MODE_NAME], | ||
configFileSelector: (profile) => profile[exports.CONFIG_ENDPOINT_MODE_NAME], | ||
default: EndpointMode_1.EndpointMode.IPv4, | ||
}; | ||
module.exports = require("../index.js"); |
@@ -1,13 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.InstanceMetadataV1FallbackError = void 0; | ||
const property_provider_1 = require("@smithy/property-provider"); | ||
class InstanceMetadataV1FallbackError extends property_provider_1.CredentialsProviderError { | ||
constructor(message, tryNextLink = true) { | ||
super(message, tryNextLink); | ||
this.tryNextLink = tryNextLink; | ||
this.name = "InstanceMetadataV1FallbackError"; | ||
Object.setPrototypeOf(this, InstanceMetadataV1FallbackError.prototype); | ||
} | ||
} | ||
exports.InstanceMetadataV1FallbackError = InstanceMetadataV1FallbackError; | ||
module.exports = require("../index.js"); |
@@ -1,70 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.fromContainerMetadata = exports.ENV_CMDS_AUTH_TOKEN = exports.ENV_CMDS_RELATIVE_URI = exports.ENV_CMDS_FULL_URI = void 0; | ||
const property_provider_1 = require("@smithy/property-provider"); | ||
const url_1 = require("url"); | ||
const httpRequest_1 = require("./remoteProvider/httpRequest"); | ||
const ImdsCredentials_1 = require("./remoteProvider/ImdsCredentials"); | ||
const RemoteProviderInit_1 = require("./remoteProvider/RemoteProviderInit"); | ||
const retry_1 = require("./remoteProvider/retry"); | ||
exports.ENV_CMDS_FULL_URI = "AWS_CONTAINER_CREDENTIALS_FULL_URI"; | ||
exports.ENV_CMDS_RELATIVE_URI = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"; | ||
exports.ENV_CMDS_AUTH_TOKEN = "AWS_CONTAINER_AUTHORIZATION_TOKEN"; | ||
const fromContainerMetadata = (init = {}) => { | ||
const { timeout, maxRetries } = (0, RemoteProviderInit_1.providerConfigFromInit)(init); | ||
return () => (0, retry_1.retry)(async () => { | ||
const requestOptions = await getCmdsUri(); | ||
const credsResponse = JSON.parse(await requestFromEcsImds(timeout, requestOptions)); | ||
if (!(0, ImdsCredentials_1.isImdsCredentials)(credsResponse)) { | ||
throw new property_provider_1.CredentialsProviderError("Invalid response received from instance metadata service."); | ||
} | ||
return (0, ImdsCredentials_1.fromImdsCredentials)(credsResponse); | ||
}, maxRetries); | ||
}; | ||
exports.fromContainerMetadata = fromContainerMetadata; | ||
const requestFromEcsImds = async (timeout, options) => { | ||
if (process.env[exports.ENV_CMDS_AUTH_TOKEN]) { | ||
options.headers = { | ||
...options.headers, | ||
Authorization: process.env[exports.ENV_CMDS_AUTH_TOKEN], | ||
}; | ||
} | ||
const buffer = await (0, httpRequest_1.httpRequest)({ | ||
...options, | ||
timeout, | ||
}); | ||
return buffer.toString(); | ||
}; | ||
const CMDS_IP = "169.254.170.2"; | ||
const GREENGRASS_HOSTS = { | ||
localhost: true, | ||
"127.0.0.1": true, | ||
}; | ||
const GREENGRASS_PROTOCOLS = { | ||
"http:": true, | ||
"https:": true, | ||
}; | ||
const getCmdsUri = async () => { | ||
if (process.env[exports.ENV_CMDS_RELATIVE_URI]) { | ||
return { | ||
hostname: CMDS_IP, | ||
path: process.env[exports.ENV_CMDS_RELATIVE_URI], | ||
}; | ||
} | ||
if (process.env[exports.ENV_CMDS_FULL_URI]) { | ||
const parsed = (0, url_1.parse)(process.env[exports.ENV_CMDS_FULL_URI]); | ||
if (!parsed.hostname || !(parsed.hostname in GREENGRASS_HOSTS)) { | ||
throw new property_provider_1.CredentialsProviderError(`${parsed.hostname} is not a valid container metadata service hostname`, false); | ||
} | ||
if (!parsed.protocol || !(parsed.protocol in GREENGRASS_PROTOCOLS)) { | ||
throw new property_provider_1.CredentialsProviderError(`${parsed.protocol} is not a valid container metadata service protocol`, false); | ||
} | ||
return { | ||
...parsed, | ||
port: parsed.port ? parseInt(parsed.port, 10) : undefined, | ||
}; | ||
} | ||
throw new property_provider_1.CredentialsProviderError("The container metadata credential provider cannot be used unless" + | ||
` the ${exports.ENV_CMDS_RELATIVE_URI} or ${exports.ENV_CMDS_FULL_URI} environment` + | ||
" variable is set", false); | ||
}; | ||
module.exports = require("./index.js"); |
@@ -1,137 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.fromInstanceMetadata = void 0; | ||
const node_config_provider_1 = require("@smithy/node-config-provider"); | ||
const property_provider_1 = require("@smithy/property-provider"); | ||
const InstanceMetadataV1FallbackError_1 = require("./error/InstanceMetadataV1FallbackError"); | ||
const httpRequest_1 = require("./remoteProvider/httpRequest"); | ||
const ImdsCredentials_1 = require("./remoteProvider/ImdsCredentials"); | ||
const RemoteProviderInit_1 = require("./remoteProvider/RemoteProviderInit"); | ||
const retry_1 = require("./remoteProvider/retry"); | ||
const getInstanceMetadataEndpoint_1 = require("./utils/getInstanceMetadataEndpoint"); | ||
const staticStabilityProvider_1 = require("./utils/staticStabilityProvider"); | ||
const IMDS_PATH = "/latest/meta-data/iam/security-credentials/"; | ||
const IMDS_TOKEN_PATH = "/latest/api/token"; | ||
const AWS_EC2_METADATA_V1_DISABLED = "AWS_EC2_METADATA_V1_DISABLED"; | ||
const PROFILE_AWS_EC2_METADATA_V1_DISABLED = "ec2_metadata_v1_disabled"; | ||
const X_AWS_EC2_METADATA_TOKEN = "x-aws-ec2-metadata-token"; | ||
const fromInstanceMetadata = (init = {}) => (0, staticStabilityProvider_1.staticStabilityProvider)(getInstanceImdsProvider(init), { logger: init.logger }); | ||
exports.fromInstanceMetadata = fromInstanceMetadata; | ||
const getInstanceImdsProvider = (init) => { | ||
let disableFetchToken = false; | ||
const { logger, profile } = init; | ||
const { timeout, maxRetries } = (0, RemoteProviderInit_1.providerConfigFromInit)(init); | ||
const getCredentials = async (maxRetries, options) => { | ||
var _a; | ||
const isImdsV1Fallback = disableFetchToken || ((_a = options.headers) === null || _a === void 0 ? void 0 : _a[X_AWS_EC2_METADATA_TOKEN]) == null; | ||
if (isImdsV1Fallback) { | ||
let fallbackBlockedFromProfile = false; | ||
let fallbackBlockedFromProcessEnv = false; | ||
const configValue = await (0, node_config_provider_1.loadConfig)({ | ||
environmentVariableSelector: (env) => { | ||
const envValue = env[AWS_EC2_METADATA_V1_DISABLED]; | ||
fallbackBlockedFromProcessEnv = !!envValue && envValue !== "false"; | ||
if (envValue === undefined) { | ||
throw new property_provider_1.CredentialsProviderError(`${AWS_EC2_METADATA_V1_DISABLED} not set in env, checking config file next.`); | ||
} | ||
return fallbackBlockedFromProcessEnv; | ||
}, | ||
configFileSelector: (profile) => { | ||
const profileValue = profile[PROFILE_AWS_EC2_METADATA_V1_DISABLED]; | ||
fallbackBlockedFromProfile = !!profileValue && profileValue !== "false"; | ||
return fallbackBlockedFromProfile; | ||
}, | ||
default: false, | ||
}, { | ||
profile, | ||
})(); | ||
if (init.ec2MetadataV1Disabled || configValue) { | ||
const causes = []; | ||
if (init.ec2MetadataV1Disabled) | ||
causes.push("credential provider initialization (runtime option ec2MetadataV1Disabled)"); | ||
if (fallbackBlockedFromProfile) | ||
causes.push(`config file profile (${PROFILE_AWS_EC2_METADATA_V1_DISABLED})`); | ||
if (fallbackBlockedFromProcessEnv) | ||
causes.push(`process environment variable (${AWS_EC2_METADATA_V1_DISABLED})`); | ||
throw new InstanceMetadataV1FallbackError_1.InstanceMetadataV1FallbackError(`AWS EC2 Metadata v1 fallback has been blocked by AWS SDK configuration in the following: [${causes.join(", ")}].`); | ||
} | ||
} | ||
const imdsProfile = (await (0, retry_1.retry)(async () => { | ||
let profile; | ||
try { | ||
profile = await getProfile(options); | ||
} | ||
catch (err) { | ||
if (err.statusCode === 401) { | ||
disableFetchToken = false; | ||
} | ||
throw err; | ||
} | ||
return profile; | ||
}, maxRetries)).trim(); | ||
return (0, retry_1.retry)(async () => { | ||
let creds; | ||
try { | ||
creds = await getCredentialsFromProfile(imdsProfile, options); | ||
} | ||
catch (err) { | ||
if (err.statusCode === 401) { | ||
disableFetchToken = false; | ||
} | ||
throw err; | ||
} | ||
return creds; | ||
}, maxRetries); | ||
}; | ||
return async () => { | ||
const endpoint = await (0, getInstanceMetadataEndpoint_1.getInstanceMetadataEndpoint)(); | ||
if (disableFetchToken) { | ||
logger === null || logger === void 0 ? void 0 : logger.debug("AWS SDK Instance Metadata", "using v1 fallback (no token fetch)"); | ||
return getCredentials(maxRetries, { ...endpoint, timeout }); | ||
} | ||
else { | ||
let token; | ||
try { | ||
token = (await getMetadataToken({ ...endpoint, timeout })).toString(); | ||
} | ||
catch (error) { | ||
if ((error === null || error === void 0 ? void 0 : error.statusCode) === 400) { | ||
throw Object.assign(error, { | ||
message: "EC2 Metadata token request returned error", | ||
}); | ||
} | ||
else if (error.message === "TimeoutError" || [403, 404, 405].includes(error.statusCode)) { | ||
disableFetchToken = true; | ||
} | ||
logger === null || logger === void 0 ? void 0 : logger.debug("AWS SDK Instance Metadata", "using v1 fallback (initial)"); | ||
return getCredentials(maxRetries, { ...endpoint, timeout }); | ||
} | ||
return getCredentials(maxRetries, { | ||
...endpoint, | ||
headers: { | ||
[X_AWS_EC2_METADATA_TOKEN]: token, | ||
}, | ||
timeout, | ||
}); | ||
} | ||
}; | ||
}; | ||
const getMetadataToken = async (options) => (0, httpRequest_1.httpRequest)({ | ||
...options, | ||
path: IMDS_TOKEN_PATH, | ||
method: "PUT", | ||
headers: { | ||
"x-aws-ec2-metadata-token-ttl-seconds": "21600", | ||
}, | ||
}); | ||
const getProfile = async (options) => (await (0, httpRequest_1.httpRequest)({ ...options, path: IMDS_PATH })).toString(); | ||
const getCredentialsFromProfile = async (profile, options) => { | ||
const credsResponse = JSON.parse((await (0, httpRequest_1.httpRequest)({ | ||
...options, | ||
path: IMDS_PATH + profile, | ||
})).toString()); | ||
if (!(0, ImdsCredentials_1.isImdsCredentials)(credsResponse)) { | ||
throw new property_provider_1.CredentialsProviderError("Invalid response received from instance metadata service."); | ||
} | ||
return (0, ImdsCredentials_1.fromImdsCredentials)(credsResponse); | ||
}; | ||
module.exports = require("./index.js"); |
@@ -1,12 +0,425 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getInstanceMetadataEndpoint = exports.httpRequest = void 0; | ||
const tslib_1 = require("tslib"); | ||
tslib_1.__exportStar(require("./fromContainerMetadata"), exports); | ||
tslib_1.__exportStar(require("./fromInstanceMetadata"), exports); | ||
tslib_1.__exportStar(require("./remoteProvider/RemoteProviderInit"), exports); | ||
tslib_1.__exportStar(require("./types"), exports); | ||
var httpRequest_1 = require("./remoteProvider/httpRequest"); | ||
Object.defineProperty(exports, "httpRequest", { enumerable: true, get: function () { return httpRequest_1.httpRequest; } }); | ||
var getInstanceMetadataEndpoint_1 = require("./utils/getInstanceMetadataEndpoint"); | ||
Object.defineProperty(exports, "getInstanceMetadataEndpoint", { enumerable: true, get: function () { return getInstanceMetadataEndpoint_1.getInstanceMetadataEndpoint; } }); | ||
var __defProp = Object.defineProperty; | ||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||
var __getOwnPropNames = Object.getOwnPropertyNames; | ||
var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); | ||
var __export = (target, all) => { | ||
for (var name in all) | ||
__defProp(target, name, { get: all[name], enumerable: true }); | ||
}; | ||
var __copyProps = (to, from, except, desc) => { | ||
if (from && typeof from === "object" || typeof from === "function") { | ||
for (let key of __getOwnPropNames(from)) | ||
if (!__hasOwnProp.call(to, key) && key !== except) | ||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||
} | ||
return to; | ||
}; | ||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||
// src/index.ts | ||
var src_exports = {}; | ||
__export(src_exports, { | ||
DEFAULT_MAX_RETRIES: () => DEFAULT_MAX_RETRIES, | ||
DEFAULT_TIMEOUT: () => DEFAULT_TIMEOUT, | ||
ENV_CMDS_AUTH_TOKEN: () => ENV_CMDS_AUTH_TOKEN, | ||
ENV_CMDS_FULL_URI: () => ENV_CMDS_FULL_URI, | ||
ENV_CMDS_RELATIVE_URI: () => ENV_CMDS_RELATIVE_URI, | ||
fromContainerMetadata: () => fromContainerMetadata, | ||
fromInstanceMetadata: () => fromInstanceMetadata, | ||
getInstanceMetadataEndpoint: () => getInstanceMetadataEndpoint, | ||
httpRequest: () => httpRequest, | ||
providerConfigFromInit: () => providerConfigFromInit | ||
}); | ||
module.exports = __toCommonJS(src_exports); | ||
// src/fromContainerMetadata.ts | ||
var import_url = require("url"); | ||
// src/remoteProvider/httpRequest.ts | ||
var import_property_provider = require("@smithy/property-provider"); | ||
var import_buffer = require("buffer"); | ||
var import_http = require("http"); | ||
function httpRequest(options) { | ||
return new Promise((resolve, reject) => { | ||
var _a; | ||
const req = (0, import_http.request)({ | ||
method: "GET", | ||
...options, | ||
// Node.js http module doesn't accept hostname with square brackets | ||
// Refs: https://github.com/nodejs/node/issues/39738 | ||
hostname: (_a = options.hostname) == null ? void 0 : _a.replace(/^\[(.+)\]$/, "$1") | ||
}); | ||
req.on("error", (err) => { | ||
reject(Object.assign(new import_property_provider.ProviderError("Unable to connect to instance metadata service"), err)); | ||
req.destroy(); | ||
}); | ||
req.on("timeout", () => { | ||
reject(new import_property_provider.ProviderError("TimeoutError from instance metadata service")); | ||
req.destroy(); | ||
}); | ||
req.on("response", (res) => { | ||
const { statusCode = 400 } = res; | ||
if (statusCode < 200 || 300 <= statusCode) { | ||
reject( | ||
Object.assign(new import_property_provider.ProviderError("Error response received from instance metadata service"), { statusCode }) | ||
); | ||
req.destroy(); | ||
} | ||
const chunks = []; | ||
res.on("data", (chunk) => { | ||
chunks.push(chunk); | ||
}); | ||
res.on("end", () => { | ||
resolve(import_buffer.Buffer.concat(chunks)); | ||
req.destroy(); | ||
}); | ||
}); | ||
req.end(); | ||
}); | ||
} | ||
__name(httpRequest, "httpRequest"); | ||
// src/remoteProvider/ImdsCredentials.ts | ||
var isImdsCredentials = /* @__PURE__ */ __name((arg) => Boolean(arg) && typeof arg === "object" && typeof arg.AccessKeyId === "string" && typeof arg.SecretAccessKey === "string" && typeof arg.Token === "string" && typeof arg.Expiration === "string", "isImdsCredentials"); | ||
var fromImdsCredentials = /* @__PURE__ */ __name((creds) => ({ | ||
accessKeyId: creds.AccessKeyId, | ||
secretAccessKey: creds.SecretAccessKey, | ||
sessionToken: creds.Token, | ||
expiration: new Date(creds.Expiration) | ||
}), "fromImdsCredentials"); | ||
// src/remoteProvider/RemoteProviderInit.ts | ||
var DEFAULT_TIMEOUT = 1e3; | ||
var DEFAULT_MAX_RETRIES = 0; | ||
var providerConfigFromInit = /* @__PURE__ */ __name(({ | ||
maxRetries = DEFAULT_MAX_RETRIES, | ||
timeout = DEFAULT_TIMEOUT | ||
}) => ({ maxRetries, timeout }), "providerConfigFromInit"); | ||
// src/remoteProvider/retry.ts | ||
var retry = /* @__PURE__ */ __name((toRetry, maxRetries) => { | ||
let promise = toRetry(); | ||
for (let i = 0; i < maxRetries; i++) { | ||
promise = promise.catch(toRetry); | ||
} | ||
return promise; | ||
}, "retry"); | ||
// src/fromContainerMetadata.ts | ||
var ENV_CMDS_FULL_URI = "AWS_CONTAINER_CREDENTIALS_FULL_URI"; | ||
var ENV_CMDS_RELATIVE_URI = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"; | ||
var ENV_CMDS_AUTH_TOKEN = "AWS_CONTAINER_AUTHORIZATION_TOKEN"; | ||
var fromContainerMetadata = /* @__PURE__ */ __name((init = {}) => { | ||
const { timeout, maxRetries } = providerConfigFromInit(init); | ||
return () => retry(async () => { | ||
const requestOptions = await getCmdsUri(); | ||
const credsResponse = JSON.parse(await requestFromEcsImds(timeout, requestOptions)); | ||
if (!isImdsCredentials(credsResponse)) { | ||
throw new import_property_provider.CredentialsProviderError("Invalid response received from instance metadata service."); | ||
} | ||
return fromImdsCredentials(credsResponse); | ||
}, maxRetries); | ||
}, "fromContainerMetadata"); | ||
var requestFromEcsImds = /* @__PURE__ */ __name(async (timeout, options) => { | ||
if (process.env[ENV_CMDS_AUTH_TOKEN]) { | ||
options.headers = { | ||
...options.headers, | ||
Authorization: process.env[ENV_CMDS_AUTH_TOKEN] | ||
}; | ||
} | ||
const buffer = await httpRequest({ | ||
...options, | ||
timeout | ||
}); | ||
return buffer.toString(); | ||
}, "requestFromEcsImds"); | ||
var CMDS_IP = "169.254.170.2"; | ||
var GREENGRASS_HOSTS = { | ||
localhost: true, | ||
"127.0.0.1": true | ||
}; | ||
var GREENGRASS_PROTOCOLS = { | ||
"http:": true, | ||
"https:": true | ||
}; | ||
var getCmdsUri = /* @__PURE__ */ __name(async () => { | ||
if (process.env[ENV_CMDS_RELATIVE_URI]) { | ||
return { | ||
hostname: CMDS_IP, | ||
path: process.env[ENV_CMDS_RELATIVE_URI] | ||
}; | ||
} | ||
if (process.env[ENV_CMDS_FULL_URI]) { | ||
const parsed = (0, import_url.parse)(process.env[ENV_CMDS_FULL_URI]); | ||
if (!parsed.hostname || !(parsed.hostname in GREENGRASS_HOSTS)) { | ||
throw new import_property_provider.CredentialsProviderError( | ||
`${parsed.hostname} is not a valid container metadata service hostname`, | ||
false | ||
); | ||
} | ||
if (!parsed.protocol || !(parsed.protocol in GREENGRASS_PROTOCOLS)) { | ||
throw new import_property_provider.CredentialsProviderError( | ||
`${parsed.protocol} is not a valid container metadata service protocol`, | ||
false | ||
); | ||
} | ||
return { | ||
...parsed, | ||
port: parsed.port ? parseInt(parsed.port, 10) : void 0 | ||
}; | ||
} | ||
throw new import_property_provider.CredentialsProviderError( | ||
`The container metadata credential provider cannot be used unless the ${ENV_CMDS_RELATIVE_URI} or ${ENV_CMDS_FULL_URI} environment variable is set`, | ||
false | ||
); | ||
}, "getCmdsUri"); | ||
// src/fromInstanceMetadata.ts | ||
// src/error/InstanceMetadataV1FallbackError.ts | ||
var _InstanceMetadataV1FallbackError = class _InstanceMetadataV1FallbackError extends import_property_provider.CredentialsProviderError { | ||
constructor(message, tryNextLink = true) { | ||
super(message, tryNextLink); | ||
this.tryNextLink = tryNextLink; | ||
this.name = "InstanceMetadataV1FallbackError"; | ||
Object.setPrototypeOf(this, _InstanceMetadataV1FallbackError.prototype); | ||
} | ||
}; | ||
__name(_InstanceMetadataV1FallbackError, "InstanceMetadataV1FallbackError"); | ||
var InstanceMetadataV1FallbackError = _InstanceMetadataV1FallbackError; | ||
// src/utils/getInstanceMetadataEndpoint.ts | ||
var import_node_config_provider = require("@smithy/node-config-provider"); | ||
var import_url_parser = require("@smithy/url-parser"); | ||
// src/config/EndpointConfigOptions.ts | ||
var ENV_ENDPOINT_NAME = "AWS_EC2_METADATA_SERVICE_ENDPOINT"; | ||
var CONFIG_ENDPOINT_NAME = "ec2_metadata_service_endpoint"; | ||
var ENDPOINT_CONFIG_OPTIONS = { | ||
environmentVariableSelector: (env) => env[ENV_ENDPOINT_NAME], | ||
configFileSelector: (profile) => profile[CONFIG_ENDPOINT_NAME], | ||
default: void 0 | ||
}; | ||
// src/config/EndpointMode.ts | ||
var EndpointMode = /* @__PURE__ */ ((EndpointMode2) => { | ||
EndpointMode2["IPv4"] = "IPv4"; | ||
EndpointMode2["IPv6"] = "IPv6"; | ||
return EndpointMode2; | ||
})(EndpointMode || {}); | ||
// src/config/EndpointModeConfigOptions.ts | ||
var ENV_ENDPOINT_MODE_NAME = "AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE"; | ||
var CONFIG_ENDPOINT_MODE_NAME = "ec2_metadata_service_endpoint_mode"; | ||
var ENDPOINT_MODE_CONFIG_OPTIONS = { | ||
environmentVariableSelector: (env) => env[ENV_ENDPOINT_MODE_NAME], | ||
configFileSelector: (profile) => profile[CONFIG_ENDPOINT_MODE_NAME], | ||
default: "IPv4" /* IPv4 */ | ||
}; | ||
// src/utils/getInstanceMetadataEndpoint.ts | ||
var getInstanceMetadataEndpoint = /* @__PURE__ */ __name(async () => (0, import_url_parser.parseUrl)(await getFromEndpointConfig() || await getFromEndpointModeConfig()), "getInstanceMetadataEndpoint"); | ||
var getFromEndpointConfig = /* @__PURE__ */ __name(async () => (0, import_node_config_provider.loadConfig)(ENDPOINT_CONFIG_OPTIONS)(), "getFromEndpointConfig"); | ||
var getFromEndpointModeConfig = /* @__PURE__ */ __name(async () => { | ||
const endpointMode = await (0, import_node_config_provider.loadConfig)(ENDPOINT_MODE_CONFIG_OPTIONS)(); | ||
switch (endpointMode) { | ||
case "IPv4" /* IPv4 */: | ||
return "http://169.254.169.254" /* IPv4 */; | ||
case "IPv6" /* IPv6 */: | ||
return "http://[fd00:ec2::254]" /* IPv6 */; | ||
default: | ||
throw new Error(`Unsupported endpoint mode: ${endpointMode}. Select from ${Object.values(EndpointMode)}`); | ||
} | ||
}, "getFromEndpointModeConfig"); | ||
// src/utils/getExtendedInstanceMetadataCredentials.ts | ||
var STATIC_STABILITY_REFRESH_INTERVAL_SECONDS = 5 * 60; | ||
var STATIC_STABILITY_REFRESH_INTERVAL_JITTER_WINDOW_SECONDS = 5 * 60; | ||
var STATIC_STABILITY_DOC_URL = "https://docs.aws.amazon.com/sdkref/latest/guide/feature-static-credentials.html"; | ||
var getExtendedInstanceMetadataCredentials = /* @__PURE__ */ __name((credentials, logger) => { | ||
const refreshInterval = STATIC_STABILITY_REFRESH_INTERVAL_SECONDS + Math.floor(Math.random() * STATIC_STABILITY_REFRESH_INTERVAL_JITTER_WINDOW_SECONDS); | ||
const newExpiration = new Date(Date.now() + refreshInterval * 1e3); | ||
logger.warn( | ||
"Attempting credential expiration extension due to a credential service availability issue. A refresh of these credentials will be attempted after ${new Date(newExpiration)}.\nFor more information, please visit: " + STATIC_STABILITY_DOC_URL | ||
); | ||
const originalExpiration = credentials.originalExpiration ?? credentials.expiration; | ||
return { | ||
...credentials, | ||
...originalExpiration ? { originalExpiration } : {}, | ||
expiration: newExpiration | ||
}; | ||
}, "getExtendedInstanceMetadataCredentials"); | ||
// src/utils/staticStabilityProvider.ts | ||
var staticStabilityProvider = /* @__PURE__ */ __name((provider, options = {}) => { | ||
const logger = (options == null ? void 0 : options.logger) || console; | ||
let pastCredentials; | ||
return async () => { | ||
let credentials; | ||
try { | ||
credentials = await provider(); | ||
if (credentials.expiration && credentials.expiration.getTime() < Date.now()) { | ||
credentials = getExtendedInstanceMetadataCredentials(credentials, logger); | ||
} | ||
} catch (e) { | ||
if (pastCredentials) { | ||
logger.warn("Credential renew failed: ", e); | ||
credentials = getExtendedInstanceMetadataCredentials(pastCredentials, logger); | ||
} else { | ||
throw e; | ||
} | ||
} | ||
pastCredentials = credentials; | ||
return credentials; | ||
}; | ||
}, "staticStabilityProvider"); | ||
// src/fromInstanceMetadata.ts | ||
var IMDS_PATH = "/latest/meta-data/iam/security-credentials/"; | ||
var IMDS_TOKEN_PATH = "/latest/api/token"; | ||
var AWS_EC2_METADATA_V1_DISABLED = "AWS_EC2_METADATA_V1_DISABLED"; | ||
var PROFILE_AWS_EC2_METADATA_V1_DISABLED = "ec2_metadata_v1_disabled"; | ||
var X_AWS_EC2_METADATA_TOKEN = "x-aws-ec2-metadata-token"; | ||
var fromInstanceMetadata = /* @__PURE__ */ __name((init = {}) => staticStabilityProvider(getInstanceImdsProvider(init), { logger: init.logger }), "fromInstanceMetadata"); | ||
var getInstanceImdsProvider = /* @__PURE__ */ __name((init) => { | ||
let disableFetchToken = false; | ||
const { logger, profile } = init; | ||
const { timeout, maxRetries } = providerConfigFromInit(init); | ||
const getCredentials = /* @__PURE__ */ __name(async (maxRetries2, options) => { | ||
var _a; | ||
const isImdsV1Fallback = disableFetchToken || ((_a = options.headers) == null ? void 0 : _a[X_AWS_EC2_METADATA_TOKEN]) == null; | ||
if (isImdsV1Fallback) { | ||
let fallbackBlockedFromProfile = false; | ||
let fallbackBlockedFromProcessEnv = false; | ||
const configValue = await (0, import_node_config_provider.loadConfig)( | ||
{ | ||
environmentVariableSelector: (env) => { | ||
const envValue = env[AWS_EC2_METADATA_V1_DISABLED]; | ||
fallbackBlockedFromProcessEnv = !!envValue && envValue !== "false"; | ||
if (envValue === void 0) { | ||
throw new import_property_provider.CredentialsProviderError( | ||
`${AWS_EC2_METADATA_V1_DISABLED} not set in env, checking config file next.` | ||
); | ||
} | ||
return fallbackBlockedFromProcessEnv; | ||
}, | ||
configFileSelector: (profile2) => { | ||
const profileValue = profile2[PROFILE_AWS_EC2_METADATA_V1_DISABLED]; | ||
fallbackBlockedFromProfile = !!profileValue && profileValue !== "false"; | ||
return fallbackBlockedFromProfile; | ||
}, | ||
default: false | ||
}, | ||
{ | ||
profile | ||
} | ||
)(); | ||
if (init.ec2MetadataV1Disabled || configValue) { | ||
const causes = []; | ||
if (init.ec2MetadataV1Disabled) | ||
causes.push("credential provider initialization (runtime option ec2MetadataV1Disabled)"); | ||
if (fallbackBlockedFromProfile) | ||
causes.push(`config file profile (${PROFILE_AWS_EC2_METADATA_V1_DISABLED})`); | ||
if (fallbackBlockedFromProcessEnv) | ||
causes.push(`process environment variable (${AWS_EC2_METADATA_V1_DISABLED})`); | ||
throw new InstanceMetadataV1FallbackError( | ||
`AWS EC2 Metadata v1 fallback has been blocked by AWS SDK configuration in the following: [${causes.join( | ||
", " | ||
)}].` | ||
); | ||
} | ||
} | ||
const imdsProfile = (await retry(async () => { | ||
let profile2; | ||
try { | ||
profile2 = await getProfile(options); | ||
} catch (err) { | ||
if (err.statusCode === 401) { | ||
disableFetchToken = false; | ||
} | ||
throw err; | ||
} | ||
return profile2; | ||
}, maxRetries2)).trim(); | ||
return retry(async () => { | ||
let creds; | ||
try { | ||
creds = await getCredentialsFromProfile(imdsProfile, options); | ||
} catch (err) { | ||
if (err.statusCode === 401) { | ||
disableFetchToken = false; | ||
} | ||
throw err; | ||
} | ||
return creds; | ||
}, maxRetries2); | ||
}, "getCredentials"); | ||
return async () => { | ||
const endpoint = await getInstanceMetadataEndpoint(); | ||
if (disableFetchToken) { | ||
logger == null ? void 0 : logger.debug("AWS SDK Instance Metadata", "using v1 fallback (no token fetch)"); | ||
return getCredentials(maxRetries, { ...endpoint, timeout }); | ||
} else { | ||
let token; | ||
try { | ||
token = (await getMetadataToken({ ...endpoint, timeout })).toString(); | ||
} catch (error) { | ||
if ((error == null ? void 0 : error.statusCode) === 400) { | ||
throw Object.assign(error, { | ||
message: "EC2 Metadata token request returned error" | ||
}); | ||
} else if (error.message === "TimeoutError" || [403, 404, 405].includes(error.statusCode)) { | ||
disableFetchToken = true; | ||
} | ||
logger == null ? void 0 : logger.debug("AWS SDK Instance Metadata", "using v1 fallback (initial)"); | ||
return getCredentials(maxRetries, { ...endpoint, timeout }); | ||
} | ||
return getCredentials(maxRetries, { | ||
...endpoint, | ||
headers: { | ||
[X_AWS_EC2_METADATA_TOKEN]: token | ||
}, | ||
timeout | ||
}); | ||
} | ||
}; | ||
}, "getInstanceImdsProvider"); | ||
var getMetadataToken = /* @__PURE__ */ __name(async (options) => httpRequest({ | ||
...options, | ||
path: IMDS_TOKEN_PATH, | ||
method: "PUT", | ||
headers: { | ||
"x-aws-ec2-metadata-token-ttl-seconds": "21600" | ||
} | ||
}), "getMetadataToken"); | ||
var getProfile = /* @__PURE__ */ __name(async (options) => (await httpRequest({ ...options, path: IMDS_PATH })).toString(), "getProfile"); | ||
var getCredentialsFromProfile = /* @__PURE__ */ __name(async (profile, options) => { | ||
const credsResponse = JSON.parse( | ||
(await httpRequest({ | ||
...options, | ||
path: IMDS_PATH + profile | ||
})).toString() | ||
); | ||
if (!isImdsCredentials(credsResponse)) { | ||
throw new import_property_provider.CredentialsProviderError("Invalid response received from instance metadata service."); | ||
} | ||
return fromImdsCredentials(credsResponse); | ||
}, "getCredentialsFromProfile"); | ||
// Annotate the CommonJS export names for ESM import in node: | ||
0 && (module.exports = { | ||
DEFAULT_MAX_RETRIES, | ||
DEFAULT_TIMEOUT, | ||
ENV_CMDS_AUTH_TOKEN, | ||
ENV_CMDS_FULL_URI, | ||
ENV_CMDS_RELATIVE_URI, | ||
fromContainerMetadata, | ||
fromInstanceMetadata, | ||
getInstanceMetadataEndpoint, | ||
httpRequest, | ||
providerConfigFromInit | ||
}); |
@@ -1,41 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.httpRequest = void 0; | ||
const property_provider_1 = require("@smithy/property-provider"); | ||
const buffer_1 = require("buffer"); | ||
const http_1 = require("http"); | ||
function httpRequest(options) { | ||
return new Promise((resolve, reject) => { | ||
var _a; | ||
const req = (0, http_1.request)({ | ||
method: "GET", | ||
...options, | ||
hostname: (_a = options.hostname) === null || _a === void 0 ? void 0 : _a.replace(/^\[(.+)\]$/, "$1"), | ||
}); | ||
req.on("error", (err) => { | ||
reject(Object.assign(new property_provider_1.ProviderError("Unable to connect to instance metadata service"), err)); | ||
req.destroy(); | ||
}); | ||
req.on("timeout", () => { | ||
reject(new property_provider_1.ProviderError("TimeoutError from instance metadata service")); | ||
req.destroy(); | ||
}); | ||
req.on("response", (res) => { | ||
const { statusCode = 400 } = res; | ||
if (statusCode < 200 || 300 <= statusCode) { | ||
reject(Object.assign(new property_provider_1.ProviderError("Error response received from instance metadata service"), { statusCode })); | ||
req.destroy(); | ||
} | ||
const chunks = []; | ||
res.on("data", (chunk) => { | ||
chunks.push(chunk); | ||
}); | ||
res.on("end", () => { | ||
resolve(buffer_1.Buffer.concat(chunks)); | ||
req.destroy(); | ||
}); | ||
}); | ||
req.end(); | ||
}); | ||
} | ||
exports.httpRequest = httpRequest; | ||
module.exports = require("../index.js"); |
@@ -1,17 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.fromImdsCredentials = exports.isImdsCredentials = void 0; | ||
const isImdsCredentials = (arg) => Boolean(arg) && | ||
typeof arg === "object" && | ||
typeof arg.AccessKeyId === "string" && | ||
typeof arg.SecretAccessKey === "string" && | ||
typeof arg.Token === "string" && | ||
typeof arg.Expiration === "string"; | ||
exports.isImdsCredentials = isImdsCredentials; | ||
const fromImdsCredentials = (creds) => ({ | ||
accessKeyId: creds.AccessKeyId, | ||
secretAccessKey: creds.SecretAccessKey, | ||
sessionToken: creds.Token, | ||
expiration: new Date(creds.Expiration), | ||
}); | ||
exports.fromImdsCredentials = fromImdsCredentials; | ||
module.exports = require("../index.js"); |
@@ -1,5 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const tslib_1 = require("tslib"); | ||
tslib_1.__exportStar(require("./ImdsCredentials"), exports); | ||
tslib_1.__exportStar(require("./RemoteProviderInit"), exports); | ||
module.exports = require("../index.js"); |
@@ -1,7 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.providerConfigFromInit = exports.DEFAULT_MAX_RETRIES = exports.DEFAULT_TIMEOUT = void 0; | ||
exports.DEFAULT_TIMEOUT = 1000; | ||
exports.DEFAULT_MAX_RETRIES = 0; | ||
const providerConfigFromInit = ({ maxRetries = exports.DEFAULT_MAX_RETRIES, timeout = exports.DEFAULT_TIMEOUT, }) => ({ maxRetries, timeout }); | ||
exports.providerConfigFromInit = providerConfigFromInit; | ||
module.exports = require("../index.js"); |
@@ -1,11 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.retry = void 0; | ||
const retry = (toRetry, maxRetries) => { | ||
let promise = toRetry(); | ||
for (let i = 0; i < maxRetries; i++) { | ||
promise = promise.catch(toRetry); | ||
} | ||
return promise; | ||
}; | ||
exports.retry = retry; | ||
module.exports = require("../index.js"); |
@@ -1,2 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
module.exports = require("./index.js"); |
@@ -1,22 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getExtendedInstanceMetadataCredentials = void 0; | ||
const STATIC_STABILITY_REFRESH_INTERVAL_SECONDS = 5 * 60; | ||
const STATIC_STABILITY_REFRESH_INTERVAL_JITTER_WINDOW_SECONDS = 5 * 60; | ||
const STATIC_STABILITY_DOC_URL = "https://docs.aws.amazon.com/sdkref/latest/guide/feature-static-credentials.html"; | ||
const getExtendedInstanceMetadataCredentials = (credentials, logger) => { | ||
var _a; | ||
const refreshInterval = STATIC_STABILITY_REFRESH_INTERVAL_SECONDS + | ||
Math.floor(Math.random() * STATIC_STABILITY_REFRESH_INTERVAL_JITTER_WINDOW_SECONDS); | ||
const newExpiration = new Date(Date.now() + refreshInterval * 1000); | ||
logger.warn("Attempting credential expiration extension due to a credential service availability issue. A refresh of these " + | ||
"credentials will be attempted after ${new Date(newExpiration)}.\nFor more information, please visit: " + | ||
STATIC_STABILITY_DOC_URL); | ||
const originalExpiration = (_a = credentials.originalExpiration) !== null && _a !== void 0 ? _a : credentials.expiration; | ||
return { | ||
...credentials, | ||
...(originalExpiration ? { originalExpiration } : {}), | ||
expiration: newExpiration, | ||
}; | ||
}; | ||
exports.getExtendedInstanceMetadataCredentials = getExtendedInstanceMetadataCredentials; | ||
module.exports = require("../index.js"); |
@@ -1,23 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getInstanceMetadataEndpoint = void 0; | ||
const node_config_provider_1 = require("@smithy/node-config-provider"); | ||
const url_parser_1 = require("@smithy/url-parser"); | ||
const Endpoint_1 = require("../config/Endpoint"); | ||
const EndpointConfigOptions_1 = require("../config/EndpointConfigOptions"); | ||
const EndpointMode_1 = require("../config/EndpointMode"); | ||
const EndpointModeConfigOptions_1 = require("../config/EndpointModeConfigOptions"); | ||
const getInstanceMetadataEndpoint = async () => (0, url_parser_1.parseUrl)((await getFromEndpointConfig()) || (await getFromEndpointModeConfig())); | ||
exports.getInstanceMetadataEndpoint = getInstanceMetadataEndpoint; | ||
const getFromEndpointConfig = async () => (0, node_config_provider_1.loadConfig)(EndpointConfigOptions_1.ENDPOINT_CONFIG_OPTIONS)(); | ||
const getFromEndpointModeConfig = async () => { | ||
const endpointMode = await (0, node_config_provider_1.loadConfig)(EndpointModeConfigOptions_1.ENDPOINT_MODE_CONFIG_OPTIONS)(); | ||
switch (endpointMode) { | ||
case EndpointMode_1.EndpointMode.IPv4: | ||
return Endpoint_1.Endpoint.IPv4; | ||
case EndpointMode_1.EndpointMode.IPv6: | ||
return Endpoint_1.Endpoint.IPv6; | ||
default: | ||
throw new Error(`Unsupported endpoint mode: ${endpointMode}.` + ` Select from ${Object.values(EndpointMode_1.EndpointMode)}`); | ||
} | ||
}; | ||
module.exports = require("../index.js"); |
@@ -1,29 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.staticStabilityProvider = void 0; | ||
const getExtendedInstanceMetadataCredentials_1 = require("./getExtendedInstanceMetadataCredentials"); | ||
const staticStabilityProvider = (provider, options = {}) => { | ||
const logger = (options === null || options === void 0 ? void 0 : options.logger) || console; | ||
let pastCredentials; | ||
return async () => { | ||
let credentials; | ||
try { | ||
credentials = await provider(); | ||
if (credentials.expiration && credentials.expiration.getTime() < Date.now()) { | ||
credentials = (0, getExtendedInstanceMetadataCredentials_1.getExtendedInstanceMetadataCredentials)(credentials, logger); | ||
} | ||
} | ||
catch (e) { | ||
if (pastCredentials) { | ||
logger.warn("Credential renew failed: ", e); | ||
credentials = (0, getExtendedInstanceMetadataCredentials_1.getExtendedInstanceMetadataCredentials)(pastCredentials, logger); | ||
} | ||
else { | ||
throw e; | ||
} | ||
} | ||
pastCredentials = credentials; | ||
return credentials; | ||
}; | ||
}; | ||
exports.staticStabilityProvider = staticStabilityProvider; | ||
module.exports = require("../index.js"); |
{ | ||
"name": "@smithy/credential-provider-imds", | ||
"version": "2.1.5", | ||
"version": "2.2.0", | ||
"description": "AWS credential provider that sources credentials from the EC2 instance metadata service and ECS container metadata service", | ||
@@ -9,3 +9,3 @@ "main": "./dist-cjs/index.js", | ||
"build": "concurrently 'yarn:build:cjs' 'yarn:build:es' 'yarn:build:types && yarn build:types:downlevel'", | ||
"build:cjs": "yarn g:tsc -p tsconfig.cjs.json", | ||
"build:cjs": "node ../../scripts/inline credential-provider-imds", | ||
"build:es": "yarn g:tsc -p tsconfig.es.json", | ||
@@ -30,6 +30,6 @@ "build:types": "yarn g:tsc -p tsconfig.types.json", | ||
"dependencies": { | ||
"@smithy/node-config-provider": "^2.1.9", | ||
"@smithy/property-provider": "^2.0.17", | ||
"@smithy/types": "^2.8.0", | ||
"@smithy/url-parser": "^2.0.16", | ||
"@smithy/node-config-provider": "^2.2.0", | ||
"@smithy/property-provider": "^2.1.0", | ||
"@smithy/types": "^2.9.0", | ||
"@smithy/url-parser": "^2.1.0", | ||
"tslib": "^2.5.0" | ||
@@ -36,0 +36,0 @@ }, |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
61675
1243
Updated@smithy/types@^2.9.0
Updated@smithy/url-parser@^2.1.0