Skip to content

[auth] Harden OIDC SSO (PKCE, email_verified, userinfo fallback)#1112

Merged
frankrousseau merged 2 commits into
cgwire:mainfrom
frankrousseau:oidc-sso
Jun 14, 2026
Merged

[auth] Harden OIDC SSO (PKCE, email_verified, userinfo fallback)#1112
frankrousseau merged 2 commits into
cgwire:mainfrom
frankrousseau:oidc-sso

Conversation

@frankrousseau

Copy link
Copy Markdown
Contributor

Problem

  • OIDC login advertised PKCE but only requested scopes, so the exchange ran without PKCE protection
  • Linking/provisioning trusted an absent email_verified claim, allowing account takeover via providers that permit unverified emails
  • Token-exchange failures in the callback surfaced as bare 500s
  • Names were left empty for providers (notably Azure AD) that omit them from the ID token

Solution

  • Enable PKCE (code_challenge_method=S256)
  • Add OIDC_REQUIRE_EMAIL_VERIFIED (default true): require an explicit verified claim before linking/provisioning; flag off restores the permissive behaviour
  • Catch callback token-exchange failures and return 400 instead of 500
  • Best-effort fall back to the userinfo endpoint for names when the ID token lacks them

frankrousseau and others added 2 commits June 15, 2026 00:33
- Enable PKCE (code_challenge_method=S256); the redirect previously
  advertised PKCE but the client only requested scopes
- Add OIDC_REQUIRE_EMAIL_VERIFIED (default true): require an explicit
  email_verified == true claim before linking/provisioning by email,
  closing an account-takeover vector; flag off restores the permissive
  absent-claim-trusted behaviour
- Catch token-exchange failures in the callback and return 400 instead
  of a bare 500
- Document OIDC_REQUIRE_EMAIL_VERIFIED; extend tests for both
  verification modes and the token-exchange failure path

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Some providers (notably Azure AD/Entra ID) omit given_name/family_name
from the ID token and only expose them on the userinfo endpoint. Fetch
it as a best-effort fallback when the token carried no usable name
claims. The call is skipped entirely for providers that already include
the names, and a failure only logs and proceeds so an otherwise valid
login is never blocked.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@frankrousseau frankrousseau merged commit e4488d6 into cgwire:main Jun 14, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant