You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This commit was created on GitHub.com and signed with GitHub’s verified signature.
feat(mapper): email-domain-guard — update-path email domain guard (#14)
* feat(mapper): email-domain-guard update-path email guard
Adds email-domain-guard-idp-mapper, a broker-time guard that stops an
already-linked identity provider from rewriting an account's email onto a
domain it is not authoritative for.
Companion to idp-asserted-domain-matches (#13): that condition guards the
first-broker-login create/link path; this mapper guards the *update* path,
which no authentication flow runs on. A returning brokered login (existing
(idp, brokerUserId) link) skips first-broker-login entirely — Keycloak calls
updateBrokeredUser and, under FORCE sync, rewrites email + re-derives
emailVerified from the provider's trustEmail, with no flow to intercept.
preprocessFederatedIdentity runs in IdentityBrokerService.authenticated
before that write. When a federated link already exists (update path only)
and the provider has domains configured, an out-of-domain asserted email is
nulled — Keycloak's updateEmail early-returns on a null email, so the account
keeps its existing verified address. First broker login and domain-less
providers pass through untouched (the auth flow owns the former; the latter
has no basis to judge domain membership).
Runs on all providers (reads the normalized context email + provider domain
list, neither protocol-specific). Suppression decision extracted to a pure
shouldSuppressEmail() and unit-tested; domain matching reuses EmailDomainMatcher.
Bumps version to 1.14.0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* perf(mapper): gate update-path link lookup behind the domain check
preprocessFederatedIdentity runs on every brokered login. Move the cheap
in-memory domain parse + match ahead of the getUserByFederatedIdentity DB
lookup, and skip the lookup entirely for the common in-domain (or no-domains)
case — only an out-of-domain email on a domains-configured provider can ever
be suppressed. No behavior change; shouldSuppressEmail stays the authoritative
decision.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(mapper): use Keycloak's "Preprocessor" display category
The mapper adjusts the brokered context via preprocessFederatedIdentity
before the user is written; it does not import an attribute. "Preprocessor"
is Keycloak's built-in category for exactly this kind of mapper (its own
Username Template mapper uses it), so the guard groups correctly in the admin
UI's mapper-type dropdown instead of appearing under "Attribute Importer".
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Jared Gibson <jared@gibson.run>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>