Skip to content

Commit d1105e3

Browse files
authored
chore(credential-provider-node): emit warning when AWS_PROFILE is set alongside ENV credentials (#6277)
1 parent 2687058 commit d1105e3

File tree

3 files changed

+61
-9
lines changed

3 files changed

+61
-9
lines changed

packages/credential-provider-node/src/credential-provider-node.integ.spec.ts

+19
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,25 @@ describe("credential-provider-node integration test", () => {
293293
credentialScope: "us-env-1",
294294
});
295295
});
296+
297+
it("should (for now) resolve AWS_PROFILE instead of static credentials from ENV if both are set. However, this is subject to change.", async () => {
298+
process.env.AWS_ACCESS_KEY_ID = "ENV_ACCESS_KEY";
299+
process.env.AWS_SECRET_ACCESS_KEY = "ENV_SECRET_KEY";
300+
process.env.AWS_PROFILE = "default";
301+
302+
Object.assign(iniProfileData.default, {
303+
aws_access_key_id: "INI_STATIC_ACCESS_KEY",
304+
aws_secret_access_key: "INI_STATIC_SECRET_KEY",
305+
});
306+
307+
await sts.getCallerIdentity({});
308+
const credentials = await sts.config.credentials();
309+
310+
expect(credentials).toEqual({
311+
accessKeyId: "INI_STATIC_ACCESS_KEY",
312+
secretAccessKey: "INI_STATIC_SECRET_KEY",
313+
});
314+
});
296315
});
297316

298317
describe("fromSSO", () => {

packages/credential-provider-node/src/defaultProvider.spec.ts

+6
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ describe(defaultProvider.name, () => {
3434

3535
const mockInit = {
3636
profile: "mockProfile",
37+
logger: {
38+
debug() {},
39+
info() {},
40+
warn() {},
41+
error() {},
42+
},
3743
};
3844

3945
const mockEnvFn = jest.fn().mockImplementation(() => credentials());

packages/credential-provider-node/src/defaultProvider.ts

+36-9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { fromEnv } from "@aws-sdk/credential-provider-env";
1+
import { ENV_KEY, ENV_SECRET, fromEnv } from "@aws-sdk/credential-provider-env";
22
import type { FromHttpOptions } from "@aws-sdk/credential-provider-http";
33
import type { FromIniInit } from "@aws-sdk/credential-provider-ini";
44
import type { FromProcessInit } from "@aws-sdk/credential-provider-process";
@@ -21,6 +21,11 @@ export type DefaultProviderInit = FromIniInit &
2121
(FromSSOInit & Partial<SsoCredentialsParameters>) &
2222
FromTokenFileInit;
2323

24+
/**
25+
* @internal
26+
*/
27+
let multipleCredentialSourceWarningEmitted = false;
28+
2429
/**
2530
* Creates a credential provider that will attempt to find credentials from the
2631
* following sources (listed in order of precedence):
@@ -58,14 +63,36 @@ export type DefaultProviderInit = FromIniInit &
5863
export const defaultProvider = (init: DefaultProviderInit = {}): MemoizedProvider<AwsCredentialIdentity> =>
5964
memoize(
6065
chain(
61-
...(init.profile || process.env[ENV_PROFILE]
62-
? []
63-
: [
64-
async () => {
65-
init.logger?.debug("@aws-sdk/credential-provider-node - defaultProvider::fromEnv");
66-
return fromEnv(init)();
67-
},
68-
]),
66+
async () => {
67+
const profile = init.profile ?? process.env[ENV_PROFILE];
68+
if (profile) {
69+
const envStaticCredentialsAreSet = process.env[ENV_KEY] && process.env[ENV_SECRET];
70+
if (envStaticCredentialsAreSet) {
71+
if (!multipleCredentialSourceWarningEmitted) {
72+
const warnFn =
73+
init.logger?.warn && init.logger?.constructor?.name !== "NoOpLogger" ? init.logger.warn : console.warn;
74+
warnFn(
75+
`@aws-sdk/credential-provider-node - defaultProvider::fromEnv WARNING:
76+
Multiple credential sources detected:
77+
Both AWS_PROFILE and the pair AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY static credentials are set.
78+
This SDK will proceed with the AWS_PROFILE value.
79+
80+
However, a future version may change this behavior to prefer the ENV static credentials.
81+
Please ensure that your environment only sets either the AWS_PROFILE or the
82+
AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY pair.
83+
`
84+
);
85+
multipleCredentialSourceWarningEmitted = true;
86+
}
87+
throw new CredentialsProviderError("AWS_PROFILE is set, skipping fromEnv provider.", {
88+
logger: init.logger,
89+
tryNextLink: true,
90+
});
91+
}
92+
}
93+
init.logger?.debug("@aws-sdk/credential-provider-node - defaultProvider::fromEnv");
94+
return fromEnv(init)();
95+
},
6996
async () => {
7097
init.logger?.debug("@aws-sdk/credential-provider-node - defaultProvider::fromSSO");
7198
const { ssoStartUrl, ssoAccountId, ssoRegion, ssoRoleName, ssoSession } = init;

0 commit comments

Comments
 (0)