Skip to content

chore(fastify): Use runtime keys for auth client and add enableHandshake option#8560

Draft
jescalan wants to merge 12 commits into
mainfrom
fix/fastify-runtime-secret-handshake
Draft

chore(fastify): Use runtime keys for auth client and add enableHandshake option#8560
jescalan wants to merge 12 commits into
mainfrom
fix/fastify-runtime-secret-handshake

Conversation

@jescalan
Copy link
Copy Markdown
Contributor

@jescalan jescalan commented May 15, 2026

Summary

  • create server-side auth clients from resolved runtime middleware options before calling authenticateRequest
  • cover Fastify, Express, Astro, Nuxt, React Router, and TanStack Start so nonce handshake payload exchange can use keys passed directly to framework middleware
  • add focused regression coverage for runtime key propagation into client construction

Context

Forced handshake nonce transport stores a short __clerk_handshake_nonce instead of the large __clerk_handshake payload. Server SDKs then need to exchange that nonce through the Backend API client attached to authenticateRequest.

Several framework wrappers passed runtime secretKey/publishableKey into authenticateRequest, but constructed the request client from environment defaults or earlier unresolved options. That means apps loading keys asynchronously and passing them into middleware could authenticate some paths with the runtime key while nonce payload exchange still used a client created without that key.

Hono and Next.js already build the client from runtime options, so no patch was needed there.

Performance

This patch avoids adding a new per-request client construction path in the common static-key cases:

  • Fastify creates the Clerk client once when clerkPlugin() registers middleware.
  • Express creates the default client once when clerkMiddleware() is created for static options. The callback form can still create a middleware/client per request, but that was already how callback options worked.
  • Astro, Nuxt, React Router, and TanStack Start already created the server Clerk client inside the request path before this PR. This patch passes the resolved options into that existing construction instead of introducing another client creation.
  • createClerkClient() itself does not perform network I/O; it builds the Backend API resource client, authenticateRequest closure, and telemetry collector. The nonce exchange network call only happens when authenticateRequest reaches forced handshake nonce handling.

Testing

  • pnpm -C packages/fastify exec vitest run src/__tests__/withClerkMiddleware.test.ts
  • pnpm -C packages/express exec vitest run src/__tests__/clerkMiddleware.test.ts -t "builds a per-middleware ClerkClient with runtime keys"
  • pnpm -C packages/react-router exec vitest run src/server/__tests__/clerkMiddleware.test.ts
  • pnpm -C packages/nuxt exec vitest run src/runtime/server/__tests__/clerkClient.test.ts
  • pnpm -C packages/astro exec vitest run src/server/__tests__/clerk-client.test.ts
  • pnpm -C packages/tanstack-react-start exec vitest run src/server/__tests__/clerkClient.test.ts
  • pnpm -C packages/fastify build
  • pnpm -C packages/express build
  • pnpm -C packages/fastify lint (passes with existing no-misused-promises warnings)
  • pnpm -C packages/express lint (passes with existing no-misused-promises warnings)
  • pnpm -C packages/astro lint (passes with existing warnings)
  • git diff --check

Notes

  • Full Express middleware tests currently hit the local backend/shared export mismatch: getAutoProxyUrlFromEnvironment is not a function.
  • React Router, Nuxt, Astro, and TanStack builds/lints still hit existing local package-linkage/DTS issues unrelated to this patch (missing local @clerk/react/@clerk/vue exports or declarations). Their JS builds reached the compile stage before those existing declaration/linkage failures.

@vercel
Copy link
Copy Markdown

vercel Bot commented May 15, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
clerk-js-sandbox Building Building Preview, Comment May 16, 2026 0:02am

Request Review

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 15, 2026

🦋 Changeset detected

Latest commit: 6fa13fb

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@clerk/fastify Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@jescalan jescalan changed the title [codex] fix(fastify): use runtime keys for auth client fix(fastify): use runtime keys for auth client May 15, 2026
@jescalan jescalan marked this pull request as ready for review May 15, 2026 15:44
@jescalan jescalan requested a review from jeremy-clerk May 15, 2026 15:44
@jescalan
Copy link
Copy Markdown
Contributor Author

!snapshot

Copy link
Copy Markdown
Contributor

@jeremy-clerk jeremy-clerk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 15, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

The PR threads runtime/loaded ClerkOptions through client factories and middleware: clerkClient functions now accept an optional options parameter and forward it to createClerkClient; middleware across Fastify, Nuxt, Astro, Express, React Router, and TanStack pass resolved/loaded options into clerkClient before calling authenticateRequest; Express resolveDefaultClerkClient now constructs per-middleware clients when specific overrides (apiUrl, apiVersion, secretKey, machineSecretKey, publishableKey, jwtKey) are present. Tests added/updated verify createClerkClient receives runtime keys. Changeset documents the patch.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ⚠️ Warning The title mentions using runtime keys for auth client, which aligns with the Fastify changes, but it also mentions 'add enableHandshake option' which is not supported by the changeset content. Update the title to accurately reflect the changes: consider 'fix(fastify): Use runtime keys for auth client in middleware' or similar, removing reference to 'enableHandshake option' which is not present in the actual changes.
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The pull request description provides a clear, detailed explanation of the changes, context, performance implications, and testing approach that directly relates to the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

This comment has been minimized.

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 15, 2026

Open in StackBlitz

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@8560

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@8560

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@8560

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@8560

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@8560

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@8560

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@8560

@clerk/express

npm i https://pkg.pr.new/@clerk/express@8560

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@8560

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@8560

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@8560

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@8560

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@8560

@clerk/react

npm i https://pkg.pr.new/@clerk/react@8560

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@8560

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@8560

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@8560

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@8560

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@8560

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@8560

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@8560

