Research: WebAuthn PRF support across browsers, OSes, hybrid/QR and passkey providers #153

Open
opened 2026-10-10 10:40:18 +00:00 by kayg · 3 comments
Owner

In production (2026-10-10), the owner's CA unlock with a passkey failed silently on Windows Chrome using the QR / phone route (hybrid transport) with 1Password on iOS. The assertion returned, but no PRF output came back, so the account key couldn't be unwrapped and bootstrap/finish was never sent.

Owner: "what is PRF and why doesn't windows do PRF via QR code for ios/android sign in?" — assign to research.

Question: across every combination (browser × OS × transport × passkey provider), when does WebAuthn PRF (hmac-secret) work, and what should infraternal do when it doesn't?

In production (2026-10-10), the owner's CA unlock with a passkey failed silently on Windows Chrome using the QR / phone route (hybrid transport) with 1Password on iOS. The assertion returned, but no PRF output came back, so the account key couldn't be unwrapped and `bootstrap/finish` was never sent. Owner: "what is PRF and why doesn't windows do PRF via QR code for ios/android sign in?" — assign to research. Question: across every combination (browser × OS × transport × passkey provider), when does WebAuthn PRF (hmac-secret) work, and what should infraternal do when it doesn't?
Author
Owner

Starting research on branch research-prf, based on dev at b9b61d07bb990ebf820cd36a71977442bab4e6c9. Issue #153 has 0 comments and no parent issue linked. The brief's apps/tracer/src/canvas/addhost/authority.on-demand.ts path is absent in this checkout; reviewing current apps/tracer/src/auth.ts instead.

Starting research on branch `research-prf`, based on `dev` at `b9b61d07bb990ebf820cd36a71977442bab4e6c9`. Issue #153 has 0 comments and no parent issue linked. The brief's `apps/tracer/src/canvas/addhost/authority.on-demand.ts` path is absent in this checkout; reviewing current `apps/tracer/src/auth.ts` instead.
Author
Owner

Finding: current Chromium source shows Windows Chrome uses the native Windows WebAuthn API for hybrid when the runtime API reports version 7+, and passes PRF get inputs through the API; API versions below 4 are explicitly treated as not evaluating hmac-secret. Windows registration-time PRF output is a separate API v8+ path and is feature-gated. Microsoft documents WebAuthn APIs from Windows 10 1903, but the reviewed Microsoft sources do not map API versions to exact Windows builds. This points the reported missing output downstream of Chrome's WebAuthn input construction, but does not distinguish webauthn.dll hybrid handling from the iOS provider response. 1Password's iOS release 8.10.74 (2025-04-29) added PRF for iOS 18, but no public source confirms that exact Windows-hybrid + iOS-provider route. The owner also reported authority.on-demand.ts is absent in this checkout; auth.ts is present and validates PRF-enabled create plus 32-byte get output.

Finding: current Chromium source shows Windows Chrome uses the native Windows WebAuthn API for hybrid when the runtime API reports version 7+, and passes PRF get inputs through the API; API versions below 4 are explicitly treated as not evaluating hmac-secret. Windows registration-time PRF output is a separate API v8+ path and is feature-gated. Microsoft documents WebAuthn APIs from Windows 10 1903, but the reviewed Microsoft sources do not map API versions to exact Windows builds. This points the reported missing output downstream of Chrome's WebAuthn input construction, but does not distinguish webauthn.dll hybrid handling from the iOS provider response. 1Password's iOS release 8.10.74 (2025-04-29) added PRF for iOS 18, but no public source confirms that exact Windows-hybrid + iOS-provider route. The owner also reported `authority.on-demand.ts` is absent in this checkout; `auth.ts` is present and validates PRF-enabled create plus 32-byte get output.
Author
Owner

Completed and pushed the research report: research/webauthn-prf/REPORT.md.

It explains PRF/hmac-secret, provides three transport matrices with 24 browser/OS rows each and E/R/G create/get state, bounds the Windows Chrome + hybrid + 1Password iOS diagnosis to the Windows WebAuthn/hybrid or iOS provider response boundary, and recommends another passkey, D152 device approval, or D25 delayed recovery while preserving D151/D168/D217. The exact provider/transport failure point remains unproven in public sources. authority.on-demand.ts was absent from this checkout. This is a docs-only commit; binary delta is 0.

Head: 61482a0c5db7a3ec7845b1feea543976930c0aa2 (branch research-prf, pushed).

scripts/verify fast output (verbatim relevant final output):

PT_INTERP: absent; size: 16692464 bytes (baseline 16142672 + allowance 262144 = max 16404816)
binary exceeds the 16404816-byte size budget: 16692464 bytes

+---------------------------+--------------+
| Rust gate                 | Result       |
+---------------------------+--------------+
| fmt                       | PASS         |
| VT native fmt             | PASS         |
| CLI plugin compile-out    | PASS         |
| clippy                    | PASS         |
| test                      | FAIL (101)   |
| cargo-deny                | PASS         |
| static builds             | FAIL (1)     |
+---------------------------+--------------+

The full parallel suite’s sole failure was server_setup_terminal_echo_and_resume_preserve_offsets_once; an isolated rerun passed 1/1 in 0.74 s. The static size failure is on the unchanged code tree. The Rust failure stopped scripts/verify fast before its TypeScript phase.

Completed and pushed the research report: `research/webauthn-prf/REPORT.md`. It explains PRF/hmac-secret, provides three transport matrices with 24 browser/OS rows each and E/R/G create/get state, bounds the Windows Chrome + hybrid + 1Password iOS diagnosis to the Windows WebAuthn/hybrid or iOS provider response boundary, and recommends another passkey, D152 device approval, or D25 delayed recovery while preserving D151/D168/D217. The exact provider/transport failure point remains unproven in public sources. `authority.on-demand.ts` was absent from this checkout. This is a docs-only commit; binary delta is 0. Head: `61482a0c5db7a3ec7845b1feea543976930c0aa2` (branch `research-prf`, pushed). `scripts/verify fast` output (verbatim relevant final output): ```text PT_INTERP: absent; size: 16692464 bytes (baseline 16142672 + allowance 262144 = max 16404816) binary exceeds the 16404816-byte size budget: 16692464 bytes +---------------------------+--------------+ | Rust gate | Result | +---------------------------+--------------+ | fmt | PASS | | VT native fmt | PASS | | CLI plugin compile-out | PASS | | clippy | PASS | | test | FAIL (101) | | cargo-deny | PASS | | static builds | FAIL (1) | +---------------------------+--------------+ ``` The full parallel suite’s sole failure was `server_setup_terminal_echo_and_resume_preserve_offsets_once`; an isolated rerun passed 1/1 in 0.74 s. The static size failure is on the unchanged code tree. The Rust failure stopped `scripts/verify fast` before its TypeScript phase.
Sign in to join this conversation.
No labels
launch-qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/infraternal#153
No description provided.