Discussed in #414
Originally posted by nwsparks April 13, 2026
in our environment we need to regenerate credentials every hour. im using a shared credential file ~/.aws/credentials
in order to generate new credentials I'm running this https://github.com/venth/aws-adfs from bash which is updating the shared credential file.
prior to upgrading to v5, when the value of that file would change, pwsh would seamlessly pick it up. after upgrading to v5 i have to restart the pwsh session. I'm also having difficult when changing accounts as it seems to be caching the old account somehow.
Description
Users who rotate credentials via external tools (e.g. aws-adfs) that write to ~/.aws/credentials find that PS Tools v5 does not pick up the new credentials mid-session. This worked in v4. The user has to restart PowerShell or manually run Clear-AWSCredential.
Root Cause
Two caching layers prevent file changes from being detected:
-
$StoredAWSCredentials session variable. Once TryGetCredentials() in CredentialsArguments.cs resolves credentials, the result is stored in $StoredAWSCredentials. Subsequent cmdlet calls hit lines 151-157 and short-circuit, returning the cached credentials without re-reading the profile chain. The SharedCredentialsFile.Refresh() path (which does re-read from disk) is never reached.
-
DefaultAWSCredentialsIdentityResolver.EnvironmentState (lines 311-340 in DefaultAWSCredentialsIdentityResolver.cs). The HasEnvironmentChanged() method only monitors four environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN, AWS_PROFILE). It does not check the credentials file mtime. This was deliberately scoped to env vars in PR #3590 (commit 9dd33271). File-based rotation was not considered.
In v4 (SDK v3), the $StoredAWSCredentials short-circuit path was less aggressively used, so the profile chain probe ran more often and SharedCredentialsFile.Refresh() re-read the file on each cmdlet call.
Suggested Fix
Add credentials file change detection to EnvironmentState.HasEnvironmentChanged(). Snapshot the file's last-modified timestamp alongside the env var snapshot, and include it in the invalidation check. SharedCredentialsFile.Refresh() already handles re-reading, the missing piece is triggering it when the file changes.
Updated Analysis
Dug into this more and the straightforward EnvironmentState fix is riskier than it looks. HasEnvironmentChanged() gets called on every API request through the auth pipeline (BaseAuthResolverHandler.PreInvoke -> ResolveIdentity -> InternalGetCredentials), so adding a file stat there means a syscall on every request. That's going to hurt at high throughput and on NFS/network home dirs. It also opens the door to cache thrashing for credential_process users where the helper touches the credentials file during refresh, which would trigger a full re-resolution (including re-running the subprocess) on every write. And we'd need to watch ~/.aws/config too since SSO profiles live there, not just ~/.aws/credentials.
Probably better to fix this closer to where the problem actually is:
- Fix it in the PS Tools layer (preferred). The regression is really about
$StoredAWSCredentials short-circuiting the file re-read in interactive sessions. We could invalidate that cache when the credentials file changes without touching the SDK's per-request auth path at all. No impact on Lambda/ECS/high-throughput workloads.
- Opt-in flag in SDK Core. (don't love this one) Add something like
EnableFileSystemWatch (default off) that PS Tools can flip on. Keeps the cost opt-in.
- Throttled stat in SDK Core. If it has to live in Core, at least cap the file check to once every N seconds so we're not doing a stat per request.
Workaround
Run Clear-AWSCredential after external credential rotation to force the next cmdlet to re-read from disk.
References
Description
Users who rotate credentials via external tools (e.g. aws-adfs) that write to
~/.aws/credentialsfind that PS Tools v5 does not pick up the new credentials mid-session. This worked in v4. The user has to restart PowerShell or manually runClear-AWSCredential.Root Cause
Two caching layers prevent file changes from being detected:
$StoredAWSCredentialssession variable. OnceTryGetCredentials()inCredentialsArguments.csresolves credentials, the result is stored in$StoredAWSCredentials. Subsequent cmdlet calls hit lines 151-157 and short-circuit, returning the cached credentials without re-reading the profile chain. TheSharedCredentialsFile.Refresh()path (which does re-read from disk) is never reached.DefaultAWSCredentialsIdentityResolver.EnvironmentState(lines 311-340 inDefaultAWSCredentialsIdentityResolver.cs). TheHasEnvironmentChanged()method only monitors four environment variables (AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY,AWS_SESSION_TOKEN,AWS_PROFILE). It does not check the credentials file mtime. This was deliberately scoped to env vars in PR #3590 (commit9dd33271). File-based rotation was not considered.In v4 (SDK v3), the
$StoredAWSCredentialsshort-circuit path was less aggressively used, so the profile chain probe ran more often andSharedCredentialsFile.Refresh()re-read the file on each cmdlet call.Suggested Fix
Add credentials file change detection toEnvironmentState.HasEnvironmentChanged(). Snapshot the file's last-modified timestamp alongside the env var snapshot, and include it in the invalidation check.SharedCredentialsFile.Refresh()already handles re-reading, the missing piece is triggering it when the file changes.Updated Analysis
Dug into this more and the straightforward
EnvironmentStatefix is riskier than it looks.HasEnvironmentChanged()gets called on every API request through the auth pipeline (BaseAuthResolverHandler.PreInvoke->ResolveIdentity->InternalGetCredentials), so adding a file stat there means a syscall on every request. That's going to hurt at high throughput and on NFS/network home dirs. It also opens the door to cache thrashing forcredential_processusers where the helper touches the credentials file during refresh, which would trigger a full re-resolution (including re-running the subprocess) on every write. And we'd need to watch~/.aws/configtoo since SSO profiles live there, not just~/.aws/credentials.Probably better to fix this closer to where the problem actually is:
$StoredAWSCredentialsshort-circuiting the file re-read in interactive sessions. We could invalidate that cache when the credentials file changes without touching the SDK's per-request auth path at all. No impact on Lambda/ECS/high-throughput workloads.EnableFileSystemWatch(default off) that PS Tools can flip on. Keeps the cost opt-in.Workaround
Run
Clear-AWSCredentialafter external credential rotation to force the next cmdlet to re-read from disk.References
DefaultAWSCredentialsIdentityResolver.cslines 311-340 (EnvironmentState)DefaultAWSCredentialsIdentityResolver.cslines 318-329 (HasEnvironmentChanged)9dd33271(scoped invalidation to env vars)