-
Notifications
You must be signed in to change notification settings - Fork 6.8k
feat: add support for httpcaching of github requests (alpha) #25879
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
base: master
Are you sure you want to change the base?
feat: add support for httpcaching of github requests (alpha) #25879
Conversation
❗ Preview Environment deployment failed on BunnyshellSee: Environment Details | Pipeline Logs Available commands (reply to this comment):
|
9325450 to
399c6e5
Compare
|
Do we need to be concerned with security implications? For example, might an AppSet be able to retrieve a response that happens to be available in the cache that it wouldn't be able to access if it had to go to GitHub to auth? Do we need the cache to be segmented by AppSet or secret or something like that? |
The caching library used here handle the segmentation internally IMO the security questions to consider are more:
Could be an option but it will improve the performance more than the security the Etag recalculation will happen a bit less. |
b2d6f1d to
7ac057c
Compare
812e17f to
24b8971
Compare
ppapapetrou76
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we also add metrics?
You can use lru.NewWithEvict to capture evictions and increment metrics.
f8061ac to
9a3432c
Compare
@ppapapetrou76 will add the metrics layer later once other remarks will be solved |
98bb0f6 to
c2d466c
Compare
f20f112 to
84d7fd4
Compare
d70a8f4 to
e7f433b
Compare
I'm a bit worried about this actually. The library is pretty clear that it does this by having reverse-engineered the Etag and this is undocumented behavior and is not supported by GitHub. And while it works fine, I'm not sure we should be depending on behaviors that could be changed by GitHub any day without notice. I'm wondering if we should just use standard HTTP conditional requests despite the drawback of having more cache misses when the credentials change |
@alexymantha for github app it's not useful at all since we recreate the token on each reconciliation loop On our side we are using github app and we do understand the risk if Github change the Etag behaviour. |
0409044 to
ca1efdf
Compare
The way we've done it internally is to reuse the ghinstallation transport and it will only generate a new token when the old one expires, so the cache only has to rebuild every hour when the token changes. It's a bit trickier here since the appset may not use the same credentials and may not have access to the same things so we would need to keep track of which transports to use, pretty similar to how you use the cache context to have different storage for different secrets I will let the maintainers decide if they are confortable using the reverse-engineered behavior, I just wanted to highlight it. |
e26b1f1 to
ae4d792
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR and for looking into resolving the GitHub API rate limit, which is a common issue, in Argo CD!
I have the following concerns about using this library:
- Security-wise, does the statement
Using this reverse-engineered ETag algorithm, we can develop a [http.RoundTripper](https://pkg.go.dev/net/http#RoundTripper) that allows a GitHub REST API response that was cached/returned for a different Authorization header to be safely reused.mean we are risking AppSet to return data a user is not authorized to see? - The library is not widely maintained, there are no releases and just 3 contributors (I realize it addresses a very narrow and specific area, but still)
- Having an Argo CD critical component depend on a reverse engineering of unofficial features and GitHub internals is problematic since the original GitHub behavior may change without notice
I think it's ok, that's what I understood about this mechanism:
So it's always the same user |
edf6053 to
b334118
Compare
|
As discussed during the Argo CD Contributor Meeting 22th January with you @reggie-k The unofficial features is not something that Argo CD will allow so the all PR need a revamp Why this unofficial features was used? because of the way ArgoCD handle Github App token management As @crenshaw-dev mention the transport implementation need to follow the given principle:
Move back the PR to draft and will rework the Github App token management and the cache to not use unofficial features. |
37b0a62 to
3527d1a
Compare
Signed-off-by: Jean-Damien HATZENBUHLER <jean-damien.hatzenbuhler@contentsquare.com>
3527d1a to
bf48c18
Compare
Signed-off-by: Jean-Damien HATZENBUHLER <jean-damien.hatzenbuhler@contentsquare.com>
bf48c18 to
b3df75e
Compare
Signed-off-by: Jean-Damien HATZENBUHLER <jean-damien.hatzenbuhler@contentsquare.com>
b3df75e to
07662aa
Compare
Description
This PR adds:
cache for Github App RoundTripper
As described in here, the cache will
Varydepending mainly from theAuthorizationheader that will renew every 1h (see for the Github App.In the applicationset controller, the Github App RoundTripper is recreated at every reconciliation loop meaning that the life time for a token is the reconciliation time.
The Github App RoundTripper cache solve this issue by reusing the same Github App RoundTripper at each reconciliation loop, the token have then a 1h lifetime instead of few seconds.
LRU cache for the github requests
The cache check if the the
Varyheader are the same before using the stored cacheWe use a hash to store the
Authorizationheader in memorySome critical header are removed from the request cache before storing
With the previous fix the cache will be fully recreated at most every hour instead of never like proposed in here
How Has This Been Tested?
Deployed the fix on our production by building a custom image and we get a ~90% cache hit

see
Motivation
Fixes #11376
Checklist
Checklist: