@smithy/credential-provider-imds 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +11 -0
- package/dist-cjs/config/Endpoint.js +8 -0
- package/dist-cjs/config/EndpointConfigOptions.js +10 -0
- package/dist-cjs/config/EndpointMode.js +8 -0
- package/dist-cjs/config/EndpointModeConfigOptions.js +11 -0
- package/dist-cjs/fromContainerMetadata.js +70 -0
- package/dist-cjs/fromInstanceMetadata.js +95 -0
- package/dist-cjs/index.js +12 -0
- package/dist-cjs/remoteProvider/ImdsCredentials.js +17 -0
- package/dist-cjs/remoteProvider/RemoteProviderInit.js +7 -0
- package/dist-cjs/remoteProvider/httpRequest.js +41 -0
- package/dist-cjs/remoteProvider/index.js +5 -0
- package/dist-cjs/remoteProvider/retry.js +11 -0
- package/dist-cjs/types.js +2 -0
- package/dist-cjs/utils/getExtendedInstanceMetadataCredentials.js +22 -0
- package/dist-cjs/utils/getInstanceMetadataEndpoint.js +23 -0
- package/dist-cjs/utils/staticStabilityProvider.js +29 -0
- package/dist-es/config/Endpoint.js +5 -0
- package/dist-es/config/EndpointConfigOptions.js +7 -0
- package/dist-es/config/EndpointMode.js +5 -0
- package/dist-es/config/EndpointModeConfigOptions.js +8 -0
- package/dist-es/fromContainerMetadata.js +66 -0
- package/dist-es/fromInstanceMetadata.js +91 -0
- package/dist-es/index.js +6 -0
- package/dist-es/remoteProvider/ImdsCredentials.js +12 -0
- package/dist-es/remoteProvider/RemoteProviderInit.js +3 -0
- package/dist-es/remoteProvider/httpRequest.js +36 -0
- package/dist-es/remoteProvider/index.js +2 -0
- package/dist-es/remoteProvider/retry.js +7 -0
- package/dist-es/types.js +1 -0
- package/dist-es/utils/getExtendedInstanceMetadataCredentials.js +17 -0
- package/dist-es/utils/getInstanceMetadataEndpoint.js +19 -0
- package/dist-es/utils/staticStabilityProvider.js +25 -0
- package/dist-types/config/Endpoint.d.ts +7 -0
- package/dist-types/config/EndpointConfigOptions.d.ts +13 -0
- package/dist-types/config/EndpointMode.d.ts +7 -0
- package/dist-types/config/EndpointModeConfigOptions.d.ts +13 -0
- package/dist-types/fromContainerMetadata.d.ts +21 -0
- package/dist-types/fromInstanceMetadata.d.ts +10 -0
- package/dist-types/index.d.ts +24 -0
- package/dist-types/remoteProvider/ImdsCredentials.d.ts +18 -0
- package/dist-types/remoteProvider/RemoteProviderInit.d.ts +32 -0
- package/dist-types/remoteProvider/httpRequest.d.ts +7 -0
- package/dist-types/remoteProvider/index.d.ts +8 -0
- package/dist-types/remoteProvider/retry.d.ts +10 -0
- package/dist-types/types.d.ts +7 -0
- package/dist-types/utils/getExtendedInstanceMetadataCredentials.d.ts +6 -0
- package/dist-types/utils/getInstanceMetadataEndpoint.d.ts +21 -0
- package/dist-types/utils/staticStabilityProvider.d.ts +16 -0
- package/package.json +69 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { CredentialsProviderError } from "@smithy/property-provider";
|
|
2
|
+
import { parse } from "url";
|
|
3
|
+
import { httpRequest } from "./remoteProvider/httpRequest";
|
|
4
|
+
import { fromImdsCredentials, isImdsCredentials } from "./remoteProvider/ImdsCredentials";
|
|
5
|
+
import { providerConfigFromInit } from "./remoteProvider/RemoteProviderInit";
|
|
6
|
+
import { retry } from "./remoteProvider/retry";
|
|
7
|
+
export const ENV_CMDS_FULL_URI = "AWS_CONTAINER_CREDENTIALS_FULL_URI";
|
|
8
|
+
export const ENV_CMDS_RELATIVE_URI = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI";
|
|
9
|
+
export const ENV_CMDS_AUTH_TOKEN = "AWS_CONTAINER_AUTHORIZATION_TOKEN";
|
|
10
|
+
export const fromContainerMetadata = (init = {}) => {
|
|
11
|
+
const { timeout, maxRetries } = providerConfigFromInit(init);
|
|
12
|
+
return () => retry(async () => {
|
|
13
|
+
const requestOptions = await getCmdsUri();
|
|
14
|
+
const credsResponse = JSON.parse(await requestFromEcsImds(timeout, requestOptions));
|
|
15
|
+
if (!isImdsCredentials(credsResponse)) {
|
|
16
|
+
throw new CredentialsProviderError("Invalid response received from instance metadata service.");
|
|
17
|
+
}
|
|
18
|
+
return fromImdsCredentials(credsResponse);
|
|
19
|
+
}, maxRetries);
|
|
20
|
+
};
|
|
21
|
+
const requestFromEcsImds = async (timeout, options) => {
|
|
22
|
+
if (process.env[ENV_CMDS_AUTH_TOKEN]) {
|
|
23
|
+
options.headers = {
|
|
24
|
+
...options.headers,
|
|
25
|
+
Authorization: process.env[ENV_CMDS_AUTH_TOKEN],
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const buffer = await httpRequest({
|
|
29
|
+
...options,
|
|
30
|
+
timeout,
|
|
31
|
+
});
|
|
32
|
+
return buffer.toString();
|
|
33
|
+
};
|
|
34
|
+
const CMDS_IP = "169.254.170.2";
|
|
35
|
+
const GREENGRASS_HOSTS = {
|
|
36
|
+
localhost: true,
|
|
37
|
+
"127.0.0.1": true,
|
|
38
|
+
};
|
|
39
|
+
const GREENGRASS_PROTOCOLS = {
|
|
40
|
+
"http:": true,
|
|
41
|
+
"https:": true,
|
|
42
|
+
};
|
|
43
|
+
const getCmdsUri = async () => {
|
|
44
|
+
if (process.env[ENV_CMDS_RELATIVE_URI]) {
|
|
45
|
+
return {
|
|
46
|
+
hostname: CMDS_IP,
|
|
47
|
+
path: process.env[ENV_CMDS_RELATIVE_URI],
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
if (process.env[ENV_CMDS_FULL_URI]) {
|
|
51
|
+
const parsed = parse(process.env[ENV_CMDS_FULL_URI]);
|
|
52
|
+
if (!parsed.hostname || !(parsed.hostname in GREENGRASS_HOSTS)) {
|
|
53
|
+
throw new CredentialsProviderError(`${parsed.hostname} is not a valid container metadata service hostname`, false);
|
|
54
|
+
}
|
|
55
|
+
if (!parsed.protocol || !(parsed.protocol in GREENGRASS_PROTOCOLS)) {
|
|
56
|
+
throw new CredentialsProviderError(`${parsed.protocol} is not a valid container metadata service protocol`, false);
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
...parsed,
|
|
60
|
+
port: parsed.port ? parseInt(parsed.port, 10) : undefined,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
throw new CredentialsProviderError("The container metadata credential provider cannot be used unless" +
|
|
64
|
+
` the ${ENV_CMDS_RELATIVE_URI} or ${ENV_CMDS_FULL_URI} environment` +
|
|
65
|
+
" variable is set", false);
|
|
66
|
+
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { CredentialsProviderError } from "@smithy/property-provider";
|
|
2
|
+
import { httpRequest } from "./remoteProvider/httpRequest";
|
|
3
|
+
import { fromImdsCredentials, isImdsCredentials } from "./remoteProvider/ImdsCredentials";
|
|
4
|
+
import { providerConfigFromInit } from "./remoteProvider/RemoteProviderInit";
|
|
5
|
+
import { retry } from "./remoteProvider/retry";
|
|
6
|
+
import { getInstanceMetadataEndpoint } from "./utils/getInstanceMetadataEndpoint";
|
|
7
|
+
import { staticStabilityProvider } from "./utils/staticStabilityProvider";
|
|
8
|
+
const IMDS_PATH = "/latest/meta-data/iam/security-credentials/";
|
|
9
|
+
const IMDS_TOKEN_PATH = "/latest/api/token";
|
|
10
|
+
export const fromInstanceMetadata = (init = {}) => staticStabilityProvider(getInstanceImdsProvider(init), { logger: init.logger });
|
|
11
|
+
const getInstanceImdsProvider = (init) => {
|
|
12
|
+
let disableFetchToken = false;
|
|
13
|
+
const { timeout, maxRetries } = providerConfigFromInit(init);
|
|
14
|
+
const getCredentials = async (maxRetries, options) => {
|
|
15
|
+
const profile = (await retry(async () => {
|
|
16
|
+
let profile;
|
|
17
|
+
try {
|
|
18
|
+
profile = await getProfile(options);
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
if (err.statusCode === 401) {
|
|
22
|
+
disableFetchToken = false;
|
|
23
|
+
}
|
|
24
|
+
throw err;
|
|
25
|
+
}
|
|
26
|
+
return profile;
|
|
27
|
+
}, maxRetries)).trim();
|
|
28
|
+
return retry(async () => {
|
|
29
|
+
let creds;
|
|
30
|
+
try {
|
|
31
|
+
creds = await getCredentialsFromProfile(profile, options);
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
if (err.statusCode === 401) {
|
|
35
|
+
disableFetchToken = false;
|
|
36
|
+
}
|
|
37
|
+
throw err;
|
|
38
|
+
}
|
|
39
|
+
return creds;
|
|
40
|
+
}, maxRetries);
|
|
41
|
+
};
|
|
42
|
+
return async () => {
|
|
43
|
+
const endpoint = await getInstanceMetadataEndpoint();
|
|
44
|
+
if (disableFetchToken) {
|
|
45
|
+
return getCredentials(maxRetries, { ...endpoint, timeout });
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
let token;
|
|
49
|
+
try {
|
|
50
|
+
token = (await getMetadataToken({ ...endpoint, timeout })).toString();
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
if (error?.statusCode === 400) {
|
|
54
|
+
throw Object.assign(error, {
|
|
55
|
+
message: "EC2 Metadata token request returned error",
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
else if (error.message === "TimeoutError" || [403, 404, 405].includes(error.statusCode)) {
|
|
59
|
+
disableFetchToken = true;
|
|
60
|
+
}
|
|
61
|
+
return getCredentials(maxRetries, { ...endpoint, timeout });
|
|
62
|
+
}
|
|
63
|
+
return getCredentials(maxRetries, {
|
|
64
|
+
...endpoint,
|
|
65
|
+
headers: {
|
|
66
|
+
"x-aws-ec2-metadata-token": token,
|
|
67
|
+
},
|
|
68
|
+
timeout,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
const getMetadataToken = async (options) => httpRequest({
|
|
74
|
+
...options,
|
|
75
|
+
path: IMDS_TOKEN_PATH,
|
|
76
|
+
method: "PUT",
|
|
77
|
+
headers: {
|
|
78
|
+
"x-aws-ec2-metadata-token-ttl-seconds": "21600",
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
const getProfile = async (options) => (await httpRequest({ ...options, path: IMDS_PATH })).toString();
|
|
82
|
+
const getCredentialsFromProfile = async (profile, options) => {
|
|
83
|
+
const credsResponse = JSON.parse((await httpRequest({
|
|
84
|
+
...options,
|
|
85
|
+
path: IMDS_PATH + profile,
|
|
86
|
+
})).toString());
|
|
87
|
+
if (!isImdsCredentials(credsResponse)) {
|
|
88
|
+
throw new CredentialsProviderError("Invalid response received from instance metadata service.");
|
|
89
|
+
}
|
|
90
|
+
return fromImdsCredentials(credsResponse);
|
|
91
|
+
};
|
package/dist-es/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export * from "./fromContainerMetadata";
|
|
2
|
+
export * from "./fromInstanceMetadata";
|
|
3
|
+
export * from "./remoteProvider/RemoteProviderInit";
|
|
4
|
+
export * from "./types";
|
|
5
|
+
export { httpRequest } from "./remoteProvider/httpRequest";
|
|
6
|
+
export { getInstanceMetadataEndpoint } from "./utils/getInstanceMetadataEndpoint";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export const isImdsCredentials = (arg) => Boolean(arg) &&
|
|
2
|
+
typeof arg === "object" &&
|
|
3
|
+
typeof arg.AccessKeyId === "string" &&
|
|
4
|
+
typeof arg.SecretAccessKey === "string" &&
|
|
5
|
+
typeof arg.Token === "string" &&
|
|
6
|
+
typeof arg.Expiration === "string";
|
|
7
|
+
export const fromImdsCredentials = (creds) => ({
|
|
8
|
+
accessKeyId: creds.AccessKeyId,
|
|
9
|
+
secretAccessKey: creds.SecretAccessKey,
|
|
10
|
+
sessionToken: creds.Token,
|
|
11
|
+
expiration: new Date(creds.Expiration),
|
|
12
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { ProviderError } from "@smithy/property-provider";
|
|
2
|
+
import { Buffer } from "buffer";
|
|
3
|
+
import { request } from "http";
|
|
4
|
+
export function httpRequest(options) {
|
|
5
|
+
return new Promise((resolve, reject) => {
|
|
6
|
+
const req = request({
|
|
7
|
+
method: "GET",
|
|
8
|
+
...options,
|
|
9
|
+
hostname: options.hostname?.replace(/^\[(.+)\]$/, "$1"),
|
|
10
|
+
});
|
|
11
|
+
req.on("error", (err) => {
|
|
12
|
+
reject(Object.assign(new ProviderError("Unable to connect to instance metadata service"), err));
|
|
13
|
+
req.destroy();
|
|
14
|
+
});
|
|
15
|
+
req.on("timeout", () => {
|
|
16
|
+
reject(new ProviderError("TimeoutError from instance metadata service"));
|
|
17
|
+
req.destroy();
|
|
18
|
+
});
|
|
19
|
+
req.on("response", (res) => {
|
|
20
|
+
const { statusCode = 400 } = res;
|
|
21
|
+
if (statusCode < 200 || 300 <= statusCode) {
|
|
22
|
+
reject(Object.assign(new ProviderError("Error response received from instance metadata service"), { statusCode }));
|
|
23
|
+
req.destroy();
|
|
24
|
+
}
|
|
25
|
+
const chunks = [];
|
|
26
|
+
res.on("data", (chunk) => {
|
|
27
|
+
chunks.push(chunk);
|
|
28
|
+
});
|
|
29
|
+
res.on("end", () => {
|
|
30
|
+
resolve(Buffer.concat(chunks));
|
|
31
|
+
req.destroy();
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
req.end();
|
|
35
|
+
});
|
|
36
|
+
}
|
package/dist-es/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const STATIC_STABILITY_REFRESH_INTERVAL_SECONDS = 5 * 60;
|
|
2
|
+
const STATIC_STABILITY_REFRESH_INTERVAL_JITTER_WINDOW_SECONDS = 5 * 60;
|
|
3
|
+
const STATIC_STABILITY_DOC_URL = "https://docs.aws.amazon.com/sdkref/latest/guide/feature-static-credentials.html";
|
|
4
|
+
export const getExtendedInstanceMetadataCredentials = (credentials, logger) => {
|
|
5
|
+
const refreshInterval = STATIC_STABILITY_REFRESH_INTERVAL_SECONDS +
|
|
6
|
+
Math.floor(Math.random() * STATIC_STABILITY_REFRESH_INTERVAL_JITTER_WINDOW_SECONDS);
|
|
7
|
+
const newExpiration = new Date(Date.now() + refreshInterval * 1000);
|
|
8
|
+
logger.warn("Attempting credential expiration extension due to a credential service availability issue. A refresh of these " +
|
|
9
|
+
"credentials will be attempted after ${new Date(newExpiration)}.\nFor more information, please visit: " +
|
|
10
|
+
STATIC_STABILITY_DOC_URL);
|
|
11
|
+
const originalExpiration = credentials.originalExpiration ?? credentials.expiration;
|
|
12
|
+
return {
|
|
13
|
+
...credentials,
|
|
14
|
+
...(originalExpiration ? { originalExpiration } : {}),
|
|
15
|
+
expiration: newExpiration,
|
|
16
|
+
};
|
|
17
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { loadConfig } from "@smithy/node-config-provider";
|
|
2
|
+
import { parseUrl } from "@smithy/url-parser";
|
|
3
|
+
import { Endpoint as InstanceMetadataEndpoint } from "../config/Endpoint";
|
|
4
|
+
import { ENDPOINT_CONFIG_OPTIONS } from "../config/EndpointConfigOptions";
|
|
5
|
+
import { EndpointMode } from "../config/EndpointMode";
|
|
6
|
+
import { ENDPOINT_MODE_CONFIG_OPTIONS, } from "../config/EndpointModeConfigOptions";
|
|
7
|
+
export const getInstanceMetadataEndpoint = async () => parseUrl((await getFromEndpointConfig()) || (await getFromEndpointModeConfig()));
|
|
8
|
+
const getFromEndpointConfig = async () => loadConfig(ENDPOINT_CONFIG_OPTIONS)();
|
|
9
|
+
const getFromEndpointModeConfig = async () => {
|
|
10
|
+
const endpointMode = await loadConfig(ENDPOINT_MODE_CONFIG_OPTIONS)();
|
|
11
|
+
switch (endpointMode) {
|
|
12
|
+
case EndpointMode.IPv4:
|
|
13
|
+
return InstanceMetadataEndpoint.IPv4;
|
|
14
|
+
case EndpointMode.IPv6:
|
|
15
|
+
return InstanceMetadataEndpoint.IPv6;
|
|
16
|
+
default:
|
|
17
|
+
throw new Error(`Unsupported endpoint mode: ${endpointMode}.` + ` Select from ${Object.values(EndpointMode)}`);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { getExtendedInstanceMetadataCredentials } from "./getExtendedInstanceMetadataCredentials";
|
|
2
|
+
export const staticStabilityProvider = (provider, options = {}) => {
|
|
3
|
+
const logger = options?.logger || console;
|
|
4
|
+
let pastCredentials;
|
|
5
|
+
return async () => {
|
|
6
|
+
let credentials;
|
|
7
|
+
try {
|
|
8
|
+
credentials = await provider();
|
|
9
|
+
if (credentials.expiration && credentials.expiration.getTime() < Date.now()) {
|
|
10
|
+
credentials = getExtendedInstanceMetadataCredentials(credentials, logger);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
catch (e) {
|
|
14
|
+
if (pastCredentials) {
|
|
15
|
+
logger.warn("Credential renew failed: ", e);
|
|
16
|
+
credentials = getExtendedInstanceMetadataCredentials(pastCredentials, logger);
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
throw e;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
pastCredentials = credentials;
|
|
23
|
+
return credentials;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { LoadedConfigSelectors } from "@smithy/node-config-provider";
|
|
2
|
+
/**
|
|
3
|
+
* @internal
|
|
4
|
+
*/
|
|
5
|
+
export declare const ENV_ENDPOINT_NAME = "AWS_EC2_METADATA_SERVICE_ENDPOINT";
|
|
6
|
+
/**
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
export declare const CONFIG_ENDPOINT_NAME = "ec2_metadata_service_endpoint";
|
|
10
|
+
/**
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
export declare const ENDPOINT_CONFIG_OPTIONS: LoadedConfigSelectors<string | undefined>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { LoadedConfigSelectors } from "@smithy/node-config-provider";
|
|
2
|
+
/**
|
|
3
|
+
* @internal
|
|
4
|
+
*/
|
|
5
|
+
export declare const ENV_ENDPOINT_MODE_NAME = "AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE";
|
|
6
|
+
/**
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
export declare const CONFIG_ENDPOINT_MODE_NAME = "ec2_metadata_service_endpoint_mode";
|
|
10
|
+
/**
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
export declare const ENDPOINT_MODE_CONFIG_OPTIONS: LoadedConfigSelectors<string | undefined>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { AwsCredentialIdentityProvider } from "@smithy/types";
|
|
2
|
+
import { RemoteProviderInit } from "./remoteProvider/RemoteProviderInit";
|
|
3
|
+
/**
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
6
|
+
export declare const ENV_CMDS_FULL_URI = "AWS_CONTAINER_CREDENTIALS_FULL_URI";
|
|
7
|
+
/**
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
export declare const ENV_CMDS_RELATIVE_URI = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI";
|
|
11
|
+
/**
|
|
12
|
+
* @internal
|
|
13
|
+
*/
|
|
14
|
+
export declare const ENV_CMDS_AUTH_TOKEN = "AWS_CONTAINER_AUTHORIZATION_TOKEN";
|
|
15
|
+
/**
|
|
16
|
+
* @internal
|
|
17
|
+
*
|
|
18
|
+
* Creates a credential provider that will source credentials from the ECS
|
|
19
|
+
* Container Metadata Service
|
|
20
|
+
*/
|
|
21
|
+
export declare const fromContainerMetadata: (init?: RemoteProviderInit) => AwsCredentialIdentityProvider;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Provider } from "@smithy/types";
|
|
2
|
+
import { RemoteProviderInit } from "./remoteProvider/RemoteProviderInit";
|
|
3
|
+
import { InstanceMetadataCredentials } from "./types";
|
|
4
|
+
/**
|
|
5
|
+
* @internal
|
|
6
|
+
*
|
|
7
|
+
* Creates a credential provider that will source credentials from the EC2
|
|
8
|
+
* Instance Metadata Service
|
|
9
|
+
*/
|
|
10
|
+
export declare const fromInstanceMetadata: (init?: RemoteProviderInit) => Provider<InstanceMetadataCredentials>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @internal
|
|
3
|
+
*/
|
|
4
|
+
export * from "./fromContainerMetadata";
|
|
5
|
+
/**
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
export * from "./fromInstanceMetadata";
|
|
9
|
+
/**
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
export * from "./remoteProvider/RemoteProviderInit";
|
|
13
|
+
/**
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
export * from "./types";
|
|
17
|
+
/**
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
20
|
+
export { httpRequest } from "./remoteProvider/httpRequest";
|
|
21
|
+
/**
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
24
|
+
export { getInstanceMetadataEndpoint } from "./utils/getInstanceMetadataEndpoint";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { AwsCredentialIdentity } from "@smithy/types";
|
|
2
|
+
/**
|
|
3
|
+
* @internal
|
|
4
|
+
*/
|
|
5
|
+
export interface ImdsCredentials {
|
|
6
|
+
AccessKeyId: string;
|
|
7
|
+
SecretAccessKey: string;
|
|
8
|
+
Token: string;
|
|
9
|
+
Expiration: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* @internal
|
|
13
|
+
*/
|
|
14
|
+
export declare const isImdsCredentials: (arg: any) => arg is ImdsCredentials;
|
|
15
|
+
/**
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
export declare const fromImdsCredentials: (creds: ImdsCredentials) => AwsCredentialIdentity;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Logger } from "@smithy/types";
|
|
2
|
+
/**
|
|
3
|
+
* @internal
|
|
4
|
+
*/
|
|
5
|
+
export declare const DEFAULT_TIMEOUT = 1000;
|
|
6
|
+
/**
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
export declare const DEFAULT_MAX_RETRIES = 0;
|
|
10
|
+
/**
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
export interface RemoteProviderConfig {
|
|
14
|
+
/**
|
|
15
|
+
* The connection timeout (in milliseconds)
|
|
16
|
+
*/
|
|
17
|
+
timeout: number;
|
|
18
|
+
/**
|
|
19
|
+
* The maximum number of times the HTTP connection should be retried
|
|
20
|
+
*/
|
|
21
|
+
maxRetries: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* @internal
|
|
25
|
+
*/
|
|
26
|
+
export interface RemoteProviderInit extends Partial<RemoteProviderConfig> {
|
|
27
|
+
logger?: Logger;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* @internal
|
|
31
|
+
*/
|
|
32
|
+
export declare const providerConfigFromInit: ({ maxRetries, timeout, }: RemoteProviderInit) => RemoteProviderConfig;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Logger } from "@smithy/types";
|
|
2
|
+
import { InstanceMetadataCredentials } from "../types";
|
|
3
|
+
/**
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
6
|
+
export declare const getExtendedInstanceMetadataCredentials: (credentials: InstanceMetadataCredentials, logger: Logger) => InstanceMetadataCredentials;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Endpoint } from "@smithy/types";
|
|
2
|
+
/**
|
|
3
|
+
* Returns the host to use for instance metadata service call.
|
|
4
|
+
*
|
|
5
|
+
* The host is read from endpoint which can be set either in
|
|
6
|
+
* {@link ENV_ENDPOINT_NAME} environment variable or {@link CONFIG_ENDPOINT_NAME}
|
|
7
|
+
* configuration property.
|
|
8
|
+
*
|
|
9
|
+
* If endpoint is not set, then endpoint mode is read either from
|
|
10
|
+
* {@link ENV_ENDPOINT_MODE_NAME} environment variable or {@link CONFIG_ENDPOINT_MODE_NAME}
|
|
11
|
+
* configuration property. If endpoint mode is not set, then default endpoint mode
|
|
12
|
+
* {@link EndpointMode.IPv4} is used.
|
|
13
|
+
*
|
|
14
|
+
* If endpoint mode is set to {@link EndpointMode.IPv4}, then the host is {@link Endpoint.IPv4}.
|
|
15
|
+
* If endpoint mode is set to {@link EndpointMode.IPv6}, then the host is {@link Endpoint.IPv6}.
|
|
16
|
+
*
|
|
17
|
+
* @returns Host to use for instance metadata service call.
|
|
18
|
+
*
|
|
19
|
+
* @internal
|
|
20
|
+
*/
|
|
21
|
+
export declare const getInstanceMetadataEndpoint: () => Promise<Endpoint>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Logger, Provider } from "@smithy/types";
|
|
2
|
+
import { InstanceMetadataCredentials } from "../types";
|
|
3
|
+
/**
|
|
4
|
+
* @internal
|
|
5
|
+
*
|
|
6
|
+
* IMDS credential supports static stability feature. When used, the expiration
|
|
7
|
+
* of recently issued credentials is extended. The server side allows using
|
|
8
|
+
* the recently expired credentials. This mitigates impact when clients using
|
|
9
|
+
* refreshable credentials are unable to retrieve updates.
|
|
10
|
+
*
|
|
11
|
+
* @param provider Credential provider
|
|
12
|
+
* @returns A credential provider that supports static stability
|
|
13
|
+
*/
|
|
14
|
+
export declare const staticStabilityProvider: (provider: Provider<InstanceMetadataCredentials>, options?: {
|
|
15
|
+
logger?: Logger | undefined;
|
|
16
|
+
}) => Provider<InstanceMetadataCredentials>;
|
package/package.json
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@smithy/credential-provider-imds",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "AWS credential provider that sources credentials from the EC2 instance metadata service and ECS container metadata service",
|
|
5
|
+
"main": "./dist-cjs/index.js",
|
|
6
|
+
"module": "./dist-es/index.js",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "concurrently 'yarn:build:cjs' 'yarn:build:es' 'yarn:build:types'",
|
|
9
|
+
"build:cjs": "tsc -p tsconfig.cjs.json",
|
|
10
|
+
"build:es": "tsc -p tsconfig.es.json",
|
|
11
|
+
"build:types": "tsc -p tsconfig.types.json",
|
|
12
|
+
"build:types:downlevel": "downlevel-dts dist-types dist-types/ts3.4",
|
|
13
|
+
"stage-release": "rimraf ./.release && yarn pack && mkdir ./.release && tar zxvf ./package.tgz --directory ./.release && rm ./package.tgz",
|
|
14
|
+
"clean": "rimraf ./dist-* && rimraf *.tsbuildinfo",
|
|
15
|
+
"lint": "eslint -c ../../.eslintrc.js \"src/**/*.ts\"",
|
|
16
|
+
"format": "prettier --config ../../prettier.config.js --ignore-path ../.prettierignore --write \"**/*.{ts,md,json}\"",
|
|
17
|
+
"test": "jest"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"aws",
|
|
21
|
+
"credentials"
|
|
22
|
+
],
|
|
23
|
+
"author": {
|
|
24
|
+
"name": "AWS SDK for JavaScript Team",
|
|
25
|
+
"url": "https://aws.amazon.com/javascript/"
|
|
26
|
+
},
|
|
27
|
+
"license": "Apache-2.0",
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@smithy/node-config-provider": "workspace:^",
|
|
30
|
+
"@smithy/property-provider": "workspace:^",
|
|
31
|
+
"@smithy/types": "workspace:^",
|
|
32
|
+
"@smithy/url-parser": "workspace:^",
|
|
33
|
+
"tslib": "^2.5.0"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@tsconfig/recommended": "1.0.1",
|
|
37
|
+
"@types/node": "^14.14.31",
|
|
38
|
+
"concurrently": "7.0.0",
|
|
39
|
+
"downlevel-dts": "0.10.1",
|
|
40
|
+
"jest": "28.1.1",
|
|
41
|
+
"nock": "^13.0.2",
|
|
42
|
+
"rimraf": "3.0.2",
|
|
43
|
+
"typedoc": "0.23.23",
|
|
44
|
+
"typescript": "~4.9.5"
|
|
45
|
+
},
|
|
46
|
+
"types": "./dist-types/index.d.ts",
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=14.0.0"
|
|
49
|
+
},
|
|
50
|
+
"typesVersions": {
|
|
51
|
+
"<4.0": {
|
|
52
|
+
"dist-types/*": [
|
|
53
|
+
"dist-types/ts3.4/*"
|
|
54
|
+
]
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"files": [
|
|
58
|
+
"dist-*/**"
|
|
59
|
+
],
|
|
60
|
+
"homepage": "https://github.com/awslabs/smithy-typescript/tree/main/packages/credential-provider-imds",
|
|
61
|
+
"repository": {
|
|
62
|
+
"type": "git",
|
|
63
|
+
"url": "https://github.com/awslabs/smithy-typescript.git",
|
|
64
|
+
"directory": "packages/credential-provider-imds"
|
|
65
|
+
},
|
|
66
|
+
"typedoc": {
|
|
67
|
+
"entryPoint": "src/index.ts"
|
|
68
|
+
}
|
|
69
|
+
}
|