-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refresh credentials for assume-role-with-web-identity calls #2641
Comments
As a reference, this issue has been surfaced in the Python lib: boto/boto3#2345 and also referenced here. It'd be nice to have an agreed upon way to do this. |
You can mange the refresh timing/scheduling yourself by calling the client = get_dynamodb_client # get your client
credentials = client.config.credentials # this should be the AssumeRoleCredentials
credentials.refresh! if credentials.respond_to? :refresh! # in case these are not RefreshingCredentials |
@alextwoods let me give that a shot and get back to you :-) then for more advice. |
@alextwoods what would you say to doing something like:
and in an initializer, do something like:
We're running on Rails 6 with a Puma webserver. |
That seems pretty reasonable overall - I'm not sure what your environment is exactly - but I'd potentially consider a check on the |
@alextwoods would you be opposed to me trying 🙂 to add a method in RefreshingCredentials that checks to see if an options for Something like:
I'm wondering if one can just pass the client with a parameter of |
Just to be clear (realize that I wasn't), by trying I meant opening a pull request 😅🙇🏽♂️ |
I'm not opposed to providing some utility to help with the refreshing of credentials - however, I'm concerned about adding it as a parameter (even default disabled) that would get used as pat of the default provider chain. Spawning threads for credential refreshing could be unintended/surprising for users - especially those that are creating a large number of clients. |
Just another thought - what if the refresh when credentials were close to expiration (ie, 5 minutes before expiration) but still valid was async? That is - the current request would use the existing, non expired credentials, but kick off a thread that would refresh the credentials in the background? |
Do you mean something here where we do something like:
I can see the benefit to doing something like that then is that the process checking credentials kicks off a background thread to refresh credentials instead of actually calling the auth API in-line. I think it would help with preventing a lock occurring on the main thread that's executing the credentials code and relieve an external network call 🤔 EDIT: Actually scratch everything below, but now I realize... we may be checking Actually @alextwoods I had a question now that I am looking at the code (assuming you are more familiar here 😅) - are we 100% sure it's thread-safe? It looks like we are potentially invoking multiple calls to refresh the credential token and there's a potential check-then-act race condition.
Here's a timeline where I'm wondering (could be wrong) if there's a bug. Assuming t1 and t2 are two threads operating on with an AWS client instance.
Basically -- are we updating |
Yeah - I recently had to dig into this while looking at another, related issue, but I do believe the code as is is correct (ish *, I think there is another related threading weirdness). The reason the So that means in your step 5, t1 will acquire the mutex, but will NOT call refresh unnecessarily. EDIT: Saw you noticed this as well, but leaving the explanation for posterity. However, there is the possibility of another weird ordering:
However, I don't believe the @credentials can be only partially updated at step 4 (they'll either be the valid old creds or also valid new creds) - its just unpredictable which t1 may end up with. |
Ah yeah, the optimization for lock fetching makes sense. As for old/new value -- hard to say 😂 (my Ruby threading knowledge is still getting there) my understanding is that there's a potential of Ruby caching whereby one needs to acquire a mutex for the most updated value of a critical variable, but in this case I imagine it's fine since we refresh near expiration. I think the visibility section of this article might explain why a stale value gets returned sometimes. Regarding implementation I can try to open a PR soon (should be within a few days) to see if I can get the async / Thread idea up. |
PR here - #2642 |
|
Is your feature request related to a problem? Please describe.
When using a
DynamoDB
client,AssumeRoleWithWebIdentity
calls happen on EKS pods to grab a AWS token using the STS client. In a Rails app, this solution can be subverted by initializing a singleton client instance on boot using the initializer. However there's an expiration time tied to these tokens and if a cluster has a lot of pods -- then those clients are going to spike in latency whenever it makes those requests to re-fetch the token since it has to make the STS client call again.Describe the solution you'd like
In the
Aws::DynamoDB::Client
or any AWS client, there should be an easy way to specify refresh.Describe alternatives you've considered
Currently I'm exploring if there's a way to implement a refresh mechanism myself using
Thread
s and having it run in the same process that's serving web requests.The text was updated successfully, but these errors were encountered: