8000 Support wildcard subdomains in redirect URIs by aqeelat · Pull Request #47570 · keycloak/keycloak · GitHub
[go: up one dir, main page]

Skip to content
< 8000 /react-partial>

Support wildcard subdomains in redirect URIs - #47570

Open
aqeelat wants to merge 2 commits into
keycloak:mainfrom
aqeelat:codex/plan-wildcard-redirect-uri-fix
Open

aqeelat wants to merge 2 commits into
keycloak:mainfrom
aqeelat:codex/plan-wildcard-redirect-uri-fix

Conversation

@aqeelat
@aqeelat aqeelat commented Mar 30, 2026 •
Copy link
Copy Markdown

Summary

This PR implements wildcard subdomain support for Keycloak OIDC redirect URI handling by allowing a single * in the first DNS label of absolute http/https URIs.

Closes #34767.
Related discussion: #9278.

What changed

  • Added shared wildcard-host matching in RedirectUtils for absolute http/https redirect URIs.
  • Supports first-label patterns such as https://*.example.com/callback, https://*-preview.example.com/callback, and https://tenant*.example.com/callback.
  • Reused the matcher for authorization redirects, post-logout redirects, explicit web origins, and login-status iframe origin checks.
  • Added allow-wildcard-subdomain to the secure redirect URIs client policy executor and factory. This setting is off by default and controls whether client registration/update requests may include wildcard-host redirect URIs when that executor applies.
  • Rejects wildcard-host registrations when OAuth 2.1 compliance is enabled or permitted domains are configured.
  • Prevents the implicit single-redirect fallback from selecting wildcard-host entries when redirect_uri is omitted.
  • Updated the admin help text and server admin documentation.
  • Added unit and Arquillian coverage for redirect validation, logout redirects, iframe origin validation, and logout CORS.

Matching rules

  • Exactly one * is supported, and only in the first host label.
  • * matches zero or more non-dot characters and never crosses a label boundary.
  • Scheme, port, remaining host labels, and the non-wildcard portions of the URI keep the existing exact matching behavior.
  • Host wildcards can be combined with a trailing context-path wildcard only where Keycloak already allows path wildcards.
  • Invalid usages such as wildcard ports, malformed host labels, later-label wildcards, multiple host wildcards, or cross-label matches are rejected.

Why this approach

  • The relevant redirect and origin checks are hardcoded in core runtime paths, so an extension alone would not provide complete behavior for authorization, logout, iframe, and CORS validation.
  • Reusing one internal matcher keeps redirect, logout, iframe, and CORS semantics aligned instead of creating slightly different wildcard rules in multiple places.
  • The secure redirect URIs client policy executor preserves the default registration/update behavior. Realm administrators can enable allow-wildcard-subdomain only for policies where wildcard-host redirect URI registration should be allowed.

Testing

  • Ran ./mvnw -pl services -am -Dtest=RedirectUtilsTest,SecureRedirectUrisEnforcerExecutorTest -Dsurefire.failIfNoSpecifiedTests=false test
  • Ran ./mvnw -pl services -am -Dtest=SecureRedirectUrisEnforcerExecutorTest -Dsurefire.failIfNoSpecifiedTests=false test
  • Added Arquillian coverage in:
    • SecureRedirectUrisEnforcerExecutorTest
    • RPInitiatedLogoutTest
    • LoginStatusIframeEndpointTest
    • LogoutCorsTest
  • I did not complete a full local testsuite/integration-arquillian/tests/base package-phase run because it requires the large distribution and testsuite reactor; the focused tests are included in the PR for CI coverage.

AI Usage

This contribution was written with OpenAI Codex from a prompt and then reviewed, revised, and validated by the submitter before opening the PR. I understand the implementation and can follow up on review feedback directly.

@trixpan
trixpan commented Apr 15, 2026
Copy link
Copy Markdown
Contributor

@aqeelat
aqeelat commented Apr 15, 2026
Copy link
Copy Markdown
Author

