fix(desktop): macOS passkey create rejects ES256 under non public-key types #35969
macPasskeyBackend.create treated any pubKeyCredParams entry with alg -7 as acceptable regardless of its type, then rewrote the list to a public-key/ES256 entry and started native createCredential. The acceptance check now requires type === 'public-key' as well as alg === ES256, so a request listing ES256 only under an unsupported credential type fails with NotSupportedError before any native call. A request with no pubKeyCredParams, or an empty list, still defaults to ES256 as before (per WebAuthn). No new regex or parser.
Fixes pingdotgg/t3code#35962
Reproduction on main#
On origin/main 67d91a0390 I added an assertion to the existing 'registers ES256 keys only and reports their real authenticator data' case in apps/desktop/src/preview/Passkeys.test.ts. It sends PASSKEY_CREATE_CHANNEL through the real PreviewPasskeys layer with the macOS backend, electron-webauthn mocked, and pubKeyCredParams [{ type: 'future-credential-type', alg: -7 }]. I ran vp test run src/preview/Passkeys.test.ts in apps/desktop: it fails. The backend called createCredential and returned { success: true, data: {...} }, a public-key credential, where NotSupportedError with no native call was expected. The existing public-key/ES256 (forwarded) and public-key/EdDSA (NotSupportedError, no native call) assertions still pass. PasskeyBridge.ts forwards pubKeyCredParams unchanged (toCloneable) and does no WebIDL validation, so a page reaches this path. The native macOS module was not run: it needs a signed macOS build with Apple's browser entitlement, and this VM runs Linux.
Evidence#
Being captured: before and after in the real app. This section is filled in before the pull request can merge.
Tests#
apps/desktop: vp test run src/preview/Passkeys.test.ts failed 1/6 before the fix (the repro assertion) and passed 6/6 after it. vp run check:changed passed format, lint, knip, typecheck (2 packages) and test (1 file). The native macOS path was not run: it needs a signed macOS build with Apple's browser entitlement.
Who did the work#
- Written by Claude Opus 5.5, in Claude Code
- Reviewed by GPT-6.1 Sol, in Codex, and by Claude Opus 5.5, each on its own
- Proof captured by GPT-6.1 Sol and checked by Claude Opus 5.5
Run by the t3code factory in T3 Code.
- 1
tanstack-source added labelsbug
github-actions[bot](GitHub profile, opens in a new tab) added labelsvouch:trusted
github-actions[bot](GitHub profile, opens in a new tab) added labelssize:XS
macroscopeapp[bot](GitHub profile, opens in a new tab) approved these changes
Approvability#
Verdict: Approved at
93a5923Macroscope's review found this PR approvable — The macOS passkey backend now rejects ES256 entries that do not specify the public-key credential type before invoking native creation. Valid requests and existing defaults remain unchanged, keeping the impact narrowly bounded.
You can add or adjust custom eligibility rules. [Learn more](https://docs.macroscope.com/approvability#example-custom-eligibility-rules).The automated pipeline stopped on this pull request and will not merge it:
the fix is written and reviewed, but proving it needs something no worker has:
- Permanent blocker: A macOS machine running the packaged desktop app signed with Apple's managed browser entitlement is required. This Linux VM cannot exercise the native macOS passkey backend. The unsupported credential-type request, native sheet behavior, and before/after outcomes remain unverified.
It stays open for a person to finish or close.
Sign in to join this conversation.
No actionable comments were generated in the recent review.
Walkthrough
The macOS passkey backend now requires ES256 parameters to use the
public-keycredential type. A test verifies that an unsupported type returnsNotSupportedErrorwithout invoking native credential creation.Changes: Passkey negotiation
apps/desktop/src/preview/PasskeyBackendMac.ts,apps/desktop/src/preview/Passkeys.test.tspublic-key. A test confirms that an unsupported type returnsNotSupportedErrorand does not call native credential creation.Estimated code review effort: 2 (Simple) | ~8 minutes
Change: Bug fix · Severity of issue fixed: Low
Suggested labels:
bugfixSuggested reviewers:
maria-rcks,t3dotggMerge Risk:
Minimal · up to
93a59This change makes macOS passkey creation reject credential parameters with unsupported types instead of silently treating them as public-key. A regression test covers the new behavior. No actionable merge risk remains.
Pre-merge checks:
4
#35962requires that macOS passkey creation reject an ES256 entry whose credential type is unsupported. It also requires NotSupportedError with zero native calls for that request, with public-ke…#35962. Passkeys.test.ts adds one regression…Full details: Title check
Explanation
The title names the macOS passkey create path, the ES256 rejection under non-public-key types, and the fix type. It matches the change, which adds a type === 'public-key' condition to the ES256 acceptance check in PasskeyBackendMac.ts and adds a matching test in Passkeys.test.ts.
Full details: Description check
Explanation
The description covers the problem, the change, scope with a linked issue, and verification with focused test results. It follows the template's section order. The Evidence section is a placeholder that says evidence is still being captured, and the template does not require it for a non-UI change. The template asks for a model and harness attribution at the end, and the description includes one.
Full details: Linked Issues check
Explanation
Issue
#35962requires that macOS passkey creation reject an ES256 entry whose credential type is unsupported. It also requires NotSupportedError with zero native calls for that request, with public-key/ES256 still forwarded and public-key/EdDSA still rejected without a native call. At head 93a5923, PasskeyBackendMac.ts adds a"type" in param && param.type === "public-key"condition to the ES256 acceptance check. A request with onlyfuture-credential-type/-7 now fails beforenativeOptionsandcreateCredentialrun. The empty-list and missing-params default to ES256 is unchanged becauseparams.length === 0 ||still precedes thesomecheck. Passkeys.test.ts adds a regression assertion for the unknown-type request. It expects NotSupportedError and a single cumulative createCredential call. The existing public-key/ES256 and EdDSA assertions remain. The author reports the test passed 6/6 after the fix. I did not run the test. The native macOS path cannot be exercised on this platform, but the rejection occurs before any native call in the reviewed code. No coding requirement is unmet.Full details: Out of Scope Changes check
Explanation
The whole-PR diff against merge base 67d91a0 contains two changes. PasskeyBackendMac.ts changes only the ES256 acceptance predicate, which is the defect in
#35962. Passkeys.test.ts adds one regression case for the same unsupported-type request. Both changes map directly to the linked issue. No unrelated files or refactors appear in the diff. The PR description's Evidence section is a placeholder. That is documentation status, not a code change, and it does not affect scope.Finishing Touches
Generate unit tests (beta)
be4d72ca-93fb-4366-9cd5-67bccebab36eReviewing files that changed from the base of the PR and between 99224f098d5d4d223ab1d04f02935288fe2651cc and 93a59233a904f20be0e52f9cbe1682dcc90534b1.
apps/desktop/src/preview/PasskeyBackendMac.tsapps/desktop/src/preview/Passkeys.test.tsIncluded review availability: This review used your included allowance. 0 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 10 reviews per hour.