Skip to content

Passkeys: hide WebAuthn and explain when a page asks for it; build 5 - #20

Merged
mattonik merged 1 commit into
mainfrom
claude/eager-cerf-epu54h
Oct 2, 2026
Merged

mattonik merged 1 commit into
mainfrom
claude/eager-cerf-epu54h

Conversation

@mattonik

@mattonik mattonik commented Oct 2, 2026

Copy link
Copy Markdown
Owner

Problem

  • Passkeys don't work in Mouselook, and people don't notice until sign-in fails.
  • Google sign-in with 2-Step Verification keeps failing with "make sure your device's Bluetooth is on".

Why: WKWebView runs WebAuthn (the browser feature behind passkeys and security keys) only for apps with Apple's com.apple.developer.web-browser entitlement, which Mouselook doesn't have, so every attempt fails. Pages still see the API, though. Because the page also sees Chrome on a Mac, Google offers a passkey or a phone nearby over Bluetooth, and that's the step that fails.

Change

  • pointerlock-polyfill.js:
    • Deletes window.PublicKeyCredential, so sign-in pages that check for WebAuthn (as Google does) should offer another method: an authenticator code, a prompt on the phone, or SMS.
    • navigator.credentials.get / create with publicKey reject at once with NotAllowedError, and once per page post {type: "webauthn"}.
    • Passkey autofill (mediation: "conditional"), which runs quietly on page load, fails without a message.
    • Other credential requests (passwords and so on) pass through untouched.
  • BrowserViewController: on webauthn, shows a toast: "Passkeys and security keys don't work in Mouselook. Choose another way to sign in, such as a code from your authenticator app or a prompt on your phone." If the request came from a sign-in popup, the toast shows over the popup, which now has its own ToastView.
  • Sign-in tips (Figma and GeForce NOW): passkeys and security keys don't work; if two-step sign-in asks for one, choose another way.
  • README: a "Passkeys and security keys" entry under Known risks, naming the browser entitlement as the only real fix.
  • project.yml: build 5.

Checked

  • npm test passes locally, with 4 new polyfill tests. They run on an https page, because WebAuthn exists only in secure contexts; on a data: URL the API is absent and a test would pass for the wrong reason.
  • With the polyfill change reverted, 3 of the 4 fail: hidden API, immediate rejection plus message, quiet autofill. The pass-through test is a regression guard.
  • Swift is not compiled here (no macOS); this PR's ios-tests job builds it.

Needs a real device

Whether Google then offers another method without the Bluetooth step can only be confirmed on an iPad. Try it in build 5: open a Google sign-in with 2-Step Verification and check which method it offers.

🤖 Generated with Claude Code

https://claude.ai/code/session_01W5tzx8GXgMz9DMzc5BF4ND


Generated by Claude Code

WKWebView runs WebAuthn only for apps with Apple's web-browser
entitlement, so passkeys and security keys always fail here. Pages still
offered them: Google's 2-Step Verification asked for a passkey or a phone
nearby and failed with "make sure Bluetooth is on".

- The polyfill deletes window.PublicKeyCredential, so sign-in pages that
  check for it offer another method.
- navigator.credentials.get/create with publicKey reject at once with
  NotAllowedError and, once per page, post {type: "webauthn"}. Passkey
  autofill (conditional mediation) fails quietly. Other credential
  requests pass through.
- The app answers with a toast saying to choose another way to sign in,
  shown over the sign-in popup when that's where the request came from.
- The GeForce NOW and Figma sign-in tips and the README say the same.
- Tests: four polyfill tests on an https page (WebAuthn needs a secure
  context). Three fail without this change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W5tzx8GXgMz9DMzc5BF4ND
@mattonik
mattonik merged commit eb56fd8 into main Oct 2, 2026
2 checks passed
@mattonik
mattonik deleted the claude/eager-cerf-epu54h branch October 2, 2026 10:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants