Skip to content

feat(expo): add biometric trusted devices - #9257

Draft
seanperez29 wants to merge 4 commits into
mainfrom
sean/Trusted-device-sign-in
Draft

feat(expo): add biometric trusted devices#9257
seanperez29 wants to merge 4 commits into
mainfrom
sean/Trusted-device-sign-in

Conversation

@seanperez29

Copy link
Copy Markdown

Description

Adds biometric trusted-device support to @clerk/expo for iOS and Android.

This PR:

  • Adds useTrustedDevices() APIs for checking availability, enrolling, listing, revoking, and signing in with trusted devices.
  • Bridges the corresponding Clerk iOS and Android native SDK functionality.
  • Preserves structured native and Clerk API error codes.
  • Adds useAuthFlow() for gating authenticated content until native authentication and Clerk-owned post-authentication steps are complete.
  • Adds an optional faceIDPermission config-plugin setting for NSFaceIDUsageDescription.
  • Adds TypeScript, native bridge, config-plugin, and authentication-flow tests.
  • Documents configuration and platform requirements in the Expo package README.

Testing

Tested in an Expo development build on a physical iOS device:

  1. Registered the application identifier under the instance’s Native API settings.
  2. Configured faceIDPermission through the Expo config plugin.
  3. Enrolled a trusted device through the native AuthView.
  4. Verified availability, enrollment, listing, revocation, and trusted-device sign-in through the JavaScript APIs.
  5. Verified useAuthFlow() correctly gates authenticated content.

Automated validation:

  • pnpm --filter @clerk/expo test — 137 tests passed.
  • pnpm --filter @clerk/expo build — passed.
  • pnpm --filter @clerk/expo format:check — passed.
  • pnpm --filter @clerk/expo lint — passed with no errors.

Release coordination

This PR currently depends on unreleased Clerk iOS and Android trusted-device APIs. The temporary native dependency pins must be replaced with the officially released versions from the automated Expo bump PRs before this PR is merged.

Checklist

  • Expo package tests run as expected.
  • Expo package build runs as expected.
  • JSDoc comments have been added or updated for the new package exports.
  • The Expo package README has been updated.
  • Clerk documentation has been updated, if required.

Type of change

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

@changeset-bot

changeset-bot Bot commented Jul 27, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 714b97f

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

This PR includes changesets to release 1 package
Name Type
@clerk/expo Minor

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 Jul 27, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
clerk-js-sandbox Ready Ready Preview, Comment Jul 27, 2026 9:00pm
swingset Ready Ready Preview, Comment Jul 27, 2026 9:00pm

Request Review

@pkg-pr-new

pkg-pr-new Bot commented Jul 27, 2026

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/electron

npm i https://pkg.pr.new/@clerk/electron@9257

@clerk/electron-passkeys

npm i https://pkg.pr.new/@clerk/electron-passkeys@9257

@clerk/eslint-plugin

npm i https://pkg.pr.new/@clerk/eslint-plugin@9257

@clerk/expo

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

@clerk/expo-google-signin

npm i https://pkg.pr.new/@clerk/expo-google-signin@9257

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/hono

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/react

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

@clerk/react-router

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/ui

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

@clerk/upgrade

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

@clerk/vue

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

commit: 714b97f

@seanperez29

Copy link
Copy Markdown
Author

@coderabbitai review

@seanperez29

Copy link
Copy Markdown
Author

@macroscope-app review

@macroscopeapp

macroscopeapp Bot commented Jul 27, 2026

Copy link
Copy Markdown

Manual reviews triggered for commit 70ce7f0:

All prior checks · these links stay valid even if you push more commits.

@macroscopeapp

macroscopeapp Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review triggered. The Approvability and Correctness checks are running now — results will be posted when complete.

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The Expo package adds biometric trusted-device enrollment, listing, availability, revocation, and sign-in APIs for iOS and Android, with structured native errors and forward-compatible fields. It adds useAuthFlow and native auth-flow change events for readiness tracking, an Expo Face ID permission plugin, updated native SDK pins, public TypeScript exports, platform fallbacks, tests, documentation, and a minor-release changeset.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

Suggested reviewers: mikepitre

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 17.72% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding biometric trusted devices to the Expo package.
Description check ✅ Passed The description matches the changeset and accurately covers the new trusted-device APIs, auth flow hook, config plugin, tests, and docs.
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.

Warning

Review ran into problems

🔥 Problems

Repository analysis: Couldn't refresh clerk/javascript clone - clone failed: Clone operation failed: Stream initialization permanently failed: 14 UNAVAILABLE: read ECONNRESET


