Share one Keycloak admin client across parallel team syncs - #4
Merged
Merged
Conversation
Every team sync built its own KeycloakAdmin, and teams are synced in a
thread pool, so each run fired several concurrent password grants for the
same service account. Keycloak intermittently rejects one of them:
keycloak.exceptions.KeycloakPostError: 400: b'{"error":"invalid_grant",
"error_description":"Invalid user credentials"}'
and that team's sync fails with "KEYCLOAK group returned empty" while the
team next to it, using the same credentials, succeeds.
Build the client once per process and reuse it; token (re)acquisition is
serialised behind a lock so threads never race each other to the token
endpoint. python-keycloak already refreshes the shared token on expiry.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UGRXmBT8HSsodKUkYXRAZK
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.
Problem
In prod, one team's sync intermittently fails while the team syncing alongside it — same credentials, same second — succeeds:
sync_all_teamsruns teams in aThreadPoolExecutor(max_workers=10), anddirectory_group_membersbuilds a freshDirectoryClient()→KeycloakAdminper call. So each run fires N concurrent password grants for the same service account, and Keycloak rejects some of them.Fix
githubapp/keycloak.py:KeycloakAdminper process (lazily, under a lock) and hand it to everyKeycloak()instance.KeycloakOpenIDConnectionsorefresh_token()is serialised: a thread that waits on the lock re-checksexpires_atand skips the refresh if another thread already did it.python-keycloakalready handles refreshing the shared token on expiry, so the only behavioural change is one login session instead of one per team per run.Verification
ruff check/ruff format --checkclean.KeycloakOpenID.tokenmocked: 10 threads each constructingKeycloak()and forcing a refresh → 1 client instance, 1 password grant (previously 10).🤖 Generated with Claude Code
https://claude.ai/code/session_01UGRXmBT8HSsodKUkYXRAZK