Skip to content

Configurable may_act claim enforcement#50980

Draft
mabartos wants to merge 1 commit into
keycloak:mainfrom
mabartos:KC-50979
Draft

Configurable may_act claim enforcement#50980
mabartos wants to merge 1 commit into
keycloak:mainfrom
mabartos:KC-50979

Conversation

@mabartos

@mabartos mabartos commented Jul 17, 2026

Copy link
Copy Markdown
Member
  • Closes Configurable may_act claim enforcement #50979
  • Replaces hardcoded sub/iss validation in validateMayAct() with a generic enforcement loop that compares any configured claim 1:1 between may_act and the actor token
  • Enforced claims are controlled by a HardcodedClaim mapper (may_act enforce_claims) on the delegation client scope - admins configure enforcement by simply editing the mapper's JSON value (e.g. ["sub","iss","preferred_username"]), no server restart or realm config needed
  • Reuses the existing mapper infrastructure rather than introducing server-side configuration, keeping it lightweight
  • Falls back to default ["sub","iss"] enforcement when the mapper is removed or the list is empty
  • Strips enforce_claims from the resulting act claim to prevent leaking into the delegation chain

@rmartinc @keycloak/core-authn Could you please check it? Thanks!

@mabartos mabartos self-assigned this Jul 17, 2026
@mabartos
mabartos marked this pull request as ready for review July 20, 2026 09:05
@mabartos
mabartos requested a review from a team as a code owner July 20, 2026 09:05
Copilot AI review requested due to automatic review settings July 20, 2026 09:05

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

Adds configurable may_act claim enforcement for token exchange delegation.

Changes:

  • Adds mapper-driven claim matching with default sub/iss enforcement.
  • Removes enforcement metadata from generated act claims.
  • Adds documentation and delegation tests.

Reviewed changes

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

File Description
TokenExchangeDelegationTest.java Tests configurable enforcement and fallback behavior.
TokenExchangeDelegationProvider.java Implements generic claim enforcement.
OIDCLoginProtocolFactory.java Adds the default enforcement mapper.
token-exchange.adoc Documents enforced-claim configuration.

@mabartos
mabartos marked this pull request as draft July 20, 2026 09:10
@mabartos
mabartos marked this pull request as ready for review July 20, 2026 09:22
Copilot AI review requested due to automatic review settings July 20, 2026 09:22

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 4 comments.

Comment thread docs/guides/securing-apps/token-exchange.adoc Outdated
@mabartos
mabartos marked this pull request as draft July 20, 2026 10:05

@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.forms.MultipleTabsLoginTest#testEmptyBaseUrl

Keycloak CI - Forms IT (firefox)

org.opentest4j.AssertionFailedError: expected: <true> but was: <false>
	at org.junit.jupiter.api.AssertionFailureBuilder.build(AssertionFailureBuilder.java:151)
	at org.junit.jupiter.api.AssertionFailureBuilder.buildAndThrow(AssertionFailureBuilder.java:132)
	at org.junit.jupiter.api.AssertTrue.failNotTrue(AssertTrue.java:63)
	at org.junit.jupiter.api.AssertTrue.assertTrue(AssertTrue.java:36)
...
org.opentest4j.AssertionFailedError: expected: <true> but was: <false>
	at org.junit.jupiter.api.AssertionFailureBuilder.build(AssertionFailureBuilder.java:151)
	at org.junit.jupiter.api.AssertionFailureBuilder.buildAndThrow(AssertionFailureBuilder.java:132)
	at org.junit.jupiter.api.AssertTrue.failNotTrue(AssertTrue.java:63)
	at org.junit.jupiter.api.AssertTrue.assertTrue(AssertTrue.java:36)
...

Report flaky test

org.keycloak.testsuite.forms.MultipleTabsLoginTest#multipleTabsParallelLoginTest

Keycloak CI - Forms IT (firefox)

org.opentest4j.AssertionFailedError: expected: <true> but was: <false>
	at org.junit.jupiter.api.AssertionFailureBuilder.build(AssertionFailureBuilder.java:151)
	at org.junit.jupiter.api.AssertionFailureBuilder.buildAndThrow(AssertionFailureBuilder.java:132)
	at org.junit.jupiter.api.AssertTrue.failNotTrue(AssertTrue.java:63)
	at org.junit.jupiter.api.AssertTrue.assertTrue(AssertTrue.java:36)
...
org.opentest4j.AssertionFailedError: expected: <true> but was: <false>
	at org.junit.jupiter.api.AssertionFailureBuilder.build(AssertionFailureBuilder.java:151)
	at org.junit.jupiter.api.AssertionFailureBuilder.buildAndThrow(AssertionFailureBuilder.java:132)
	at org.junit.jupiter.api.AssertTrue.failNotTrue(AssertTrue.java:63)
	at org.junit.jupiter.api.AssertTrue.assertTrue(AssertTrue.java:36)
...

Report flaky test

org.keycloak.testsuite.forms.BrowserFlowTest#testUserWithOneAdditionalFactorOtpSuccess

Keycloak CI - Base IT (5)

org.opentest4j.AssertionFailedError: expected: <true> but was: <false>
	at org.junit.jupiter.api.AssertionFailureBuilder.build(AssertionFailureBuilder.java:151)
	at org.junit.jupiter.api.AssertionFailureBuilder.buildAndThrow(AssertionFailureBuilder.java:132)
	at org.junit.jupiter.api.AssertTrue.failNotTrue(AssertTrue.java:63)
	at org.junit.jupiter.api.AssertTrue.assertTrue(AssertTrue.java:36)
...

Report flaky test

Closes keycloak#50979

Signed-off-by: Martin Bartoš <mabartos@redhat.com>
@mabartos
mabartos marked this pull request as ready for review July 20, 2026 10:27
Copilot AI review requested due to automatic review settings July 20, 2026 10:27

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.

Comments suppressed due to low confidence (1)

services/src/main/java/org/keycloak/protocol/oidc/tokenexchange/TokenExchangeDelegationProvider.java:177

  • A present null value is treated as absent, so may_act: {"sub": null} passes the mandatory-key check and then skips the default actor binding entirely. Skip only claims whose key is absent, and reject a present null value as a mismatch.
            if (mayActValue == null) {
                continue;

@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.forms.BrowserFlowTest#testUserWithOneAdditionalFactorOtpSuccess

Keycloak CI - Base IT (5)

org.opentest4j.AssertionFailedError: expected: <true> but was: <false>
	at org.junit.jupiter.api.AssertionFailureBuilder.build(AssertionFailureBuilder.java:151)
	at org.junit.jupiter.api.AssertionFailureBuilder.buildAndThrow(AssertionFailureBuilder.java:132)
	at org.junit.jupiter.api.AssertTrue.failNotTrue(AssertTrue.java:63)
	at org.junit.jupiter.api.AssertTrue.assertTrue(AssertTrue.java:36)
...

Report flaky test

@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

@mabartos
mabartos marked this pull request as draft July 21, 2026 08:19
@mabartos mabartos added the status/hold PR should not be merged. On hold for later. label Jul 21, 2026
@mabartos

Copy link
Copy Markdown
Member Author

Put on hold for now based on the offline discussion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

flaky-test status/hold PR should not be merged. On hold for later.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Configurable may_act claim enforcement

2 participants