not recommended by

https://datatracker.ietf.org/doc/html/rfc9700#section-4.1

I agree that it might not be best practice if production environments but is crucial for development environments, and the linked issue clearly indicate that there’s huge demand for it.

It’s also opt-in per realm which means that users will be conscious about enabling it.

I can add a popup that says this is not recommended when users try to enable it though. Or maybe we can specify in the realm config the subdomains that are allowed to be wildcarded.

@trixpan
trixpan commented Apr 15, 2026
Copy link
Copy Markdown
Contributor

not recommended by
https://datatracker.ietf.org/doc/html/rfc9700#section-4.1

I agree that it might not be best practice if production environments but is crucial for development environments, and the linked issue clearly indicate that there’s huge demand for it.

It’s also opt-in per realm which means that users will be conscious about enabling it.

I can add a popup that says this is not recommended when users try to enable it though. Or maybe we can specify in the realm config the subdomains that are allowed to be wildcarded.

There’s a separate PR on oAuth2.0 clients where even subpath wildcards are being disabled

#47320

@mike-pt
mike-pt commented May 27, 2026
Copy link
Copy Markdown
Contributor

There’s a separate PR on oAuth2.0 clients where even subpath wildcards are being disabled

#47320

I'd like to offer some counter arguments to this and why I think this PR is heading in a good direction.

First, it's being implied that PR #47320 will now disable *, but that is not what it does. It adds an opt-in oauth-2-0-compliant flag to the client policy executor. When an admin explicitly enables it, wildcards (including subpath) are rejected. It doesn't disable anything by default — without the flag, bare * as a redirect URI is still accepted today with no warning, no policy, no restriction.

So as I also commented on #34767, KC by default still allows a single * as entry, effectively allowing any host. Per my tests it also allows https://a*, which is still much worse than allowing a scoped subdomain wildcard.

