This repository was archived by the owner on Sep 30, 2024. It is now read-only.
[Backport 5.5.x] fix(appliance): cache authorization status#64219
Merged
Conversation
In order to reduce the cost of calls to auth-gated endpoints, cache valid admin passwords in-memory. The appliance's frontend calls auth-gated endpoints in a tight loop, and bcrypt checking is intentionally an expensive operation. This could occasionally cause the appliance-frontend to disconnect from the backend. We observed frontend's nginx reporting an upstream connection close, and exec'ing into its pod and curling the backend regularly hung. (cherry picked from commit 156aa5a)
Chickensoupwithrice
approved these changes
Aug 1, 2024
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
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
In order to reduce the cost of calls to auth-gated endpoints, cache valid admin passwords in-memory. The appliance's frontend calls auth-gated endpoints in a tight loop, and bcrypt checking is intentionally an expensive operation.
This could occasionally cause the appliance-frontend to disconnect from the backend. We observed frontend's nginx reporting an upstream connection close, and exec'ing into its pod and curling the backend regularly hung.
I collected two CPU profiles from the appliance backend: one without this commit, one with it. In both cases, SG was not being installed - the frontend was running, and I had a browser tab open, so that the browser was hitting the backend frequently via the nginx API proxy.
Without this fix:
With this fix:
See the test plan below for how I obtained these CPU profiles.
2 things stand out between them: without this fix, the total CPU time consumed over the 30-second profiling period is 1000s of times larger! On my mac (so not even contending with other processes on a kubernetes node), it used 25 seconds of CPU time - almost saturating a core. We can also see that calls to
bcrypt.CompareHashAndPassword()are responsible for all of this.It's perhaps not ideal from a security perspective to memory-cache the password, but subjectively this trade-off seems like a reasonable way to get moving. Let me know what you think though.
This is a necessary step for https://linear.app/sourcegraph/issue/REL-308/appliance-frontend-seems-to-disconnect-the-backend-during-installation but does not close it. This is because the disconnection bug still occurs, after clicking wait-for-admin, but I think this instance of it is for a different reason. See https://github.com/sourcegraph/sourcegraph/pull/64216 for an explanation and fix of that reason.
Test plan
Starting on the https://github.com/sourcegraph/sourcegraph/pull/64211 branch, not this one:
In one terminal:
In another:
Navigate to localhost:8889 in a web browser and log into the appliance. You don't need to begin installing SG, just leave the tab open.
In another terminal:
go tool pprof -png -output appliance-cpu-main.png 'http://localhost:6061/debug/pprof/profile?seconds=30Repeat the experiment for this branch (but with https://github.com/sourcegraph/sourcegraph/pull/64211 merged into it, for pprof), and compare profiles.
Finally, I deployed this branch to my local minikube environment to see how it interacted with the ingress stack:
I saw no disconnections during SG's installation, until the race condition I described further up kicked in after clicking wait-for-admin, and I had to refresh the page in order to see site-admin.
Changelog
Backport 156aa5a from #64213