Skip to content

Commit 1e97ce1

Browse files
committed
fix(aws): serve unexpired workload credentials when an exchange fails
Outside an executing attempt no workload-identity token can be minted, so a post-run metrics flush near the refresh window failed even though the cached credentials were still valid. A failed exchange now keeps serving the cached credentials until a minute before they expire.
1 parent e47cd97 commit 1e97ce1

1 file changed

Lines changed: 20 additions & 2 deletions

File tree

  • apps/sim/lib/core/config

‎apps/sim/lib/core/config/aws.ts‎

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,25 @@ function getWorkloadProvider(roleArn: string): AwsCredentialsProvider {
4545
return workloadProvider
4646
}
4747

48+
/** Credentials this close to expiry are treated as expired, so a signed request never outlives them. */
49+
const EXPIRY_SKEW_MS = 60_000
50+
51+
function remainingMs(credentials: AWSCredentials | null): number {
52+
return credentials ? credentials.expiration.getTime() - Date.now() : 0
53+
}
54+
4855
/**
4956
* The cached workload credentials while they have more than `minRemainingMs` left, otherwise a
50-
* fresh exchange. Concurrent callers share one exchange.
57+
* fresh exchange. Concurrent callers share one exchange. When the exchange fails, still-valid
58+
* cached credentials are served instead: outside an executing attempt no token can be minted, and
59+
* work a run leaves behind (the metrics flush) must not lose credentials that have not expired.
5160
*/
5261
function resolveWorkloadCredentials(
5362
roleArn: string,
5463
minRemainingMs: number
5564
): Promise<AWSCredentials> {
5665
const current = currentWorkloadCredentials
57-
if (current && current.expiration.getTime() - Date.now() > minRemainingMs) {
66+
if (current && remainingMs(current) > minRemainingMs) {
5867
return Promise.resolve(current)
5968
}
6069
if (!pendingWorkloadCredentials) {
@@ -63,6 +72,15 @@ function resolveWorkloadCredentials(
6372
currentWorkloadCredentials = credentials
6473
return credentials
6574
})
75+
.catch((error: unknown) => {
76+
const cached = currentWorkloadCredentials
77+
if (!cached || remainingMs(cached) <= EXPIRY_SKEW_MS) throw error
78+
logger.warn('Workload-identity exchange failed; serving cached credentials until expiry', {
79+
error,
80+
remainingMs: remainingMs(cached),
81+
})
82+
return cached
83+
})
6684
.finally(() => {
6785
pendingWorkloadCredentials = null
6886
})

0 commit comments

Comments
 (0)