Edit history

Earlier versions of SSO Config Validation can result in incorrect Issuer URL, newest first.

Current version | Edited by Rex
Changes
You can see in `"payload"` that the SSO provider returns `"iss":"https://example.com"`, which will not match the `https://example.com/` in the config.Removed: ### ChecksRemoved: Removed: - ☑ I searched existing issues.Removed: - ☑ I wrote this report in my own words, except for direct translation if needed.Removed:
Show

SSO Config Validation can result in incorrect Issuer URL

Summary

Clicking "Save SSO Settings" when "Enable SSO" is checked can cause the "Issuer" field to get changed (in particular, URLs without a trailing slash will have one added). I assume this happens somewhere in the config validation/normalization, but I haven't looked much further. Since jose checks for an exact issuer match, this can cause SSO to fail with "Invalid SSO token." (user-facing) and JWTClaimValidationFailed/ERR_JWT_CLAIM_VALIDATION_FAILED/"Failed to verify SSO id_token" (in the logs, see below).

Steps to reproduce

  1. Go to https://chat.example.com/admin/instance-config
  2. Check "Enable SSO" and set the "Issuer" to https://example.com
  3. Click "Save SSO Settings" and refresh the page
  4. The "Issuer" is now set to https://example.com/, which will cause SSO to fail if the identity provider returns the URL without a trailing slash as the iss value

Environment

Latest docker image (v1)

Logs or screenshots

Short video demonstrating the config value changing (I am refreshing the page after saves): 608915653-5b06efed-c4a6-47d7-b944-def36e16b849.mp4 When properly setting up SSO and attempting to complete the auth flow, the logged error will look like the following:
{"level":"error","time":"2026-06-17T00:39:05.931Z","service":"fluxer-api","env":"production","logger":"SsoService","error":{"type":"JWTClaimValidationFailed","message":"unexpected \"iss\" claim value","stack":"JWTClaimValidationFailed: unexpected \"iss\" claim value\n    at validateClaimsSet (file:///usr/src/app/fluxer_api/node_modules/.pnpm/jose@6.1.3/node_modules/jose/dist/webapi/lib/jwt_claims_set.js:114:15)\n    at jwtVerify (file:///usr/src/app/fluxer_api/node_modules/.pnpm/jose@6.1.3/node_modules/jose/dist/webapi/jwt/verify.js:9:21)\n    at async SsoService.verifyIdToken (/usr/src/app/fluxer_api/src/api/auth/services/SsoService.ts:611:23)\n    at async SsoService.resolveClaims (/usr/src/app/fluxer_api/src/api/auth/services/SsoService.ts:553:14)\n    at async SsoService.completeLogin (/usr/src/app/fluxer_api/src/api/auth/services/SsoService.ts:319:18)\n    at async AuthRequestService.toSsoCompleteResponse (/usr/src/app/fluxer_api/src/api/auth/AuthRequestService.ts:383:18)\n    at async Object.handler (/usr/src/app/fluxer_api/src/api/auth/AuthController.ts:104:19)\n    at async dispatch (file:///usr/src/app/fluxer_api/node_modules/.pnpm/hono@4.12.2/node_modules/hono/dist/compose.js:22:17)\n    at async handler (file:///usr/src/app/fluxer_api/node_modules/.pnpm/hono@4.12.2/node_modules/hono/dist/hono-base.js:118:39)\n    at async dispatch (file:///usr/src/app/fluxer_api/node_modules/.pnpm/hono@4.12.2/node_modules/hono/dist/compose.js:22:17)","code":"ERR_JWT_CLAIM_VALIDATION_FAILED","name":"JWTClaimValidationFailed","claim":"iss","reason":"check_failed","payload":{"iss":"https://example.com","aud":["1516580774764351578"],"iat":1781656745,"exp":1781660345,"auth_time":1781656739,"at_hash":"CD3h8zmT_AAtZkEGHFq_LQ","sub":"82824507223445504"}},"msg":"Failed to verify SSO id_token"}
You can see in "payload" that the SSO provider returns "iss":"https://example.com", which will not match the https://example.com/ in the config.
Original by Rex
Show

