* UI should prevent admins from defining a dynamic client scope with type Default
Closes#22229
Signed-off-by: Martin Bartoš <mabartos@redhat.com>
* Add Alert, and change to non-dynamic scope
Signed-off-by: Martin Bartoš <mabartos@redhat.com>
* Unify the dynamic label usage
Signed-off-by: Martin Bartoš <mabartos@redhat.com>
---------
Signed-off-by: Martin Bartoš <mabartos@redhat.com>
Adds Shared Signals Framework support to Keycloak in the **SSF Transmitter** role: Keycloak signs Security Event Tokens (SETs, RFC 8417) describing realm/user/session/credential events and delivers them to OAuth clients
registered as **SSF Receivers**, either by HTTP PUSH (RFC 8935) or HTTP POLL (RFC 8936).
Targets the OpenID Shared Signals Framework 1.0 (Final) specification plus the CAEP Interoperability Profile 1.0. Ships the legacy SSE CAEP profile alongside for Apple Business Manager / Apple School Manager interop, since Apple device-fleet enrolment is a concrete drive-use case.
Gated behind \`Profile.Feature.SSF\` experimental, opt-in.
Issue #43614 originally proposed SSF *Receiver* support (Keycloak ingesting SETs from upstream IdPs / risk engines). After exploring both sides, we're shipping the **Transmitter** first (see #48254) because it covers the strongest community asks (federate Keycloak events to downstream SaaS, Apple device fleet revoke flow) and lets us validate the SSF data-plane against real receivers before designing the harder "action mapping" question on the Receiver side. Receiver support remains on the roadmap and is tracked separately via #43614.
**In:**
- Compliance with SSF 1.0, CAEP 1.0, RISC 1.0, RFC 8935, RFC 8936, RFC 9493, RFC 8417
- SSF Transmitter support (Keycloak Realm can act as a SSF Transmitter)
- SSF Stream management (CRUD, status, verification)
- SSF Subjects management (subjects)
- SET delivery via HTTP PUSH (RFC 8935) and HTTP POLL (RFC 8936) with POLL in a return-immediately form
- SSF events temporarily stored in durable outbox with cluster-aware drainer and exponential backoff
- SSF Receivers managed as OIDC Clients with client credentials grant or auth code grant (currently only one stream per client)
- Support for SSF Stream, CAEP 1.0 and RISC 1.0 events (custom events via SPI)
- CAEP credential-change / session-revoked / (device-compliance-change) event mapping from native Keycloak events
- Support for RFC 9493 Subject Identifiers for Security Event Tokens
- Support for SSF Receiver subject event subscription with subject selection (per-user / per-orgssf.notify.<clientId>attribute, support fordefault_subjectspolicy (ALL, NONE))
- Support for Synthetic event emittance via REST endpoint for non-Keycloak-native event sources (external IAM solution)
- Per-receiver "Emit-only events" gate to suppress auto-emit per event type per receiver
- Support for legacy SSE CAEP profile for Apple Business Manager / Apple School Manager interop (verified)
- Per-realm SSF admin REST + Admin UI for SSF-enabled clients (Receiver / Stream / Subjects / Events)
- Prometheus metrics (dispatcher, drainer, poll, verification, outbox depth, delivery metrics)
**Out (tracked as separate follow-up issues):**
- SSF Receiver role for Keycloak (ingestion of SETs)
- POLL long-polling (\`returnImmediately=false\` honoured)
- Dedicated SSF signing key (separate from realm OIDC signing key)
- Chunked HELD release for very large backlogs
- Performance characterization + security review
- Formal interop matrix (caep.dev, ABM)
- [X] All code gated behind \`Profile.Feature.SSF\` (experimental, off by default)
- [X] Per-realm \`ssf.transmitterEnabled\` toggle; per-client \`ssf.enabled\` toggle
- [X] SSF event listener registered as global (not user-toggleable per realm)
- [X] Receiver-facing endpoints conformant with SSF 1.0
- [X] CAEP credential-change / session-revoked / device-compliance mapping pass interop testing against \`caep.dev\`
- [X] SSE CAEP profile narrowed shape works with Apple Business Manager
- [X] Integration test coverage for the dispatch / outbox / push / poll pipeline (100+ tests)
- [X] Prometheus metrics exposed under \`keycloak_ssf_*\`
- [X] Design notes published
Fixes#48901
This PR was partially co-authored with Claude AI
Signed-off-by: Thomas Darimont <thomas.darimont@googlemail.com>
Enable the rule (previously "off") and fix all violations across the JS
workspace. The core change makes RealmContext.realmRepresentation
non-optional — guarded by the existing KeycloakSpinner in the provider —
allowing ~30 downstream consumers to drop redundant optional chains.
Where TypeScript types declare a value as non-nullable but runtime
behaviour can still produce undefined/null (API responses, react-hook-form
dynamic values, route params present on one route but not another, array
index access, DOM queries), the existing guards are preserved with
eslint-disable-next-line comments explaining the rationale.
Additional fixes surfaced during this work:
- PermissionConfigurationDetails: fix spinner blocking the "create
permission" form by distinguishing "loading" (null) from "new" ({})
- ResourceType: restore resourceIds?.some() guard — form.getValues
returns undefined when the field has no default value
- clients.ts createOrUpdatePolicy: narrow catch to 404 NetworkError
only instead of swallowing all errors
Closes#17770
Signed-off-by: Pierluigi Lenoci <pierluigilenoci@gmail.com>
When a user drags an authentication flow step and drops it back in its original position, the onDrop handler now returns early instead of calling executeChange(). This prevents an unnecessary refresh() call and the false "Flow successfully updated" success notification.
Closes#47710
Signed-off-by: chon3806 <93464148+chon3806@users.noreply.github.com>
Added message bundles to custom themes so descriptions are now automatically rendered to user
Sanitize theme names for dynamic paths to allow multiple themes rendering at once
Closes#47762
Signed-off-by: Benjamin DeWeese <benjamin@deweese.cc>
possible values: conditional, optional, required, silent
conditional remains the default to not break the current behavior
when optional or required and the user dismissed the modal, it will stay hidden for this auth-session, can still be opened by button
adjusted all related resources, like JS files (also consolidated duplicated logic), Java classes and freemarker template
tests extended
passkey documentation extended/updated
closes#46959
Signed-off-by: Niko Köbler <niko@n-k.de>
The Authorization Resources table was incorrectly duplicating the last
element of the current page as the first element of the next page.
This occurred because the fetching logic requests 'max + 1' items to
detect if a subsequent page exists. However, the UI was rendering the
entire array instead of limiting the display to the 'max' value.
Fixed by applying a .slice(0, max) before mapping the resources to
table rows. Added a Playwright E2E regression test to ensure unique
resource distribution across pages and prevent future regressions.
Closes#46088
---------
Signed-off-by: André Rocha <andre.queiroz.rocha@tecnico.ulisboa.pt>
Signed-off-by: Alexander Schwartz <alexander.schwartz@ibm.com>
Co-authored-by: Alexander Schwartz <alexander.schwartz@ibm.com>
* refactor(admin-ui): replace use-react-router-breadcrumbs with React Router native useMatches
Replace the third-party `use-react-router-breadcrumbs` package with
React Router v6's built-in `useMatches()` hook for breadcrumb rendering.
Since the Admin UI already uses `createHashRouter` (data router API),
`useMatches()` is available and provides access to route `handle` data
at each matched route level.
Changes:
- Move `breadcrumb` property from route objects into `handle` across
all 89 route definitions, making it accessible via `useMatches()`
- Update `AppRouteObjectHandle` type to include the optional
`breadcrumb` property
- Remove `breadcrumb` from `AppRouteObject` interface (no longer a
top-level route property)
- Rewrite `PageBreadCrumbs` component to use `useMatches()` instead
of `useBreadcrumbs()` from the third-party library
- Remove `use-react-router-breadcrumbs` dependency from package.json
- Update pnpm-lock.yaml
Closes#19309
Signed-off-by: Pierluigi Lenoci <pierluigi.lenoci@gmail.com>
Signed-off-by: Alexander Schwartz <alexander.schwartz@ibm.com>
Co-authored-by: Alexander Schwartz <alexander.schwartz@ibm.com>
The console.log statement in the workflow delete test was left from debugging and should not be present in test code.
Closes#47958
Signed-off-by: chon3806 <93464148+chon3806@users.noreply.github.com>
Closes#47951
Register the Vietnamese locale across all theme types (login, account, admin, email) and add initial message bundles seeded from English sources. Vietnamese translations will follow via Weblate.
Signed-off-by: thangnm11 <thang.991992@gmail.com>
Co-authored-by: ThangNM <thangnm@hotmail.com>
Remove all explicit `: any` annotations from catch clauses in the
Admin UI. Since TypeScript's `strict` mode (with
`useUnknownInCatchVariables`) already types catch variables as
`unknown`, the explicit `: any` annotations were unnecessarily
bypassing type safety.
For catch blocks that only pass the error to `addError()` (which
accepts `unknown`), the fix is simply removing the `: any` annotation.
For two catch blocks that performed unsafe property access on the
error (`error.response?.data?.errorMessage`), the fix replaces:
- `CreateFlow.tsx`: use `addError()` instead of manual message
extraction (consistent with the rest of the codebase)
- `ClientScopesSection.tsx`: use `getErrorMessage()` from
`@keycloak/keycloak-ui-shared` for type-safe error formatting
Closes#17771
Signed-off-by: Pierluigi Lenoci <pierluigi.lenoci@gmail.com>