Skip to content

fix: role assumption through profiles not working properly in certain situations#14315

Merged
ShadowCat567 merged 3 commits intodevfrom
downgrade-cred-providers
Oct 31, 2025
Merged

fix: role assumption through profiles not working properly in certain situations#14315
ShadowCat567 merged 3 commits intodevfrom
downgrade-cred-providers

Conversation

@ShadowCat567
Copy link
Copy Markdown
Contributor

@ShadowCat567 ShadowCat567 commented Oct 31, 2025

Description of changes

This PR fixes 2 bugs that affect people who get their credentials from profiles that look like this:

[profile test-profile]
role_arn=arn:aws:iam::<account number>:role/test-role
source_profile=other-profile
  1. @aws-sdk/credential-providers
    @aws-sdk/credential-providers uses v4 of @smithy/property-providers. This is a problem because our bundling solution (pkg) does not support dynamic imports, which were introduced in v4 of @smithy/property-providers. So I downgraded us to the newest version that still uses v3 of @smithy/property-providers until we come up with a more permanent solution.
    Not sure why this change specifically broke profiles that use a role and another profile to get credentials since profiles that got credentials through other methods worked fine for me.

  2. identity.expiration.getTime is not a function
    The expiration field within credentials of profiles that get credentials through a role and another profile is a string instead of a Date. This was fine in AWS SDK V2, since it was more flexible with types, however AWS SDK V3 is much stricter with typing so the expiration field needs to get converted to a Date before it gets used in any clients.

Issue #, if available

#14290

Description of how you validated changes

Discovered the first issue after 14.2.1 was released and was able to reproduce the second issue and verify that both are fixed by these changes.

