feat(CORE-27): allow opt-in public clients#2598
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR introduces an opt-in security hardening flag that allows non-device-flow Keycloak SSO clients configured as publicClient: true, while keeping stricter defaults and adding validation, tests, chart plumbing, and documentation.
Changes:
- Add
SECURITY_HARDENING_PUBLIC_CLIENTS_ENABLED(default"false") to KeycloakrealmInitEnv, propagate it into the realm env Secret, and validate its schema. - Update the UDS Operator Package admission validator to (1) always reject inherently-incompatible public client options and (2) gate non-device-flow public clients behind the new flag.
- Add unit/integration tests, helm-unittest coverage, docs updates, and an ADR describing the decision.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| test/vitest/keycloak-public-clients.spec.ts | Adds an integration test asserting standard-flow public clients are denied by default. |
| src/pepr/operator/index.ts | Watches keycloak-realm-env Secret updates to refresh the in-memory public-clients flag. |
| src/pepr/operator/crd/validators/package-validator.ts | Splits public-client validation into always-enforced guards plus a flag-gated non-device-flow check. |
| src/pepr/operator/crd/validators/package-validator.spec.ts | Adds unit test coverage for always-enforced and flag-gated public-client behaviors. |
| src/pepr/operator/controllers/config/types.ts | Extends operator config shape with securityHardeningPublicClientsEnabled. |
| src/pepr/operator/controllers/config/config.ts | Loads the flag from keycloak-realm-env at startup and updates it on Secret changes. |
| src/keycloak/chart/values.yaml | Introduces realmInitEnv.SECURITY_HARDENING_PUBLIC_CLIENTS_ENABLED default. |
| src/keycloak/chart/values.schema.json | Adds schema validation for the new realmInitEnv value. |
| src/keycloak/chart/tests/kc_public_clients_test.yaml | Adds helm-unittest assertions for Secret propagation of the new realm env key. |
| docs/reference/configuration/identity-and-authorization.md | Documents the new flag and the risks/constraints of public clients. |
| docs/how-to-guides/identity-and-authorization/register-and-customize-sso-clients.mdx | Mentions the new flag in the context of client customization guidance. |
| docs/how-to-guides/identity-and-authorization/configure-user-account-settings.mdx | Adds an optional procedure step and verification notes for enabling public clients. |
| docs/how-to-guides/identity-and-authorization/configure-device-flow.mdx | Updates device-flow guidance to reflect the new default/opt-in behavior. |
| adrs/0010-allow-opt-in-public-clients.md | Records the rationale and decision for a default-off opt-in flag. |
slaskawi
added a commit
to defenseunicorns/uds-identity-config
that referenced
this pull request
Apr 20, 2026
Adds an `allow-public-clients` toggle on the UDS Client Policy executor, wired through `SECURITY_HARDENING_PUBLIC_CLIENTS_ENABLED` in realm.json5. When the toggle is true, the executor permits `publicClient: true` only if the client enforces PKCE with the S256 challenge method. When false (the default), all public clients are rejected. Companion to defenseunicorns/uds-core#2598.
slaskawi
commented
Apr 21, 2026
slaskawi
commented
Apr 21, 2026
slaskawi
commented
Apr 21, 2026
slaskawi
commented
Apr 21, 2026
slaskawi
commented
Apr 21, 2026
slaskawi
commented
Apr 21, 2026
slaskawi
commented
Apr 21, 2026
slaskawi
commented
Apr 21, 2026
slaskawi
commented
Apr 21, 2026
8ca75b1 to
20ebeaa
Compare
bburky
reviewed
Apr 21, 2026
mjnagel
reviewed
Apr 22, 2026
fa9d4c2 to
d99420e
Compare
7e45ba1 to
72e2138
Compare
UDS bundle overrides coerce YAML scalars to their native type, so a bundle passing ALLOW_PUBLIC_CLIENTS: "true" (string) arrives at the operator-config chart as a boolean and fails the string-only schema. Widen the schema to accept either form; Helm's quote filter in secret.yaml stringifies both to the same Secret value, so the operator's === "true" check still works.
slaskawi
commented
Apr 23, 2026
mjnagel
reviewed
Apr 23, 2026
Contributor
mjnagel
left a comment
There was a problem hiding this comment.
LGTM pending two open threads.
mjnagel
approved these changes
Apr 24, 2026
jasonwashburn
pushed a commit
that referenced
this pull request
Apr 28, 2026
🤖 I have created a release *beep* *boop* --- ## [1.3.0](v1.2.0...v1.3.0) (2026-04-28) ### Features * **CORE-27:** allow opt-in public clients ([#2598](#2598)) ([9af5ca7](9af5ca7)) * cycle gateways when istio gatewayTopology proxyProtocol changes ([#2595](#2595)) ([5eceba7](5eceba7)) ### Bug Fixes * **ci:** run istio gen-crds in autogenerated-check ([#2605](#2605)) ([40a1a97](40a1a97)) * handle apply properly for keycloak client secret ([#2627](#2627)) ([c227289](c227289)) * re-add keycloak client registration authpol ([#2614](#2614)) ([ebed871](ebed871)) * restore original loki write service account name ([#2599](#2599)) ([a5386e2](a5386e2)) * updating prometheus to use endpointslice ([#2594](#2594)) ([ba319c8](ba319c8)) ### Miscellaneous * add retry to multi-arch manifest check ([#2602](#2602)) ([4e8ba23](4e8ba23)) * **deps-dev:** bump postcss from 8.5.8 to 8.5.12 in /scripts/renovate ([#2615](#2615)) ([0922090](0922090)) * **deps:** update identity-config to 0.26.1 ([#2616](#2616)) ([fd105a2](fd105a2)) * **deps:** update istio to v1.29.2 ([#2587](#2587)) ([caddf35](caddf35)) * **deps:** update pepr to v1.1.6 ([#2607](#2607)) ([d9f2ae9](d9f2ae9)) * **deps:** update pepr to v1.1.7 ([#2611](#2611)) ([fd43cc3](fd43cc3)) * **deps:** update prometheus-stack ([#2546](#2546)) ([6812697](6812697)) * **deps:** update velero chart to v12.0.1 ([#2613](#2613)) ([1048ae9](1048ae9)) * swap bundles google idp saml signing cert ([#2609](#2609)) ([57795b9](57795b9)) * update istio CRDs to use v1 API ([#2606](#2606)) ([079c361](079c361)) ### Documentation * add 1.3.0 release notes ([#2633](#2633)) ([00468ab](00468ab)) * add keycloak admin handling doc ([#2597](#2597)) ([328d19c](328d19c)) * add troubleshooting for too many open files ([#2612](#2612)) ([0b64a05](0b64a05)) * update release notes for 1.2.1 ([#2603](#2603)) ([bfa8124](bfa8124)) * update release notes to include newest patches ([#2629](#2629)) ([d59ca81](d59ca81)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This Pull Request adds a new ADR as well as the implementation for Public Keycloak Clients.
Related Issue
Relates to https://linear.app/defense-unicorns/issue/CORE-27/consider-allowing-public-clients
Type of change
Steps to Validate
Tested automatically:
Checklist before merging