fix: stop the badge sweep re-triggering SSO sign-in every cycle - #16
Open
marcioviniciusspiridigliozzi-dot wants to merge 1 commit into
Conversation
The sweep loads a hibernated service's real URL in a transient web view to read its badge. When that service's session has expired, the load is redirected to the identity provider and returns nothing — and the next sweep does it again, and the one after that. On an SSO tenant each of those redirects is a fresh approval request. One user saw 68 authenticator pushes in 14 hours from two services, arriving at the sweep's own cadence: 20s apart within a cycle, 4m03s between cycles. Retrying can never help, because a transient web view has no way to sign anyone in. So park a service after two consecutive fetches that end off-host with no count, and let it back in the moment the user opens it — which is the only place a sign-in can actually be completed. The release runs first in the sweep, because a service with a live web view is filtered out of the target list and would otherwise stay parked forever. Two strikes rather than one: a slow hydrate can also finish off-host with nothing readable, and parking by mistake costs a stale badge until the service is opened.
marcioviniciusspiridigliozzi-dot
force-pushed
the
fix/badge-sweep-sso-storm
branch
from
August 11, 2026 10:27
ae8fc2d to
600859f
Compare
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 join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
The hibernated-badge sweep loads a service's real URL in a transient web view to read its badge. When that service's session has expired, the load is redirected to the identity provider and comes back with nothing. The next sweep does the same, and the one after that.
On an SSO tenant every one of those redirects is a fresh approval request. One user here saw 68 authenticator pushes in 14 hours from two services, arriving at the sweep's own cadence: 20 seconds apart within a cycle, 4m03s between cycles.
That is worth treating as more than an annoyance. Repeated unexplained push prompts are exactly the conditioning that MFA fatigue attacks rely on — someone who has learned to tap "approve" to make the buzzing stop is one prompt away from approving somebody else's sign-in.
Retrying can never help, either. A transient web view has no way to sign anyone in, so the sweep is generating approval requests it could not consume even if the user granted them.
The change
Park a service after two consecutive fetches that end off-host with no count, and let it back in the moment the user opens it — which is the only place a sign-in can actually be completed.
Two strikes rather than one because a slow hydrate can also finish off-host with nothing readable, and parking by mistake costs a stale badge until the service is next opened. That seemed the right way round: a late badge is cheap, a missed one is not.
The release runs first in the sweep. A service with a live web view is filtered out of the target list, so releasing later would leave it parked forever.
The decision itself is factored into
AuthWallResolver.looksLikeSignInWallso it can be tested without a live web view — covered for the off-host-and-empty case, the same-host-and-empty case (an authenticated inbox that is simply empty), the redirected-but-counted case, and the unresolved-host case.Note on CI
This branches from
main, which currently has an intermittentStoreRepairtest flake — I sent a separate fix for it in #15. Until that lands, a red run here is most likely that flake rather than this change. I re-ran this branch with #15's fix applied underneath: 0 failures in 8 runs, against 1 in 4 without it.