SSO Config Validation can result in incorrect Issuer URL

Summary

Clicking "Save SSO Settings" when "Enable SSO" is checked can cause the "Issuer" field to get changed (in particular, URLs without a trailing slash will have one added). I assume this happens somewhere in the config validation/normalization, but I haven't looked much further. Since jose checks for an exact issuer match, this can cause SSO to fail with "Invalid SSO token." (user-facing) and JWTClaimValidationFailed/ERR_JWT_CLAIM_VALIDATION_FAILED/"Failed to verify SSO id_token" (in the logs, see below).

Steps to reproduce

  1. Go to https://chat.example.com/admin/instance-config
  2. Check "Enable SSO" and set the "Issuer" to https://example.com
  3. Click "Save SSO Settings" and refresh the page
  4. The "Issuer" is now set to https://example.com/, which will cause SSO to fail if the identity provider returns the URL without a trailing slash as the iss value

Environment

Latest docker image (v1)

Logs or screenshots

Short video demonstrating the config value changing (I am refreshing the page after saves): 608915653-5b06efed-c4a6-47d7-b944-def36e16b849.mp4 When properly setting up SSO and attempting to complete the auth flow, the logged error will look like the following:
{"level":"error","time":"2026-06-17T00:39:05.931Z","service":"fluxer-api","env":"production","logger":"SsoService","error":{"type":"JWTClaimValidationFailed","message":"unexpected \"iss\" claim value","stack":"JWTClaimValidationFailed: unexpected \"iss\" claim value\n    at validateClaimsSet (file:///usr/src/app/fluxer_api/node_modules/.pnpm/jose@6.1.3/node_modules/jose/dist/webapi/lib/jwt_claims_set.js:114:15)\n    at jwtVerify (file:///usr/src/app/fluxer_api/node_modules/.pnpm/jose@6.1.3/node_modules/jose/dist/webapi/jwt/verify.js:9:21)\n    at async SsoService.verifyIdToken (/usr/src/app/fluxer_api/src/api/auth/services/SsoService.ts:611:23)\n    at async SsoService.resolveClaims (/usr/src/app/fluxer_api/src/api/auth/services/SsoService.ts:553:14)\n    at async SsoService.completeLogin (/usr/src/app/fluxer_api/src/api/auth/services/SsoService.ts:319:18)\n    at async AuthRequestService.toSsoCompleteResponse (/usr/src/app/fluxer_api/src/api/auth/AuthRequestService.ts:383:18)\n    at async Object.handler (/usr/src/app/fluxer_api/src/api/auth/AuthController.ts:104:19)\n    at async dispatch (file:///usr/src/app/fluxer_api/node_modules/.pnpm/hono@4.12.2/node_modules/hono/dist/compose.js:22:17)\n    at async handler (file:///usr/src/app/fluxer_api/node_modules/.pnpm/hono@4.12.2/node_modules/hono/dist/hono-base.js:118:39)\n    at async dispatch (file:///usr/src/app/fluxer_api/node_modules/.pnpm/hono@4.12.2/node_modules/hono/dist/compose.js:22:17)","code":"ERR_JWT_CLAIM_VALIDATION_FAILED","name":"JWTClaimValidationFailed","claim":"iss","reason":"check_failed","payload":{"iss":"https://example.com","aud":["1516580774764351578"],"iat":1781656745,"exp":1781660345,"auth_time":1781656739,"at_hash":"CD3h8zmT_AAtZkEGHFq_LQ","sub":"82824507223445504"}},"msg":"Failed to verify SSO id_token"}
You can see in "payload" that the SSO provider returns "iss":"https://example.com", which will not match the https://example.com/ in the config.

Checks

  • ☑ I searched existing issues.
  • ☑ I wrote this report in my own words, except for direct translation if needed.