Skip to content

Fix SCIM unfiltered search returning non-imported federated users - #51683

Merged
pedroigor merged 2 commits into
keycloak:mainfrom
sguilhen:51343-scim-federated-users
Aug 17, 2026
Merged

pedroigor merged 2 commits into
keycloak:mainfrom
sguilhen:51343-scim-federated-users

Conversation

@sguilhen

Copy link
Copy Markdown
Contributor

Closes #51343

Copilot AI balanced review requested due to automatic review settings August 12, 2026 15:33
@sguilhen
sguilhen requested a review from a team as a code owner August 12, 2026 15:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Aligns SCIM /Users list semantics to exclude non-imported federated users (e.g., LDAP/custom providers with import disabled), fixing inconsistent results between filtered vs. unfiltered searches and documenting the expected behavior.

Changes:

  • Update SCIM user listing/counting to query local storage only for unfiltered searches.
  • Add an integration test covering filtered vs. unfiltered search consistency with non-imported federated users.
  • Document SCIM /Users behavior and add test dependency needed for the custom federation provider.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

File Description
scim/model/src/main/java/org/keycloak/scim/model/user/UserResourceTypeProvider.java Ensures unfiltered SCIM user search/count uses local storage, excluding non-imported federated users.
scim/tests/base/src/test/java/org/keycloak/tests/scim/tck/FederatedUserTest.java Adds regression test verifying consistent filtered/unfiltered results and exclusion of non-imported federated users.
scim/tests/base/pom.xml Adds test-scoped dependency required by the new integration test.
docs/documentation/server_admin/topics/scim/managing-users.adoc Documents that SCIM /Users returns only locally stored users and excludes non-imported federated users.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Copilot AI review requested due to automatic review settings August 12, 2026 16:24
@sguilhen
sguilhen force-pushed the 51343-scim-federated-users branch from a7ac047 to 0e6d75c Compare August 12, 2026 16:24

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

Suppressed comments (3)

scim/tests/base/src/test/java/org/keycloak/tests/scim/tck/FederatedUserTest.java:62

  • This comment is no longer true after the change: the unfiltered request now uses local storage and does not include federated-provider results. Update it to describe the expected fixed path.
            // unfiltered SCIM search - goes through UserStorageManager, includes federated providers

scim/tests/base/src/test/java/org/keycloak/tests/scim/tck/FederatedUserTest.java:84

  • not(hasItems(a, b)) passes when either one of the two users is present; it only rejects a list containing both. Assert each forbidden username separately so a partial leak cannot satisfy this regression test.
            assertThat(unfilteredUserNames, not(hasItems("fed-charlie", "fed-diana")));
            assertThat(filteredUserNames, not(hasItems("fed-charlie", "fed-diana")));

scim/tests/base/src/test/java/org/keycloak/tests/scim/tck/FederatedUserTest.java:46

  • This describes the pre-fix implementation as the current behavior, but the production change now routes unfiltered searches to local storage. Phrase it as historical regression context so the test documentation remains accurate.

This issue also appears on line 62 of the same file.

     * Currently, unfiltered searches go through UserStorageManager (which queries
     * federated providers), while filtered searches use direct JPA queries against
     * the local UserEntity table - so non-imported federated users only appear in
     * unfiltered results.

Copilot AI review requested due to automatic review settings August 12, 2026 17:41
@sguilhen
sguilhen force-pushed the 51343-scim-federated-users branch from 0e6d75c to 0709242 Compare August 12, 2026 17:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

Suppressed comments (3)

scim/model/src/main/java/org/keycloak/scim/model/user/UserResourceTypeProvider.java:41

  • This introduces a dependency on UserStoragePrivateUtil (a private/internal utility). That makes SCIM more sensitive to internal refactors in user storage. If there is an existing supported accessor for local user storage in this layer, prefer that; otherwise consider encapsulating the local-only lookup behind a small SCIM-local helper (or extending the SCIM/user SPI to express ‘local-only’ intent) so the private util isn’t referenced directly throughout resource type providers.
import org.keycloak.storage.UserStoragePrivateUtil;

scim/model/src/main/java/org/keycloak/scim/model/user/UserResourceTypeProvider.java:155

  • This introduces a dependency on UserStoragePrivateUtil (a private/internal utility). That makes SCIM more sensitive to internal refactors in user storage. If there is an existing supported accessor for local user storage in this layer, prefer that; otherwise consider encapsulating the local-only lookup behind a small SCIM-local helper (or extending the SCIM/user SPI to express ‘local-only’ intent) so the private util isn’t referenced directly throughout resource type providers.
            return UserStoragePrivateUtil.userLocalStorage(session).searchForUserStream(realm, Map.of(UserModel.INCLUDE_SERVICE_ACCOUNT, "false"), firstResult, maxResults);

scim/model/src/main/java/org/keycloak/scim/model/user/UserResourceTypeProvider.java:174

  • This introduces a dependency on UserStoragePrivateUtil (a private/internal utility). That makes SCIM more sensitive to internal refactors in user storage. If there is an existing supported accessor for local user storage in this layer, prefer that; otherwise consider encapsulating the local-only lookup behind a small SCIM-local helper (or extending the SCIM/user SPI to express ‘local-only’ intent) so the private util isn’t referenced directly throughout resource type providers.
            return (long) UserStoragePrivateUtil.userLocalStorage(session).getUsersCount(realm, false);

@pedroigor pedroigor left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we also want to cover GET by ID?

Copilot AI review requested due to automatic review settings August 13, 2026 13:01
@sguilhen
sguilhen force-pushed the 51343-scim-federated-users branch from 0709242 to f625976 Compare August 13, 2026 13:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

@sguilhen

Copy link
Copy Markdown
Contributor Author

I guess we also want to cover GET by ID?

Yes, I've updated the commit.

@keycloak-github-bot keycloak-github-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unreported flaky test detected, please review

@keycloak-github-bot

Copy link
Copy Markdown

Unreported flaky test detected

If the flaky tests below are affected by the changes, please review and update the changes accordingly. Otherwise, a maintainer should report the flaky tests prior to merging the PR.

org.keycloak.testsuite.federation.ldap.LDAPUserLoginTest#loginLDAPUserAuthenticationSimpleEncryptionStartTLS

Keycloak CI - Java Distribution IT (windows-latest - temurin - 17)

org.openqa.selenium.TimeoutException: 
java.net.SocketTimeoutException: Read timed out
Build info: version: '4.28.1', revision: '73f5ad48a2'
System info: os.name: 'Windows Server 2025', os.arch: 'amd64', os.version: '10.0', java.version: '17.0.20'
Driver info: driver.version: HtmlUnitDriver
...

Report flaky test

pedroigor
pedroigor previously approved these changes Aug 14, 2026
Copilot AI review requested due to automatic review settings August 14, 2026 14:31
@sguilhen
sguilhen force-pushed the 51343-scim-federated-users branch from f625976 to 0555571 Compare August 14, 2026 14:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

Suppressed comments (1)

scim/model/src/main/java/org/keycloak/scim/model/user/UserResourceTypeProvider.java:104

  • Returning the local adapter directly bypasses UserStorageManager validation for imported federated users. For example, a user linked to a removed provider remains readable and updatable here instead of being rejected, and a disabled provider's read-only delegate is skipped; first prove that a local row exists, then resolve it through session.users() to preserve federation validation without exposing non-imported users.
        UserModel model = UserStoragePrivateUtil.userLocalStorage(session).getUserById(realm, id);

@keycloak-github-bot keycloak-github-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unreported flaky test detected, please review

@keycloak-github-bot

Copy link
Copy Markdown

Unreported flaky test detected

If the flaky tests below are affected by the changes, please review and update the changes accordingly. Otherwise, a maintainer should report the flaky tests prior to merging the PR.

org.keycloak.testsuite.federation.ldap.LDAPUserLoginTest#loginLDAPUserAuthenticationSimpleEncryptionStartTLS

Keycloak CI - Java Distribution IT (windows-latest - temurin - 17)

org.openqa.selenium.TimeoutException: 
java.net.SocketTimeoutException: Read timed out
Build info: version: '4.28.1', revision: '73f5ad48a2'
System info: os.name: 'Windows Server 2025', os.arch: 'amd64', os.version: '10.0', java.version: '17.0.20'
Driver info: driver.version: HtmlUnitDriver
...

Report flaky test

@pedroigor
pedroigor enabled auto-merge (rebase) August 17, 2026 18:39
Closes keycloak#51343

Signed-off-by: Stefan Guilhen <sguilhen@redhat.com>
Signed-off-by: Stefan Guilhen <sguilhen@redhat.com>
Copilot AI review requested due to automatic review settings August 17, 2026 18:40
@pedroigor
pedroigor force-pushed the 51343-scim-federated-users branch from 0555571 to 1eacd4d Compare August 17, 2026 18:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

Suppressed comments (1)

scim/model/src/main/java/org/keycloak/scim/model/user/UserResourceTypeProvider.java:104

  • Looking up the raw local adapter bypasses UserStorageManager.validateUser, so imported users no longer receive their federation proxy/read-only delegate; SCIM PUT/PATCH can consequently update the local row even when the provider is read-only, and GET can return stale provider data. Reject provider-owned IDs first, then use session.users() for local IDs so imported users retain normal federation validation and decoration.
        UserModel model = UserStoragePrivateUtil.userLocalStorage(session).getUserById(realm, id);

@keycloak-github-bot keycloak-github-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unreported flaky test detected, please review

@keycloak-github-bot

Copy link
Copy Markdown

Unreported flaky test detected

If the flaky tests below are affected by the changes, please review and update the changes accordingly. Otherwise, a maintainer should report the flaky tests prior to merging the PR.

org.keycloak.testsuite.webauthn.registration.WebAuthnOtherSettingsTest#timeout

Keycloak CI - WebAuthn IT

org.openqa.selenium.WebDriverException: 
unknown error: unhandled inspector error: {"code":-32000,"message":"Node with given id does not belong to the document"}
  (Session info: chrome=151.0.7922.108)
Build info: version: '4.28.1', revision: '73f5ad48a2'
System info: os.name: 'Linux', os.arch: 'amd64', os.version: '6.17.0-1022-azure', java.version: '25.0.4'
...

Report flaky test

@sguilhen
sguilhen deleted the 51343-scim-federated-users branch September 21, 2026 19:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Ensure SCIM endpoints do not return non-imported federated users

4 participants