aws-sdk-java-v2 icon indicating copy to clipboard operation
aws-sdk-java-v2 copied to clipboard

StsWebIdentityTokenFileCredentialsProvider not respecting prefetchTime and staleTime configuration

Open shailendher opened this issue 7 months ago • 5 comments

Describe the bug

We were trying to override the StsWebIdentityTokenFileCredentialsProvider with a custom configuration as below but it doesn't seem to work.

StsWebIdentityTokenFileCredentialsProvider.builder()
        .asyncCredentialUpdateEnabled(true)
        .stsClient(StsClient.create())
        .prefetchTime(Duration.ofMinutes(35))
        .staleTime(Duration.ofMinutes(30))
        .build();

Inspecting the code, it seems that StsWebIdentityTokenFileCredentialsProvider is a wrapper over StsAssumeRoleWithWebIdentityCredentialsProvider but it doesn't pass the parameters when initializing it at line106-110. Shouldn't it pass all the parameters upstream?

Regression Issue

  • [ ] Select this option if this issue appears to be a regression.

Expected Behavior

StsWebIdentityTokenFileCredentialsProvider should respect prefetchTime and staleTime

Current Behavior

StsWebIdentityTokenFileCredentialsProvider ignores the prefetchTime and staleTime parameters.

Reproduction Steps

  • Create a custom provider using this configuration:
StsWebIdentityTokenFileCredentialsProvider.builder()
        .asyncCredentialUpdateEnabled(true)
        .stsClient(StsClient.create())
        .prefetchTime(Duration.ofMinutes(35))
        .staleTime(Duration.ofMinutes(30))
        .build();
  • Verify if the session is refreshed as expected either via debug logs or Cloudtrail logs.

Possible Solution

No response

Additional Information/Context

From what I understand, the workaround is to use StsAssumeRoleWithWebIdentityCredentialsProvider directly by passing the necessary EKS pod env variables to it.

AWS Java SDK version used

v2 2.31.63

JDK version used

24

Operating System and version

amazoncorretto:24-alpine

shailendher avatar Jun 16 '25 16:06 shailendher

Hello @shailendher,

Thank you for reporting the issue. I am able to reproduce the scenario using below code snippet. I will discuss this further with the team for next steps.

Main.java
package org.example;

import software.amazon.awssdk.auth.credentials.AwsCredentials;
import software.amazon.awssdk.services.sts.StsClient;
import software.amazon.awssdk.services.sts.auth.StsWebIdentityTokenFileCredentialsProvider;

import java.time.Duration;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {

        System.setProperty("aws.webIdentityTokenFile", "/tmp/***/web-identity-token.txt");
        System.setProperty("aws.roleArn", "arn:aws:iam::****:role/**Role");
        System.setProperty("aws.roleSessionName", "local-test-session");
        System.setProperty("aws.region", "us-east-1");

        var client = StsWebIdentityTokenFileCredentialsProvider.builder()
                .asyncCredentialUpdateEnabled(true)
                .stsClient(StsClient.builder().build())
                .refreshRequest(req -> req.durationSeconds(900)
                        .roleArn(System.getProperty("aws.roleArn"))
                        .roleSessionName(System.getProperty("aws.roleSessionName")))
                .prefetchTime(Duration.ofMinutes(14)) //for 15 mins of session duration
                .staleTime(Duration.ofMinutes(12)) //for 15 mins of session duration
                .build();

        String previousAccessKey = null;

        try {
            for (int i = 1; i <= 15; i++) {
                System.out.println("\n=== Check " + i + " at " +
                        Instant.now().atZone(ZoneId.of("America/Los_Angeles"))
                                .format(DateTimeFormatter.ofPattern("HH:mm:ss")) + " ===");

                AwsCredentials credentials = client.resolveCredentials();
                String currentAccessKey = credentials.accessKeyId();

                if (previousAccessKey != null && !currentAccessKey.equals(previousAccessKey)) {
                    System.out.println("SDK REFRESHED CREDENTIALS! New key: " + currentAccessKey);
                } else {
                    System.out.println("Access Key: " + currentAccessKey);
                }

                if (credentials.expirationTime().isPresent()) {
                    Instant expiration = credentials.expirationTime().get();
                    Duration timeLeft = Duration.between(Instant.now(), expiration);
                    System.out.println("Minutes until expiration: " + timeLeft.toMinutes());

                    previousAccessKey = currentAccessKey;
                    Thread.sleep(60000);
                }
            }
        } catch (Exception e) {
            System.err.println("Error: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Regards, Chaitanya

bhoradc avatar Aug 07 '25 22:08 bhoradc

Also having the same issue. Any updates about it? Thanks!

fcappi avatar Sep 29 '25 12:09 fcappi

Analysing the code, it looks like a simple fix by copying the values from builder. Would it be helpful if I submit a PR for this?

fcappi avatar Sep 29 '25 13:09 fcappi

@bhoradc Could you please assign this to me?

fcappi avatar Oct 06 '25 13:10 fcappi

Hi @fcappi

Thanks for your interest in submiting PR, external contributions are always welcomed. Feel free to submit a PR for the SDK review. You can link this issue to the changes you submit.

Regards, Chaitanya

bhoradc avatar Oct 21 '25 20:10 bhoradc