Linked repositories: Couldn't analyze clerk/clerk-android - clone failed: Clone operation failed: Cloning into '/home/jailuser/git'...
From https://github.com/clerk/clerk-android

Errors logged to '/home/jailuser/git/.git/lfs/logs/20260727T185355.998291611.log'.
Use git lfs logs last to view the log.
error: external filter 'git-lfs filter-process' failed
fatal: config/bin/detekt-cli: smudge filter lfs failed
Downloading config/bin/detekt-cli (71 MB)
Error downloading object: config/bin/detekt-cli (2655f48): Smudge error: Error downloading config/bin/detekt-cli (2655f48c7c303a5f9bf920a33229408b8571bb1d29e4e57cf7be3e151bceecb1): LFS: Client error: https://github-cloud.githubusercontent.com/alambic/media/877189286/26/55/2655f48c7c303a5f9bf920a33229408b8571bb1d29e4e57cf7be3e151bceecb1?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIA5BA2674WPWWEFGQ5%2F20260727%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260727T185516Z&X-Amz-Expires=3600&X-Amz-Signature=073c541d24b6cccb46b314ea07e1d2d7fbbce6d6647581cda559792bdeab47b4&X-Amz-SignedHeaders=host&actor_id=136622811&key_id=0&repo_id=980409545&token=1

Errors logged to '/home/jailuser/git/.git/lfs/logs/20260727T185516.506366854.log'.
Use git lfs logs last to view the log.
error: external filter 'git-lfs filter-process' failed
fatal: config/bin/detekt-cli: smudge filter lfs failed


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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
packages/expo/src/trusted-devices/index.ts (1)

1-3: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Remove this feature-module barrel.

Keep re-exports at packages/expo/src/index.ts and export the three trusted-device modules there directly; this avoids introducing an internal circular-dependency hub.

Based on learnings, only package-level entry points are exempted; as per coding guidelines, “Avoid barrel files (index.ts re-exports) as they can cause circular dependencies.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/expo/src/trusted-devices/index.ts` around lines 1 - 3, Remove the
trusted-devices feature-module barrel by deleting its index re-exports, then
update the package-level packages/expo/src/index.ts entry point to export
errors, types, and useTrustedDevices directly. Do not add or retain another
internal index.ts re-export hub.

Sources: Coding guidelines, Learnings

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/expo/android/build.gradle`:
- Around line 23-24: Update the clerkAndroidApiVersion and clerkAndroidUiVersion
pins to published Clerk Android SDK versions before merging, ensuring both
dependency coordinates resolve successfully for `@clerk/expo` consumers.

In `@packages/expo/src/native/useAuthFlow.ts`:
- Around line 71-87: Update the getAuthFlowState promise handler in useAuthFlow
so a resolved value that fails isNativeAuthFlowState is treated like a failed
native-state lookup: when still mounted and no event has been received, call
setUseJsFallback(true) instead of leaving nativeState unloaded. Preserve
setNativeState for valid payloads and retain the existing rejection handling.

---

Nitpick comments:
In `@packages/expo/src/trusted-devices/index.ts`:
- Around line 1-3: Remove the trusted-devices feature-module barrel by deleting
its index re-exports, then update the package-level packages/expo/src/index.ts
entry point to export errors, types, and useTrustedDevices directly. Do not add
or retain another internal index.ts re-export hub.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 89ef4001-80da-4149-b7ff-47d48402780a

📥 Commits

Reviewing files that changed from the base of the PR and between e35d971 and 70ce7f0.

📒 Files selected for processing (28)
  • .changeset/thin-spoons-trust.md
  • packages/expo/README.md
  • packages/expo/android/build.gradle
  • packages/expo/android/src/main/java/expo/modules/clerk/ClerkExpoModule.kt
  • packages/expo/android/src/test/java/expo/modules/clerk/TrustedDeviceBridgeTest.kt
  • packages/expo/app.plugin.js
  • packages/expo/ios/ClerkExpo.podspec
  • packages/expo/ios/ClerkExpoModule.swift
  • packages/expo/ios/ClerkNativeBridge.swift
  • packages/expo/src/__tests__/appPlugin.theme.test.js
  • packages/expo/src/index.ts
  • packages/expo/src/native/AuthView.tsx
  • packages/expo/src/native/AuthView.types.ts
  • packages/expo/src/native/__tests__/useAuthFlow.test.tsx
  • packages/expo/src/native/index.ts
  • packages/expo/src/native/useAuthFlow.ts
  • packages/expo/src/specs/NativeClerkModule.android.ts
  • packages/expo/src/specs/NativeClerkModule.ts
  • packages/expo/src/specs/NativeClerkModule.types.ts
  • packages/expo/src/trusted-devices/__tests__/useTrustedDevices.test.ts
  • packages/expo/src/trusted-devices/errors.ts
  • packages/expo/src/trusted-devices/index.ts
  • packages/expo/src/trusted-devices/types.ts
  • packages/expo/src/trusted-devices/useTrustedDevices.android.ts
  • packages/expo/src/trusted-devices/useTrustedDevices.ios.ts
  • packages/expo/src/trusted-devices/useTrustedDevices.shared.ts
  • packages/expo/src/trusted-devices/useTrustedDevices.ts
  • packages/expo/src/utils/native-module.ts
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

