Socket
Socket
Sign inDemoInstall

@smithy/credential-provider-imds

Package Overview
Dependencies
Maintainers
2
Versions
48
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@smithy/credential-provider-imds - npm Package Compare versions

Comparing version 2.1.5 to 2.2.0

9

dist-cjs/config/Endpoint.js

@@ -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");

437

dist-cjs/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 @@ },

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc