-
Notifications
You must be signed in to change notification settings - Fork 587
/
defaultProvider.ts
151 lines (144 loc) · 6.62 KB
/
defaultProvider.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import { ENV_KEY, ENV_SECRET, fromEnv } from "@aws-sdk/credential-provider-env";
import type { FromHttpOptions } from "@aws-sdk/credential-provider-http";
import type { FromIniInit } from "@aws-sdk/credential-provider-ini";
import type { FromProcessInit } from "@aws-sdk/credential-provider-process";
import type { FromSSOInit, SsoCredentialsParameters } from "@aws-sdk/credential-provider-sso";
import type { FromTokenFileInit } from "@aws-sdk/credential-provider-web-identity";
import type { RemoteProviderInit } from "@smithy/credential-provider-imds";
import { chain, CredentialsProviderError, memoize } from "@smithy/property-provider";
import { ENV_PROFILE } from "@smithy/shared-ini-file-loader";
import { AwsCredentialIdentity, MemoizedProvider } from "@smithy/types";
import { remoteProvider } from "./remoteProvider";
/**
* @public
*/
export type DefaultProviderInit = FromIniInit &
FromHttpOptions &
RemoteProviderInit &
FromProcessInit &
(FromSSOInit & Partial<SsoCredentialsParameters>) &
FromTokenFileInit;
/**
* @internal
*/
let multipleCredentialSourceWarningEmitted = false;
/**
* Creates a credential provider that will attempt to find credentials from the
* following sources (listed in order of precedence):
* * Environment variables exposed via `process.env`
* * SSO credentials from token cache
* * Web identity token credentials
* * Shared credentials and config ini files
* * The EC2/ECS Instance Metadata Service
*
* The default credential provider will invoke one provider at a time and only
* continue to the next if no credentials have been located. For example, if
* the process finds values defined via the `AWS_ACCESS_KEY_ID` and
* `AWS_SECRET_ACCESS_KEY` environment variables, the files at
* `~/.aws/credentials` and `~/.aws/config` will not be read, nor will any
* messages be sent to the Instance Metadata Service.
*
* @param init Configuration that is passed to each individual
* provider
*
* @see {@link fromEnv} The function used to source credentials from
* environment variables.
* @see {@link fromSSO} The function used to source credentials from
* resolved SSO token cache.
* @see {@link fromTokenFile} The function used to source credentials from
* token file.
* @see {@link fromIni} The function used to source credentials from INI
* files.
* @see {@link fromProcess} The function used to sources credentials from
* credential_process in INI files.
* @see {@link fromInstanceMetadata} The function used to source credentials from the
* EC2 Instance Metadata Service.
* @see {@link fromContainerMetadata} The function used to source credentials from the
* ECS Container Metadata Service.
*/
export const defaultProvider = (init: DefaultProviderInit = {}): MemoizedProvider<AwsCredentialIdentity> =>
memoize(
chain(
async () => {
const profile = init.profile ?? process.env[ENV_PROFILE];
if (profile) {
const envStaticCredentialsAreSet = process.env[ENV_KEY] && process.env[ENV_SECRET];
if (envStaticCredentialsAreSet) {
if (!multipleCredentialSourceWarningEmitted) {
const warnFn =
init.logger?.warn && init.logger?.constructor?.name !== "NoOpLogger" ? init.logger.warn : console.warn;
warnFn(
`@aws-sdk/credential-provider-node - defaultProvider::fromEnv WARNING:
Multiple credential sources detected:
Both AWS_PROFILE and the pair AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY static credentials are set.
This SDK will proceed with the AWS_PROFILE value.
However, a future version may change this behavior to prefer the ENV static credentials.
Please ensure that your environment only sets either the AWS_PROFILE or the
AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY pair.
`
);
multipleCredentialSourceWarningEmitted = true;
}
}
throw new CredentialsProviderError("AWS_PROFILE is set, skipping fromEnv provider.", {
logger: init.logger,
tryNextLink: true,
});
}
init.logger?.debug("@aws-sdk/credential-provider-node - defaultProvider::fromEnv");
return fromEnv(init)();
},
async () => {
init.logger?.debug("@aws-sdk/credential-provider-node - defaultProvider::fromSSO");
const { ssoStartUrl, ssoAccountId, ssoRegion, ssoRoleName, ssoSession } = init;
if (!ssoStartUrl && !ssoAccountId && !ssoRegion && !ssoRoleName && !ssoSession) {
throw new CredentialsProviderError(
"Skipping SSO provider in default chain (inputs do not include SSO fields).",
{ logger: init.logger }
);
}
const { fromSSO } = await import("@aws-sdk/credential-provider-sso");
return fromSSO(init)();
},
async () => {
init.logger?.debug("@aws-sdk/credential-provider-node - defaultProvider::fromIni");
const { fromIni } = await import("@aws-sdk/credential-provider-ini");
return fromIni(init)();
},
async () => {
init.logger?.debug("@aws-sdk/credential-provider-node - defaultProvider::fromProcess");
const { fromProcess } = await import("@aws-sdk/credential-provider-process");
return fromProcess(init)();
},
async () => {
init.logger?.debug("@aws-sdk/credential-provider-node - defaultProvider::fromTokenFile");
const { fromTokenFile } = await import("@aws-sdk/credential-provider-web-identity");
return fromTokenFile(init)();
},
async () => {
init.logger?.debug("@aws-sdk/credential-provider-node - defaultProvider::remoteProvider");
return (await remoteProvider(init))();
},
async () => {
throw new CredentialsProviderError("Could not load credentials from any providers", {
tryNextLink: false,
logger: init.logger,
});
}
),
credentialsTreatedAsExpired,
credentialsWillNeedRefresh
);
/**
* @internal
*
* @returns credentials have expiration.
*/
export const credentialsWillNeedRefresh = (credentials: AwsCredentialIdentity) => credentials?.expiration !== undefined;
/**
* @internal
*
* @returns credentials with less than 5 minutes left.
*/
export const credentialsTreatedAsExpired = (credentials: AwsCredentialIdentity) =>
credentials?.expiration !== undefined && credentials.expiration.getTime() - Date.now() < 300000;