From what I can see (correct me if I'm wrong) this PR aims to implement this based on a flag (ALLOW_WILDCARD_SUBDOMAIN) the admin would enable so is even better than the other PR cause the default is NOT enabled — exactly the same approach as Okta. They implement this and are still compliant. As a curiosity, Aaron Parecki (Okta) is one of the editors of OAuth 2.1 and sits on the OpenID Foundation board — surely this would be a big deal for Okta too.

I do agree that a better warning about the risk is a good idea though.

I know my opinion probably values very little I'm just a long time user but this one really affects me daily as I have several KC installation as for dynamic test URL I have to always keep a "open wildcard" for all that is a lot more worrying, so I hope you consider this PR for approval.

@aqeelat
aqeelat force-pushed the codex/plan-wildcard-redirect-uri-fix branch 4 times, most recently from 87a7e5a to 39dc7e4 Compare June 3, 2026 09:28
@aqeelat
aqeelat commented Jun 4, 2026
Copy link
Copy Markdown
Author

Added a follow-up clarification after re-reviewing the opt-in wording and matching rules.

The PR now distinguishes runtime wildcard-host matching from client-policy admission control:

  • runtime matching works when a wildcard-host URI is configured on a client
  • allow-wildcard-subdomain is off by default
  • that setting controls whether client registration/update may include wildcard-host redirect URIs when the secure redirect URI executor applies

I also tightened validation for malformed wildcard-host patterns, including wildcard ports and invalid host labels. The executor help text now says “host wildcard” because one host wildcard can still be combined with an existing trailing path wildcard where Keycloak already allows path wildcards, for example https://*.example.com/app/*.

Focused validation run:

./mvnw -pl services -am -Dtest=SecureRedirectUrisEnforcerExecutorTest -Dsurefire.failIfNoSpecifiedTests=false test

mike-pt reacted with thumbs up emoji

@aqeelat
aqeelat force-pushed the codex/plan-wildcard-redirect-uri-fix branch from 19d6095 to 6fab262 Compare June 4, 2026 17:58
@aqeelat
aqeelat commented Jun 14, 2026
Copy link
Copy Markdown
Author

Would appreciate your review.
@mposolda @rmartinc @jonkoops @stianst

@aqeelat
aqeelat force-pushed the codex/plan-wildcard-redirect-uri-fix branch from 6fab262 to 57dbe96 Compare June 28, 2026 10:32
@Robsta86
Copy link
Copy Markdown

This PR seems to fix an issue introduced by #48430 in 26.6.3.
Use case: dynamic MR preview environments with FQDNs like applicationname-<mr_id>.foo.example.com, where <mr_id> is assigned at MR creation and is unknown at client-config time. A redirect URI of https://applicationname* covered all of them until 26.6.3.

Would appreciate a review on this PR, as there's no workaround short of provisioning a client per MR.

8000

@abaars
abaars commented Jul 14, 2026
Copy link
Copy Markdown

Running into the same issue after upgrading to 26.6.3 because of #48430 . This PR would fix the issue for our use case. A review on this issue would be very much appreciated!

aqeelat and others added 2 commits July 15, 2026 10:05
Add first-label wildcard host matching for redirect URIs, post-logout
redirect URIs, and web origins. Gate wildcard-subdomain registration
with the secure redirect URIs client policy, reject implicit OAuth2
fallback selection for wildcard-host entries when redirect_uri is
omitted, and add service plus Arquillian coverage together with admin
and documentation updates.

- Validate wildcard redirect hosts to prevent malformed patterns
- Clarify wildcard redirect opt-in behavior in admin docs
- Update secure redirect URIs executor with wildcard-specific checks
- Add CORS, logout, and login-status-iframe test coverage

Closes keycloak#34767

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Abdullah Alaqeel <abdullah.t.aqeel@gmail.com>
Signed-off-by: Abdullah Alaqeel <abdullah.t.aqeel@gmail.com>
Copilot AI review requested due to automatic review settings July 15, 2026 07:42
@aqeelat
aqeelat force-pushed the codex/plan-wildcard-redirect-uri-fix branch from 57dbe96 to f938fe9 Compare July 15, 2026 07:42
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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@jimmydg
jimmydg commented Jul 28, 2026
Copy link
Copy Markdown

We're also running in the same issue and would gladly appreciate a review on this. It's blocking our upgrade right now and it's a pain to workaround this issue in the latest version.

@fgarciaSD
Copy link
Copy Markdown

Having this solution would be very helpful

@tpjnorton
Copy link
Copy Markdown

Another + 1 for this solution, would be very convenient for us.

@jsonarso
Copy link
Copy Markdown

+1, this is exactly the gap we hit.

Environment: Keycloak 26.7.0 (Keycloak Operator, k8s), realm clients managed declaratively via keycloak-config-cli.

Use case: Per-merge-request preview deployments (GitLab CI review apps), e.g. app-mr-.preview.example.com — the MR/branch id is only known at MR-creation time, so it can't be baked into the client config ahead of time.

Since #48430 closed the host-boundary bug in 26.6.3, we've had no working wildcard option — https://app-mr-*.preview.example.com/* matches exactly the "wildcard within first label" pattern this PR supports (like your tenant*.example.com), and would replace what's currently a manual, per-preview entry in redirectUris, webOrigins, and post.logout.redirect.uris. Today that means a config-repo commit + redeploy every time someone opens a new preview environment — this PR would let us set it once.

@panos-konstantellos
Copy link
Copy Markdown

+1 on this PR. We've been looking for native wildcard subdomain support for redirect_uri validation in our multi-tenant setup

The centralized approach in RedirectUtils covering logout/iframe origin checks, along with the allow-wildcard-subdomain client policy switch, makes this a safe and complete solution.

Looking forward to seeing this merged!

@christophenoel
Copy link
Copy Markdown

+1 Waiting this for 3 years (use case : platform which generates thousands of temporary webui in the context of an ESA project).

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.

Implement wildcard hostnames
0