commit: 71d3ff7

@jescalan jescalan force-pushed the fix/fastify-runtime-secret-handshake branch from 71d3ff7 to 25efe99 Compare May 15, 2026 15:58
@jescalan jescalan changed the title fix(fastify): use runtime keys for auth client [codex] fix framework runtime keys for nonce handshakes May 15, 2026
@jescalan jescalan marked this pull request as draft May 15, 2026 15:59
@wobsoriano
Copy link
Copy Markdown
Member

@copilot can you add changes from #8563 to this PR?

Copy link
Copy Markdown
Contributor

Copilot AI commented May 15, 2026

@copilot can you add changes from #8563 to this PR?

Done — I pulled in the changes from #8563 in commits 19f3473, 0cc1e3c, and 60312d1, and added a follow-up fix for the React Router CI type error in 9243a0a.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • download.cypress.io
    • Triggering command: /usr/local/bin/node node index.js --exec install (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI requested a review from wobsoriano May 15, 2026 21:24
@wobsoriano
Copy link
Copy Markdown
Member

!snapshot

@wobsoriano
Copy link
Copy Markdown
Member

!snapshot

@wobsoriano
Copy link
Copy Markdown
Member

!snapshot

@github-actions
Copy link
Copy Markdown
Contributor

Hey @wobsoriano - the snapshot version command generated the following package versions:

Package Version
@clerk/astro 3.2.4-snapshot.v20260515233846
@clerk/backend 3.4.9-snapshot.v20260515233846
@clerk/chrome-extension 3.1.26-snapshot.v20260515233846
@clerk/clerk-js 6.11.1-snapshot.v20260515233846
@clerk/dev-cli 0.1.1-snapshot.v20260515233846
@clerk/expo 3.2.12-snapshot.v20260515233846
@clerk/expo-passkeys 1.0.25-snapshot.v20260515233846
@clerk/express 2.1.17-snapshot.v20260515233846
@clerk/fastify 3.1.27-snapshot.v20260515233846
@clerk/hono 0.1.27-snapshot.v20260515233846
@clerk/localizations 4.6.4-snapshot.v20260515233846
@clerk/msw 0.0.25-snapshot.v20260515233846
@clerk/nextjs 7.3.5-snapshot.v20260515233846
@clerk/nuxt 2.4.4-snapshot.v20260515233846
@clerk/react 6.6.4-snapshot.v20260515233846
@clerk/react-router 3.2.5-snapshot.v20260515233846
@clerk/shared 4.12.0-snapshot.v20260515233846
@clerk/tanstack-react-start 1.2.5-snapshot.v20260515233846
@clerk/testing 2.0.29-snapshot.v20260515233846
@clerk/ui 1.11.0-snapshot.v20260515233846
@clerk/upgrade 2.0.3-snapshot.v20260515233846
@clerk/vue 2.2.4-snapshot.v20260515233846

Tip: Use the snippet copy button below to quickly install the required packages.
@clerk/astro

npm i @clerk/astro@3.2.4-snapshot.v20260515233846 --save-exact

@clerk/backend

npm i @clerk/backend@3.4.9-snapshot.v20260515233846 --save-exact

@clerk/chrome-extension

npm i @clerk/chrome-extension@3.1.26-snapshot.v20260515233846 --save-exact

@clerk/clerk-js

npm i @clerk/clerk-js@6.11.1-snapshot.v20260515233846 --save-exact

@clerk/dev-cli

npm i @clerk/dev-cli@0.1.1-snapshot.v20260515233846 --save-exact

@clerk/expo

npm i @clerk/expo@3.2.12-snapshot.v20260515233846 --save-exact

@clerk/expo-passkeys

npm i @clerk/expo-passkeys@1.0.25-snapshot.v20260515233846 --save-exact

@clerk/express

npm i @clerk/express@2.1.17-snapshot.v20260515233846 --save-exact

@clerk/fastify

npm i @clerk/fastify@3.1.27-snapshot.v20260515233846 --save-exact

@clerk/hono

npm i @clerk/hono@0.1.27-snapshot.v20260515233846 --save-exact

@clerk/localizations

npm i @clerk/localizations@4.6.4-snapshot.v20260515233846 --save-exact

@clerk/msw

npm i @clerk/msw@0.0.25-snapshot.v20260515233846 --save-exact

@clerk/nextjs

npm i @clerk/nextjs@7.3.5-snapshot.v20260515233846 --save-exact

@clerk/nuxt

npm i @clerk/nuxt@2.4.4-snapshot.v20260515233846 --save-exact

@clerk/react

npm i @clerk/react@6.6.4-snapshot.v20260515233846 --save-exact

@clerk/react-router

npm i @clerk/react-router@3.2.5-snapshot.v20260515233846 --save-exact

@clerk/shared

npm i @clerk/shared@4.12.0-snapshot.v20260515233846 --save-exact

@clerk/tanstack-react-start

npm i @clerk/tanstack-react-start@1.2.5-snapshot.v20260515233846 --save-exact

@clerk/testing

npm i @clerk/testing@2.0.29-snapshot.v20260515233846 --save-exact

@clerk/ui

npm i @clerk/ui@1.11.0-snapshot.v20260515233846 --save-exact

@clerk/upgrade

npm i @clerk/upgrade@2.0.3-snapshot.v20260515233846 --save-exact

@clerk/vue

npm i @clerk/vue@2.2.4-snapshot.v20260515233846 --save-exact

@wobsoriano wobsoriano changed the title [codex] fix framework runtime keys for nonce handshakes chore(fastify): Use runtime keys for auth client and add enableHandshake option May 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants