Skip to content

CodeExchangeError: Invalid code verifier in v0.15.0 (works in v0.14.0) #82

@faramos

Description

@faramos

🐛 TL;DR

SAML SSO authentication (Entra ID) fails in v0.15.0 with CodeExchangeError: Invalid code verifier.
Works perfectly in v0.14.0. Library appears to incorrectly apply OAuth PKCE validation to SAML flows.


Bug Description

After upgrading from @workos-inc/authkit-react@0.14.0 to @workos-inc/authkit-react@0.15.0, SAML-based authentication fails with:

CodeExchangeError: Invalid code verifier.
    at HttpClient.authenticateWithCode (@workos-inc_authkit-react.js:606:11)
    at async Client.handleCallback_fn (@workos-inc_authkit-react.js:882:40)
    at async Client.initialize (@workos-inc_authkit-react.js:752:7)
    at async createClient (@workos-inc_authkit-react.js:1037:3)

Environment

  • Package version: @workos-inc/authkit-react@0.15.0
  • Framework: Vite + React Router (TanStack Router)
  • Authentication: SAML SSO (Entra ID / Azure AD)
  • Environment: Development (localhost:3000) and Production

SSO Configuration

  • Connection Type: SAML with Entra ID (Azure AD)
  • Organization-based SSO: Yes (organizationId required)
  • Authentication Flow: Organization → SAML → WorkOS → App

Configuration

<AuthKitProvider
  clientId={workosClientId}
  redirectUri="http://localhost:3000" // Matches WorkOS Dashboard exactly
  onRedirectCallback={({ state }) => {
    if (state?.returnTo) {
      sessionStorage.setItem("returnTo", state.returnTo);
    }
  }}
>
  {/* App with organization validation */}
</AuthKitProvider>

What Works ✅

  • Authentication works perfectly in v0.14.0
  • SAML SSO with Entra ID is correctly configured in WorkOS Dashboard
  • User successfully authenticates through Entra ID
  • WorkOS receives SAML response and redirects back to app

What Fails ❌

  • SAML callback handling fails with "Invalid code verifier" in v0.15.0
  • Library appears to confuse SAML flow with OAuth PKCE flow
  • Only happens in v0.15.0, works fine in v0.14.0

Steps to Reproduce

  1. Set up SAML SSO with Entra ID (Azure AD) in WorkOS Dashboard
  2. Configure organization-based authentication
  3. Install @workos-inc/authkit-react@0.15.0
  4. Configure AuthKitProvider with organization ID
  5. Attempt to sign in through SAML SSO
  6. Complete authentication on Entra ID
  7. Observe error on SAML callback

Expected Behavior

User should be authenticated successfully after SAML callback, as it does in v0.14.0.

Actual Behavior

SAML callback fails with CodeExchangeError: Invalid code verifier because the library is incorrectly attempting PKCE validation on a SAML flow.

Technical Analysis

Why this is happening:

  1. SAML authentication does not use OAuth code exchange
  2. SAML does not have code_verifier or code_challenge - these are OAuth/OIDC PKCE concepts
  3. The error occurs in HttpClient.authenticateWithCode() which is OAuth-specific
  4. v0.15.0 appears to route SAML callbacks through OAuth code exchange logic

Evidence:

CodeExchangeError: Invalid code verifier.
    at HttpClient.authenticateWithCode  ← OAuth-specific method

The SAML callback should be handled by a SAML-specific handler, not the OAuth code exchange handler.

Impact

  • Severity: High - Blocks authentication for all SAML SSO users
  • Affected users: Anyone using SAML with Entra ID, Okta, Google Workspace, or other SAML providers
  • Scope: Both development and production environments

Root Cause Hypothesis

Version 0.15.0 likely changed how it detects/handles different authentication flows. It now incorrectly treats SAML callbacks as OAuth callbacks and tries to validate a PKCE code verifier that doesn't exist in SAML.

According to v0.15.0 release notes, the version added authenticationMethod to state. This change may have affected how SAML vs OAuth flows are distinguished.

Workaround

Current solution: Pin to v0.14.0 in package.json

Code Analysis Confirmation

After reviewing the authkit-js v0.17.0 changes (PR #99), the bug is confirmed:

  1. Change: Added authenticationMethod tracking to deserializeAuthenticationResponse
  2. Bug: The callback handler doesn't check authentication flow type before calling HttpClient.authenticateWithCode()
  3. Impact: SAML callbacks (which have authenticationMethod: "SSO") incorrectly go through OAuth code exchange
  4. Result: PKCE validation fails because SAML doesn't use code verifiers

The fix requires:
Check if callback is SAML (authenticationMethod === "SSO") and route to SAML-specific handler, not OAuth authenticateWithCode().

Sources:

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions