-
Notifications
You must be signed in to change notification settings - Fork 205
Introduce token cache and use it for GitHub App tokens #1745
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
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
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.
This pkg PR introduces cache in the auth/github pkg and caches the token once it is fetched. In scenarios where the token is invalid (for example: due to incorrectly permissions configured by the user), the git operations would fail with an error (similar to Unauthorized). The token needs to be invalidated from the cache in this case.
When we had attempted to add the cache as part of enabling Azure OIDC for gitrepository, we had discussed in the PR comment and the dev meetings to add the cache in the respective clients instead where the token is actually used. For example, for git operations, the cache would be added to git client. During clone operations, cached token would be fetched from the cache first. In case of a cache HIT, it would be used to do the clone. If the clone operation fails and the token is no longer valid it would be invalidated from the cache. In case of a cache miss or invalid token, a new token would be fetched using auth/github GetToken API. This token would be cached after successful clone operation.
Uh oh!
There was an error while loading. Please reload this page.
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.
Scenario 1: Permission errors
I just did a simple test here with our implementation for flux-operator, we have this code running in a cluster for a few days.
This was my experiment:
failed to call provider failed to list requests: could not list pull requests: GET https://api.github.com/repos/matheuscscp-test-org/test-repo/pulls?per_page=100&state=open: 403 Resource not accessible by integration []
To make sure that the cached token was not purged and was reused after I re-added the permission, I ran this command:
Only one log was printed, the same one I saw before the experiment by running the same command and looking at the timestamp.
Conclusion: Purging the token from the cache doesn't help when the token is invalid due to permissions. That's because the token represents an identity. The set of permissions associated with that identity are not embedded on the token. So the token is not really invalid, it just happens that the identity it represents lacks permissions. The token remains valid and that is proven by the fact that the reconciliation resumed after I re-added the permissions.
Scenario 2: GitHub App is deleted/replaced, or reinstalled in the org/repo, or the private key is rotated, or the base URL is changed
If any of these events happen, the token key will change, see how the cache key is built:
https://github.com/fluxcd/pkg/blob/8b1f852228b117123efcc7b5708ce112801416b6/auth/github/client.go#L232-L241
Conclusion: The cached token is effectively a function of
(appID, installationID, baseURL, privateKey)
. If these remain the same, the cached token remains valid if it's not expired.Overall Conclusion
There are no real scenarios where purging the token from the cache really helps, we don't need to worry about that.
P.S.: We expire tokens with 80% of their lifetime, so there's no risk of getting errors due to expired token.
Uh oh!
There was an error while loading. Please reload this page.
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.
I don't think this approach is good, because a GitHub App could be used for multiple different things, not just cloning a git repo. We're gonna use GitHub App tokens for other things in Flux e.g. for the notification providers. We shouldn't cache a token twice, once for the
github
provider and once for thegithubdispatch
provider, if the underlying app/installation/baseURL/privateKey is the same for bothProvider
objects.So, again, the token is a function of
(appID, installationID, baseURL, privateKey)
, not(appID, installationID, baseURL, privateKey, use case)
.The same idea will apply when we implement caching for OIDC tokens. They are a function of the identity they represent, not
(identity, use case)
. We will share a token for aBucket
and anOCIRepository
object if the identity they want to impersonate is the same and we already have a token for it.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.
Makes sense, thanks for the detailed test scenarios and explanation.
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.
This comment was very important 👍 Let's leave this thread unresolved as it contains a lot of information that is important for whoever reads this PR in the future, even after merged