Checklist

  • PR description included
  • yarn test passes
  • Tests are changed or added
  • Relevant documentation is changed or added (and PR referenced)
  • New AWS SDK calls or CloudFormation actions have been added to relevant test and service IAM policies
  • Pull request labels are added

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@ShadowCat567 ShadowCat567 changed the title fix: source profiles not working properly in certain situations fix: role assumption through profiles not working properly in certain situations Oct 31, 2025
@ShadowCat567 ShadowCat567 marked this pull request as ready for review October 31, 2025 20:58
@ShadowCat567 ShadowCat567 requested a review from a team as a code owner October 31, 2025 20:58
Comment thread packages/amplify-provider-awscloudformation/src/index.ts Fixed
@ShadowCat567 ShadowCat567 merged commit 04f7bcf into dev Oct 31, 2025
5 checks passed
@ShadowCat567 ShadowCat567 deleted the downgrade-cred-providers branch October 31, 2025 21:47
danrivett added a commit to danrivett/amplify-cli that referenced this pull request Jan 29, 2026
This commit fixes three related bugs in the credential caching logic for
MFA-based role assumption that were introduced in commit 04f7bcf
(PR aws-amplify#14315 "fix: role assumption through profiles not working properly").

Bug 1: MFA prompt never appears
----------------------------------------
getCachedRoleCredentials() always returned an object `{ credentials: {} }`
even when no valid cached credentials existed. This caused the check
`if (!roleCredentials)` in getRoleCredentials() to always be false,
so the STS AssumeRole call with MFA token was never executed.

Fix: Return undefined when no valid cached credentials exist.

Bug 2: Credential cache validation always fails
----------------------------------------
Credentials were cached in nested format `{ credentials: { accessKeyId, ... } }`
but validateCachedCredentials() expected flat format `{ accessKeyId, ... }`.
This caused cache validation to always fail, prompting for MFA on every call.

Fix: Cache the flat credentials object (roleCredentials.credentials) instead
of the nested wrapper.

Bug 3: "identity.expiration.getTime is not a function" error
----------------------------------------
When credentials are read from the JSON cache file, the Date object for
expiration is deserialized as a string. The AWS SDK's @smithy/core module
calls expiration.getTime() which fails on a string.

The fix in PR aws-amplify#14315 only addressed this in getConfiguredAWSClientConfig(),
but getProfiledAwsConfig() is called directly during env checkout without
going through that code path.

Fix: Convert expiration to Date when returning cached credentials.
danrivett added a commit to danrivett/amplify-cli that referenced this pull request Feb 26, 2026
…d credentials after v14.2.2.

This commit fixes three related bugs in the credential caching logic for
MFA-based role assumption that were introduced in commit 04f7bcf
(PR aws-amplify#14315 "fix: role assumption through profiles not working properly").

Bug 1: MFA prompt never appears
----------------------------------------
getCachedRoleCredentials() always returned an object `{ credentials: {} }`
even when no valid cached credentials existed. This caused the check
`if (!roleCredentials)` in getRoleCredentials() to always be false,
so the STS AssumeRole call with MFA token was never executed.

Fix: Return undefined when no valid cached credentials exist.

Bug 2: Credential cache validation always fails
----------------------------------------
Credentials were cached in nested format `{ credentials: { accessKeyId, ... } }`
but validateCachedCredentials() expected flat format `{ accessKeyId, ... }`.
This caused cache validation to always fail, prompting for MFA on every call.

Fix: Cache the flat credentials object (roleCredentials.credentials) instead
of the nested wrapper.

Bug 3: "identity.expiration.getTime is not a function" error
----------------------------------------
When credentials are read from the JSON cache file, the Date object for
expiration is deserialized as a string. The AWS SDK's @smithy/core module
calls expiration.getTime() which fails on a string.

The fix in PR aws-amplify#14315 only addressed this in getConfiguredAWSClientConfig(),
but getProfiledAwsConfig() is called directly during env checkout without
going through that code path.

Fix: Convert expiration to Date when returning cached credentials.
danrivett added a commit to danrivett/amplify-cli that referenced this pull request Feb 27, 2026
…th cached credentials (aws-amplify#14626)

Fixes three related bugs in credential caching for MFA-based role
assumption introduced in commit 04f7bcf (PR aws-amplify#14315).

Bug 1 - MFA prompt never appears: getCachedRoleCredentials() always
returned { credentials: {} } even with no valid cache, so the STS
AssumeRole call was never executed.

Fix: return undefined when no valid cached credentials exist.

Bug 2 - Cache validation always fails: credentials were cached in
nested format { credentials: { accessKeyId, ... } } but
validateCachedCredentials() expected flat format.

Fix: cache the flat credentials object (roleCredentials.credentials).

Bug 3 - expiration.getTime error: cached Date is deserialized as a
string, but the AWS SDK calls expiration.getTime(). The fix in
PR aws-amplify#14315 only addressed this in getConfiguredAWSClientConfig(), not
in getProfiledAwsConfig().

Fix: convert expiration to Date when returning cached credentials.
danrivett added a commit to danrivett/amplify-cli that referenced this pull request Mar 23, 2026
…th cached credentials (aws-amplify#14626)

Fixes three related bugs in credential caching for MFA-based role
assumption introduced in commit 04f7bcf (PR aws-amplify#14315).

Bug 1 - MFA prompt never appears: getCachedRoleCredentials() always
returned { credentials: {} } even with no valid cache, so the STS
AssumeRole call was never executed.

Fix: return undefined when no valid cached credentials exist.

Bug 2 - Cache validation always fails: credentials were cached in
nested format { credentials: { accessKeyId, ... } } but
validateCachedCredentials() expected flat format.

Fix: cache the flat credentials object (roleCredentials.credentials).

Bug 3 - expiration.getTime error: cached Date is deserialized as a
string, but the AWS SDK calls expiration.getTime(). The fix in
PR aws-amplify#14315 only addressed this in getConfiguredAWSClientConfig(), not
in getProfiledAwsConfig().

Fix: convert expiration to Date when returning cached credentials.
danrivett added a commit to danrivett/amplify-cli that referenced this pull request Mar 25, 2026
…th cached credentials (aws-amplify#14626)

Fixes three related bugs in credential caching for MFA-based role
assumption introduced in commit 04f7bcf (PR aws-amplify#14315).

Bug 1 - MFA prompt never appears: getCachedRoleCredentials() always
returned { credentials: {} } even with no valid cache, so the STS
AssumeRole call was never executed.

Fix: return undefined when no valid cached credentials exist.

Bug 2 - Cache validation always fails: credentials were cached in
nested format { credentials: { accessKeyId, ... } } but
validateCachedCredentials() expected flat format.

Fix: cache the flat credentials object (roleCredentials.credentials).

Bug 3 - expiration.getTime error: cached Date is deserialized as a
string, but the AWS SDK calls expiration.getTime(). The fix in
PR aws-amplify#14315 only addressed this in getConfiguredAWSClientConfig(), not
in getProfiledAwsConfig().

Fix: convert expiration to Date when returning cached credentials.
danrivett added a commit to danrivett/amplify-cli that referenced this pull request Mar 25, 2026
…th cached credentials (aws-amplify#14626)

Fixes three related bugs in credential caching for MFA-based role
assumption introduced in commit 04f7bcf (PR aws-amplify#14315).

Bug 1 - MFA prompt never appears: getCachedRoleCredentials() always
returned { credentials: {} } even with no valid cache, so the STS
AssumeRole call was never executed.

Fix: return undefined when no valid cached credentials exist.

Bug 2 - Cache validation always fails: credentials were cached in
nested format { credentials: { accessKeyId, ... } } but
validateCachedCredentials() expected flat format.

Fix: cache the flat credentials object (roleCredentials.credentials).

Bug 3 - expiration.getTime error: cached Date is deserialized as a
string, but the AWS SDK calls expiration.getTime(). The fix in
PR aws-amplify#14315 only addressed this in getConfiguredAWSClientConfig(), not
in getProfiledAwsConfig().

Fix: convert expiration to Date when returning cached credentials.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants