Skip to content

feat(clerk-js,shared): add experimental trusted device resources - #9953

Closed
mikepitre wants to merge 15 commits into
mike/expo-native-remove-legacy-syncfrom
mike/clerk-js-trusted-device-resources
Closed

mikepitre wants to merge 15 commits into
mike/expo-native-remove-legacy-syncfrom
mike/clerk-js-trusted-device-resources

Conversation

@mikepitre

Copy link
Copy Markdown
Contributor

Description

Foundational, additive resource support for trusted devices (called biometric credentials in native SDKs), so clerk-js can talk to FAPI directly for Expo biometric sign-in. Device key creation, signing, and sign-in/enrollment orchestration will come in follow-up PRs.

@clerk/shared types:

  • trusted_device strategy (TrustedDeviceStrategy) added to SignInStrategy, to SignInCreateParams (with trustedDeviceId), and to AttemptFirstFactorParams (TrustedDeviceAttempt: trustedDeviceId, clientData, signature, algorithm: 'ES256'). SignInFirstFactor/SignInSecondFactor are unchanged, since FAPI does not list trusted_device in sign-in supported factors and sign-in attempt_second_factor does not accept it.
  • TrustedDeviceChallengeJSON / TrustedDeviceChallengeResource, exposed as an optional trustedDeviceChallenge on VerificationResource.
  • NativeSettingsJSON / NativeSettingsResource, exposed as nativeSettings on AuthConfigResource.
  • BiometricCredentialJSON / BiometricCredentialResource, plus PrepareBiometricCredentialParams / AttemptBiometricCredentialParams.

@clerk/clerk-js:

  • Verification parses trusted_device_challenge (FAPI's expires_at there is in seconds) and includes it in the snapshot when present.
  • AuthConfig parses native_settings and includes it in its snapshot.
  • New BiometricCredential resource, plus User.__experimental_getBiometricCredentials(), __experimental_prepareBiometricCredential(), __experimental_attemptBiometricCredential() and __experimental_revokeBiometricCredential(id) for /v1/me/biometric_credentials. publicKeyJwk accepts a JWK object or its JSON string.
  • signIn.create / signIn.attemptFirstFactor already forward params as-is, so trusted_device requests serialize to trusted_device_id, client_data, signature, algorithm with no runtime changes.

All new surface is additive and marked @experimental. Nothing on the Clerk class changes.

Bundlewatch: clerk.native.js goes from 79.94KB to 80.63KB gzip, so its maxSize goes from 80KB to 82KB. Other entries grew by about 0.7KB and remain under their limits.

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

🤖 Generated with Claude Code

@changeset-bot

changeset-bot Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: f9b9404

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

This PR includes changesets to release 24 packages
Name Type
@clerk/clerk-js Minor
@clerk/shared Minor
@clerk/chrome-extension Patch
@clerk/electron Patch
@clerk/expo Patch
@clerk/astro Patch
@clerk/backend Patch
@clerk/expo-passkeys Patch
@clerk/express Patch
@clerk/fastify Patch
@clerk/hono Patch
@clerk/localizations Patch
@clerk/mosaic Patch
@clerk/msw Patch
@clerk/nextjs Patch
@clerk/nuxt Patch
@clerk/react-router Patch
@clerk/react Patch
@clerk/swingset Patch
@clerk/tanstack-react-start Patch
@clerk/testing Patch
@clerk/ui Patch
@clerk/vue Patch
@clerk/expo-native-components 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

@vercel

vercel Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
clerk-js-sandbox Ready Ready Preview Sep 28, 2026 8:26pm UTC
swingset Ready Ready Preview Sep 28, 2026 8:26pm UTC

Request Review

@coderabbitai

coderabbitai Bot commented Sep 27, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

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

mikepitre and others added 6 commits September 27, 2026 10:15
…kages/expo-native

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…elegate its config plugin

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… add changesets

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@clerk/expo-native now takes useAuth from @clerk/react, so the two workspace
packages no longer form a cycle. The config plugin records the installed
@clerk/expo version for the native host SDK header on both platforms via
Info.plist and gradle.properties, and fails early if the installed @clerk/expo
still bundles the native module.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…geset

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
mikepitre and others added 7 commits September 28, 2026 16:08
…/expo-native-components

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Adds an engine-agnostic behavior suite for JS <-> native client sync,
backed by a fake Frontend API, a fake native SDK, and a clerk-js
stand-in, with a thin adapter that drives today's ClerkProvider engine.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Replace the JS <-> native client sync engine with one where native storage
owns the single shared device token and each side refetches its own client
on a payload-free "client changed" signal. Codes against the new ClerkExpo
module contract (configureNative, getDeviceToken, setDeviceToken CAS,
refreshClient, clerkNativeClientInvalidated).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Session updatedAt can move on session activity and token refresh, which
would refresh the native client on every token refresh. Profile edits
still reach native through the active user's updatedAt.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Remove configure, getClientToken, syncClientStateFromJs and the
clerkNativeClientChanged event from the iOS and Android ClerkExpo module,
along with the client observation loop and JS-sync suppression state that
only served them. The JS engine now uses configureNative, getDeviceToken,
setDeviceToken, refreshClient and clerkNativeClientInvalidated.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@mikepitre

Copy link
Copy Markdown
Contributor Author

Combined into #9989, which ships biometrics on today's native client sync. The sync redesign stack (#9955 onward) now sits on top of it.

@mikepitre mikepitre closed this Sep 29, 2026

This branch was successfully deployed

2 active deployments
Preview – swingset — f9b9404c Deployed Sep 28, 2026 by vercel[bot]
Preview – clerk-js-sandbox — f9b9404c Deployed Sep 28, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant