Closed tgoodsell-tempus closed 5 months ago
Hi @tgoodsell-tempus, thanks for opening this issue. The credential provider fromWebToken is not intended to handle expiration, since it expects to always be provided with a valid token. Something you can do here is to add a custom credential provider where you handle when a token is expired and supply that custom implementation as the credential provider for the SDK client you will use. Here is a simple example:
import {GetCallerIdentityCommand, STSClient} from "@aws-sdk/client-sts";
import {fromWebToken} from "@aws-sdk/credential-providers";
async function main() {
const isExpired = (token) => {
// Check if token is expired
return true;
};
const myIdTokenGetter = async () => {
// Generate a new fresh token
return ''
};
let currentToken;
const stsClient = new STSClient({
credentials: async () => {
if (!currentToken || isExpired(currentToken)) {
currentToken = await myIdTokenGetter();
}
return await fromWebToken({
roleArn: "someARN",
webIdentityToken: currentToken,
roleSessionName: "sessionName",
durationSeconds: 900,
})();
},
region: 'us-east-1'
});
const testCmd = new GetCallerIdentityCommand({});
const resp = await stsClient.send(testCmd);
console.log(resp);
setInterval(() => {
stsClient.send(testCmd).then(data => {
console.log(data);
}).catch(err => {
console.error(err);
});
}, 900000)
}
await main();
Please let me know if that helps!
Thanks!
Hi @yenfryherrerafeliz
Your workaround idea has been working as expected for our initial testing, when swapping in our own ID token getting code, so I appreciate your guidance there!
However, I'm not fully satisfied with this outcome:
fromWebToken
provider itself not being setup to handle the expiration of the input token, and my interpretation you (or the managing group for this as a whole) believe that to be "correct" is difficult to understand. As the AssumeRoleWithWebIdentity
is entirely based around the use of OAuth 2.0 Access Tokens or OIDC Identity Tokens, both of which will have some sort of expiration as a best practice (and really a practical security requirement), that choice goes against the fundamentals of this sort of mechanism. The workaround requiring the entire fromWebToken
block instead of only the token field (since that's really the only item which changes in a "normal" circumstance) also seems really unintuitive.credentials
field, minimally this should be dealt with by including the need to do this in the SDK documentation and calling out the behavior of the underlying fromWebToken
provider.This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs and link to relevant comments in this thread.
Checkboxes for prior research
Describe the bug
Based on my experimentation and general lack of information on this in the docs:
The
fromWebToken
method in thecredential-providers
package is unable to deal with the eventual expiration of an ID token. Since thetoken
value is passed as astring
instead of a promise/function (or something else), the value is statically encoded into the configuration and is not detected or able to handle refreshing.Perhaps this function should be explicitly updated to take one of the aforementioned types, which would allow the user to fulfill with whatever logic / source they need to ensure a valid ID token is returned on each call.
Docs: https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-aws-sdk-credential-providers/#fromwebtoken
SDK version number
@aws-sdk/credential-providers@3.315.0
Which JavaScript Runtime is this issue in?
Node.js
Details of the browser/Node.js/ReactNative version
Node 20.6.1
Reproduction Steps
Observed Behavior
Basically we get errors like the following once the ID token expires:
Expected Behavior
Generally I would expect the interface which we provide our ID token to allow for some need for that value to change due to expiration or other reasons. I suppose we had expected that when feeding the function value instead of a string const or something it would take care of that, however that goes against the primitive
pass by value
conventions so that would be wrong to expect in reality.Possible Solution
Instead of using a primitive string input, something like a promise, function, generator, etc would be more useful for this. Something that the middleware would know to go call and fetch/retrieve a real token value from before it performs the AWS token refresh cycle. Outside of that, the logic on handling the ID token should probably still remain in the hands of the developer.
Additional Information/Context
No response