Comment on lines +23 to +24
clerkAndroidApiVersion = "1.0.37"
clerkAndroidUiVersion = "1.0.37"

@coderabbitai coderabbitai Bot Jul 27, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Are com.clerk:clerk-android-api:1.0.37andcom.clerk:clerk-android-ui:1.0.37 released and publicly available from the Maven repository used by Clerk Expo consumers?

💡 Result:

As of July 27, 2026, the artifacts com.clerk:clerk-android-api:1.0.37 and com.clerk:clerk-android-ui:1.0.37 are not released and publicly available in Maven Central. The official Clerk Android SDK, which is published to Maven Central under the com.clerk group, currently has a latest released version of 1.0.33, published on July 8, 2026 [1][2]. There is no record of a 1.0.37 release for these specific artifacts in the official Maven repository used by Clerk consumers [3][4][1]. Clerk recommends checking their official GitHub releases page [1] or Maven Central directly to confirm the availability of specific versions [5][6].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== build.gradle snippet ==\n'
sed -n '1,80p' packages/expo/android/build.gradle

printf '\n== search for 1.0.37 references ==\n'
rg -n '1\.0\.37|clerk-android-(api|ui)' packages/expo -S || true

printf '\n== repository declarations ==\n'
rg -n 'mavenCentral|google\(\)|maven \{' packages/expo/android -S || true

Repository: clerk/javascript

Length of output: 1908


🏁 Script executed (no clone):

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
import json, urllib.request, urllib.error

urls = {
    "maven_api_1_0_37": "https://repo1.maven.org/maven2/com/clerk/clerk-android-api/1.0.37/",
    "maven_ui_1_0_37": "https://repo1.maven.org/maven2/com/clerk/clerk-android-ui/1.0.37/",
}
for name, url in urls.items():
    try:
        with urllib.request.urlopen(url, timeout=20) as r:
            print(name, r.status, r.geturl())
            print(r.read(200).decode("utf-8", "ignore"))
    except Exception as e:
        print(name, "ERROR", repr(e))
PY

Length of output: 327


Replace the Android SDK pins before merging. com.clerk:clerk-android-api:1.0.37 and com.clerk:clerk-android-ui:1.0.37 aren’t published yet, so @clerk/expo will fail to resolve Android dependencies for consumers.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/expo/android/build.gradle` around lines 23 - 24, Update the
clerkAndroidApiVersion and clerkAndroidUiVersion pins to published Clerk Android
SDK versions before merging, ensuring both dependency coordinates resolve
successfully for `@clerk/expo` consumers.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Agreed. This PR is intentionally a draft and is blocked on the native SDK releases. These are temporary placeholder pins for the upcoming Android trusted-device release, so the Android CI failures are currently expected. Once Clerk Android is published, its release workflow will automatically open an Expo dependency-bump PR. I’ll rebase that change and use the published version before marking this PR ready or merging it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@seanperez29, thanks for clarifying. That release-gating plan addresses the concern: keeping the placeholder pins is reasonable while this remains a draft, provided they are replaced by the published dependency-bump before the PR is marked ready or merged. I’ll leave the finding open until then.


✏️ Learnings added
Learnt from: seanperez29
Repo: clerk/javascript PR: 9257
File: packages/expo/android/build.gradle:23-24
Timestamp: 2026-07-27T19:04:52.833Z
Learning: For GitHub pull request `#9257` in `clerk/javascript`, `packages/expo/android/build.gradle` intentionally uses temporary unreleased Clerk Android SDK pins for trusted-device support while the PR remains a draft. Android CI failures are expected until Clerk Android publishes the release; its release workflow will open an Expo dependency-bump PR, which must be rebased and applied before this PR is marked ready or merged.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

Comment thread packages/expo/src/native/useAuthFlow.ts

clerk_ios_repo = 'https://github.com/clerk/clerk-ios.git'
clerk_ios_version = '1.3.4'
clerk_ios_requirement = { :kind => 'revision', :revision => '1026c9d6fb8183b6eb2a0f67bed25d2a5a3ce2cd' }

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Will correct this once iOS is released

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.

2 participants