From 93ea192f8c23a061571eeb833ebbd4b79ab09bfa Mon Sep 17 00:00:00 2001 From: David Leek Date: Thu, 20 Nov 2025 10:59:48 +0100 Subject: [PATCH] feat: frontend for pkce (#11005) --- .../admin/auth/OidcAuth/OidcAuth.tsx | 40 +++++++++++++++++++ frontend/src/interfaces/uiConfig.ts | 1 + .../models/oidcSettingsResponseSchema.ts | 2 + .../openapi/models/oidcSettingsSchemaOneOf.ts | 2 + .../models/oidcSettingsSchemaOneOfFour.ts | 2 + src/lib/types/experimental.ts | 7 +++- 6 files changed, 53 insertions(+), 1 deletion(-) diff --git a/frontend/src/component/admin/auth/OidcAuth/OidcAuth.tsx b/frontend/src/component/admin/auth/OidcAuth/OidcAuth.tsx index bd042f6843..9418d8b518 100644 --- a/frontend/src/component/admin/auth/OidcAuth/OidcAuth.tsx +++ b/frontend/src/component/admin/auth/OidcAuth/OidcAuth.tsx @@ -36,6 +36,7 @@ const initialState = { secret: '', acrValues: '', idTokenSigningAlgorithm: 'RS256', + enablePkce: false, }; type State = typeof initialState & { @@ -47,6 +48,7 @@ export const OidcAuth = () => { const { setToastData, setToastApiError } = useToast(); const { uiConfig } = useUiConfig(); const { oidcConfiguredThroughEnv } = uiConfig; + const oidcPkceSupport = Boolean(uiConfig.flags?.oidcPkceSupport); const [data, setData] = useState(initialState); const { config } = useAuthSettings('oidc'); const { updateSettings, errors, loading } = useAuthSettingsApi('oidc'); @@ -253,6 +255,44 @@ export const OidcAuth = () => { /> + + + Enable PKCE +

+ Require Proof Key for Code Exchange (PKCE) + to add an extra layer of security for the + authorization code flow. +

+
+ + + setValue( + 'enablePkce', + event.target.checked, + ) + } + name='enablePkce' + checked={Boolean(data.enablePkce)} + disabled={ + !data.enabled || + oidcConfiguredThroughEnv + } + /> + } + label={ + data.enablePkce ? 'Enabled' : 'Disabled' + } + /> + + + } + /> ACR Values diff --git a/frontend/src/interfaces/uiConfig.ts b/frontend/src/interfaces/uiConfig.ts index 5d06c5073b..f63be56a6b 100644 --- a/frontend/src/interfaces/uiConfig.ts +++ b/frontend/src/interfaces/uiConfig.ts @@ -90,6 +90,7 @@ export type UiFlags = { milestoneProgression?: boolean; featureReleasePlans?: boolean; safeguards?: boolean; + oidcPkceSupport?: boolean; extendedUsageMetrics?: boolean; }; diff --git a/frontend/src/openapi/models/oidcSettingsResponseSchema.ts b/frontend/src/openapi/models/oidcSettingsResponseSchema.ts index 24eb5e41d3..9f187f579c 100644 --- a/frontend/src/openapi/models/oidcSettingsResponseSchema.ts +++ b/frontend/src/openapi/models/oidcSettingsResponseSchema.ts @@ -34,6 +34,8 @@ export interface OidcSettingsResponseSchema { enableGroupSyncing?: boolean; /** Support Single sign out when user clicks logout in Unleash. If `true` user is signed out of all OpenID Connect sessions against the clientId they may have active */ enableSingleSignOut?: boolean; + /** Enable Proof Key for Code Exchange (PKCE) when performing the OIDC authorization code flow. */ + enablePkce?: boolean; /** Specifies the path in the OIDC token response to read which groups the user belongs to from. */ groupJsonPath?: string; /** The signing algorithm used to sign our token. Refer to the [JWT signatures](https://jwt.io/introduction) documentation for more information. */ diff --git a/frontend/src/openapi/models/oidcSettingsSchemaOneOf.ts b/frontend/src/openapi/models/oidcSettingsSchemaOneOf.ts index 56248819f7..012952c7ff 100644 --- a/frontend/src/openapi/models/oidcSettingsSchemaOneOf.ts +++ b/frontend/src/openapi/models/oidcSettingsSchemaOneOf.ts @@ -31,6 +31,8 @@ export type OidcSettingsSchemaOneOf = { enableGroupSyncing?: boolean; /** Support Single sign out when user clicks logout in Unleash. If `true` user is signed out of all OpenID Connect sessions against the clientId they may have active */ enableSingleSignOut?: boolean; + /** Enable Proof Key for Code Exchange (PKCE) when performing the OIDC authorization code flow. */ + enablePkce?: boolean; /** Specifies the path in the OIDC token response to read which groups the user belongs to from. */ groupJsonPath?: string; /** The signing algorithm used to sign our token. Refer to the [JWT signatures](https://jwt.io/introduction) documentation for more information. */ diff --git a/frontend/src/openapi/models/oidcSettingsSchemaOneOfFour.ts b/frontend/src/openapi/models/oidcSettingsSchemaOneOfFour.ts index 402f1cf002..7f47464bbc 100644 --- a/frontend/src/openapi/models/oidcSettingsSchemaOneOfFour.ts +++ b/frontend/src/openapi/models/oidcSettingsSchemaOneOfFour.ts @@ -31,6 +31,8 @@ export type OidcSettingsSchemaOneOfFour = { enableGroupSyncing?: boolean; /** Support Single sign out when user clicks logout in Unleash. If `true` user is signed out of all OpenID Connect sessions against the clientId they may have active */ enableSingleSignOut?: boolean; + /** Enable Proof Key for Code Exchange (PKCE) when performing the OIDC authorization code flow. */ + enablePkce?: boolean; /** Specifies the path in the OIDC token response to read which groups the user belongs to from. */ groupJsonPath?: string; /** The signing algorithm used to sign our token. Refer to the [JWT signatures](https://jwt.io/introduction) documentation for more information. */ diff --git a/src/lib/types/experimental.ts b/src/lib/types/experimental.ts index 820546d46b..ea6e998839 100644 --- a/src/lib/types/experimental.ts +++ b/src/lib/types/experimental.ts @@ -64,7 +64,8 @@ export type IFlagKey = | 'milestoneProgression' | 'featureReleasePlans' | 'plausibleMetrics' - | 'safeguards'; + | 'safeguards' + | 'oidcPkceSupport'; export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>; @@ -285,6 +286,10 @@ const flags: IFlags = { process.env.UNLEASH_EXPERIMENTAL_SAFEGUARDS, false, ), + oidcPkceSupport: parseEnvVarBoolean( + process.env.UNLEASH_EXPERIMENTAL_OIDC_PKCE_SUPPORT, + false, + ), }; export const defaultExperimentalOptions: IExperimentalOptions = {