Skip to content

Commit

Permalink
chore(credential-provider-node): emit warning when AWS_PROFILE is set…
Browse files Browse the repository at this point in the history
… alongside ENV credentials (#6277)
  • Loading branch information
kuhe authored Jul 16, 2024
1 parent 2687058 commit d1105e3
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,25 @@ describe("credential-provider-node integration test", () => {
credentialScope: "us-env-1",
});
});

it("should (for now) resolve AWS_PROFILE instead of static credentials from ENV if both are set. However, this is subject to change.", async () => {
process.env.AWS_ACCESS_KEY_ID = "ENV_ACCESS_KEY";
process.env.AWS_SECRET_ACCESS_KEY = "ENV_SECRET_KEY";
process.env.AWS_PROFILE = "default";

Object.assign(iniProfileData.default, {
aws_access_key_id: "INI_STATIC_ACCESS_KEY",
aws_secret_access_key: "INI_STATIC_SECRET_KEY",
});

await sts.getCallerIdentity({});
const credentials = await sts.config.credentials();

expect(credentials).toEqual({
accessKeyId: "INI_STATIC_ACCESS_KEY",
secretAccessKey: "INI_STATIC_SECRET_KEY",
});
});
});

describe("fromSSO", () => {
Expand Down
6 changes: 6 additions & 0 deletions packages/credential-provider-node/src/defaultProvider.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ describe(defaultProvider.name, () => {

const mockInit = {
profile: "mockProfile",
logger: {
debug() {},
info() {},
warn() {},
error() {},
},
};

const mockEnvFn = jest.fn().mockImplementation(() => credentials());
Expand Down
45 changes: 36 additions & 9 deletions packages/credential-provider-node/src/defaultProvider.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { fromEnv } from "@aws-sdk/credential-provider-env";
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";
Expand All @@ -21,6 +21,11 @@ export type DefaultProviderInit = FromIniInit &
(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):
Expand Down Expand Up @@ -58,14 +63,36 @@ export type DefaultProviderInit = FromIniInit &
export const defaultProvider = (init: DefaultProviderInit = {}): MemoizedProvider<AwsCredentialIdentity> =>
memoize(
chain(
...(init.profile || process.env[ENV_PROFILE]
? []
: [
async () => {
init.logger?.debug("@aws-sdk/credential-provider-node - defaultProvider::fromEnv");
return fromEnv(init)();
},
]),
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;
Expand Down

0 comments on commit d1105e3

Please sign in to comment.