/admin/realms/{realm}/users is slow for “view-only” callers due to per-user group traversal in access checks (N+1 USER_GROUP_MEMBERSHIP)
#46,682 创建于 2026年2月27日
仓库指标
- 星标
- (34,398 个星标)
- PR 合并指标
- (平均合并 6天 19小时) (30 天内合并 384 个 PR)
描述
Before reporting an issue
- I have read and understood the above terms for submitting issues, and I understand that my issue may be closed without action if I do not follow them.
Area
organizations
Describe the bug
When calling /admin/realms/{realm}/users with a token that does not have global manage-users, Keycloak computes UserRepresentation.access for each user and falls back to group-based permission evaluation, which calls user.getGroupsStream() per listed user. This produces N+1 SQL like: select ... from USER_GROUP_MEMBERSHIP where USER_ID=? This makes the endpoint much slower for readonly/service accounts than for fully privileged admins. Related tickets in the same area: #31519 (admin API slow with fine-grained authz)
Version
26.3.3
Regression
- The issue is a regression
Expected behavior
If the caller has no group permissions that could possibly allow “manage members”, Keycloak should avoid walking each listed user’s group memberships just to compute access flags. User listing should be able to remain fast for view-only callers.
Actual behavior
Listing N users triggers O(N) user-group membership DB queries just for access evaluation.
How to Reproduce?
Realm with many users (10k+), users have group memberships.
Create a service account / user with permission to view users, but not global manage-users.
Enable Hibernate SQL logging.
Call:
curl -k -H "Authorization: Bearer <token>" \ "https://<host>/admin/realms/<realm>/users?briefRepresentation=true&max=1000"
Observe per-user USER_GROUP_MEMBERSHIP where USER_ID=? queries.
Anything else?
The access computation in the /users listing path sets rep.access per user and triggers a canManageByGroup(user) fallback which evaluates the user’s groups/hierarchy. A request-scoped short-circuit seems feasible if the caller has no “manage members” permission on any group, since the group-based path can never succeed.