Skip to content

PKCE in .NET with Clerk

PKCE is supported by both Clerk and ASP.NET Core, and in modern configurations it is either enabled by default or strongly recommended.

PKCE Support in Clerk

Clerk Supports PKCE. Clerk implements Authorization Code Flow with PKCE for:

  • SPA applications
  • Next.js apps
  • Mobile apps
  • Public clients
  • OAuth-based integrations

Clerk sits on top of OAuth 2.0 / OIDC providers and implements PKCE internally when required.

How Clerk Uses PKCE

When using Clerk in:

  • SPA
  • Next.js frontend
  • Mobile app

The client library automatically:

  1. Generates a code_verifier
  2. Creates the code_challenge
  3. Sends it to the identity provider
  4. Uses it during token exchange

You do not usually manage PKCE manually.

When Using Clerk as OIDC Provider for .NET

If your .NET backend trusts Clerk as an OIDC authority:

builder.Services.AddAuthentication("Bearer")
    .AddJwtBearer(options =>
    {
        options.Authority = "https://your-clerk-domain";
        options.Audience = "your-api";
    });

In this scenario:

  • PKCE is handled client-side
  • .NET API just validates JWT

Clerk Architecture (Simplified)

flowchart LR
    Browser --> ClerkFrontend
    ClerkFrontend --> |PKCE| ClerkAuthServer
    ClerkAuthServer --> Browser
    Browser --> API
    API --> JWT_Validation

PKCE Support in ASP.NET Core

ASP.NET Core fully supports PKCE through:

  • AddOpenIdConnect
  • Microsoft.Identity.Web
  • IdentityModel
  • Duende IdentityServer
  • Azure Entra ID integration

Server-Side Web App (.NET 8 / .NET 9 / .NET 10)

Default behaviour

.AddOpenIdConnect("oidc", options =>
{
    options.ResponseType = "code";
    options.UsePkce = true;  // Default true in modern .NET
});

In modern ASP.NET Core:

  • PKCE is enabled automatically
  • You typically don’t need to configure it manually

SPA + .NET API

If using:

  • Blazor WebAssembly
  • Angular + .NET API
  • React + .NET API

PKCE is:

  • Implemented by MSAL or other JS auth library
  • Required
  • Handled automatically

Example (Blazor WASM):

builder.Services.AddOidcAuthentication(options =>
{
    builder.Configuration.Bind("Oidc", options.ProviderOptions);
});

Blazor WASM always uses PKCE.

When PKCE Is NOT Used

Only in legacy or incorrect configurations:

  • Implicit Flow (deprecated)
  • Client Credentials (machine-to-machine)
  • Older OAuth 2.0 implementations

Modern security standards (OAuth 2.1 draft) require PKCE.

Clerk + .NET Combined Scenario

Common architecture:

flowchart LR
    SPA -->|PKCE| Clerk
    SPA -->|Access Token| ASPNETAPI
    ASPNETAPI --> DB

Here:

  • Clerk handles PKCE
  • .NET API validates tokens
  • No PKCE logic needed in API

Advantages of PKCE in These Platforms

  • Protects public clients
  • Prevents code interception
  • Required for modern OAuth
  • Transparent implementation
  • Works across web + mobile

Security Best Practices with Clerk + .NET

Even though PKCE is handled automatically you should:

  • Validate JWT signature
  • Validate iss
  • Validate aud
  • Validate exp
  • Use HTTPS only
  • Avoid storing tokens in localStorage (use HttpOnly cookies where possible)
  • Consider BFF pattern for SPAs

Summary

PKCE is fully supported by both Clerk and ASP.NET Core. Clerk implements Authorization Code Flow with PKCE automatically for public clients such as SPAs and mobile apps. ASP.NET Core enables PKCE by default when using OpenID Connect with response type code. In typical architectures, PKCE is handled client-side, while the .NET backend validates JWT access tokens. PKCE is mandatory under modern OAuth 2.1 security guidance.

Enterprise Takeaway

In 2026:

If you're using OIDC correctly, you're using PKCE — whether you know it or not.

It is no longer optional security.