Skip to content

Honor configured admin realm in ClientManager.isInternalClient - #50809

Merged
rmartinc merged 1 commit into
keycloak:mainfrom
gaurav0107:fix/50796-clientmanager-isinternalclient-checks-on
Aug 26, 2026
Merged

rmartinc merged 1 commit into
keycloak:mainfrom
gaurav0107:fix/50796-clientmanager-isinternalclient-checks-on

Conversation

@gaurav0107

@gaurav0107 gaurav0107 commented Jul 11, 2026 •

Copy link
Copy Markdown
Contributor

Description

ClientManager.isInternalClient(realmName, clientId) hardcoded the literal
"master" realm name when deciding whether a realm is the admin realm:

if (!"master".equals(realmName)) {
    return false;
}

On servers configured with an alternative admin realm (via
Config.getAdminRealm() / the keycloak.admin.realm option), the per-realm
internal admin-container clients (<realm>-realm, which live in the admin
realm) are therefore not recognised as internal by isInternalClient, and
can be deleted through removeClient.

This aligns the check with the admin-realm idiom used consistently across the
codebase (e.g. ApplianceBootstrap, MgmtPermissions, ModelToRepresentation,
AdminConsole), which all reference Config.getAdminRealm() rather than a
literal "master".

Fix

Use Config.getAdminRealm().equals(realmName) instead of "master".equals(realmName).

Config.getAdminRealm() returns a non-null value that defaults to "master",
so behaviour is unchanged on default installations and there is no new NPE
surface (realmName == null still yields false, as before).

Testing

  • ./mvnw spotless:check -pl services — passes.
  • ./mvnw compile -pl services -am — compiles cleanly.
  • The internal-client protection path is covered by the existing integration
    test InternalClientManagementTest (default admin realm), whose behaviour
    is unchanged. Exercising the custom-admin-realm path requires booting a
    server with a non-default keycloak.admin.realm; happy to add a dedicated
    integration test if preferred.

Closes #50796


🤖 Opened with Superhuman, an open-source contribution agent.

@gaurav0107
gaurav0107 marked this pull request as ready for review July 11, 2026 18:12
@gaurav0107
gaurav0107 requested a review from a team as a code owner July 11, 2026 18:12
Copilot AI balanced review requested due to automatic review settings July 11, 2026 18:12

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

Updates internal-client detection to honor a configured admin realm, addressing #50796.

Changes:

  • Replaces the hardcoded "master" check with Config.getAdminRealm().
  • Preserves default behavior while supporting custom admin realms.

@@ -415,7 +416,7 @@ private Map<String, Object> getClientCredentialsAdapterConfig(ClientModel client
private boolean isInternalClient(String realmName, String clientId) {
if (defaultClients.contains(clientId)) return true;

if (!"master".equals(realmName)) {
if (!Config.getAdminRealm().equals(realmName)) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch. You're right that InternalClientManagementTest runs with the default admin realm and doesn't exercise client deletion, so it wouldn't guard this path.

The fix itself is a minimal alignment with the Config.getAdminRealm() idiom already used across the codebase (e.g. ApplianceBootstrap, MgmtPermissions, ModelToRepresentation) — behaviour is unchanged on the default master realm.

A regression test here needs the server booted with a non-default admin realm (a server-level option, not a per-test realm setup) and then asserts that removeClient refuses to delete a -realm client in that realm. I'm happy to add that as a @KeycloakIntegrationTest with a custom KeycloakServerConfig; let me know if you'd prefer it in this PR or a follow-up.

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.

@gaurav0107 in this PR would be good.

@rmartinc rmartinc Aug 26, 2026 •

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.

@gaurav0107 I don't think we really need a test for this. We are using the same in a lot of places and I don't think we need a explicit test. Just checking everything is OK to me. If you really want to do the test you can file a follow-up issue and send a new PR. I rebased the PR and started the CI. If CI passes this is OK to me and we can proceed with it.

isInternalClient hardcoded the literal "master" realm name when deciding
whether a realm is the admin realm. On servers configured with an alternative
admin realm (Config.getAdminRealm()), the per-realm internal admin-container
clients (<realm>-realm) were not recognised as internal and could be deleted.
Use Config.getAdminRealm() instead, matching the admin-realm idiom used
throughout the codebase. Behaviour is unchanged on the default master realm.

Signed-off-by: Gaurav Dubey <gauravdubey0107@gmail.com>
Copilot AI review requested due to automatic review settings August 26, 2026 09:16
@rmartinc
rmartinc force-pushed the fix/50796-clientmanager-isinternalclient-checks-on branch from 1d53b97 to ddadd13 Compare August 26, 2026 09:16

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 1 out of 1 changed files in this pull request and generated no new comments.

@rmartinc rmartinc 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.

Thanks @gaurav0107! Tests passed. As commented, if you want to do the test, just file a new issue for it.

@rmartinc
rmartinc merged commit 140df27 into keycloak:main Aug 26, 2026
102 of 104 checks passed
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.

ClientManager.isInternalClient checks only for "master" realm

5 participants