Skip to content

feat(passkeys): correct and expand passkey sign-in Glean telemetry#20731

Draft
vpomerleau wants to merge 4 commits into
mainfrom
FXA-13896-passkey-glean-events
Draft

feat(passkeys): correct and expand passkey sign-in Glean telemetry#20731
vpomerleau wants to merge 4 commits into
mainfrom
FXA-13896-passkey-glean-events

Conversation

@vpomerleau

Copy link
Copy Markdown
Contributor

Because

  • Passkey sign-in events shared reason codes across the email-first, OTP, login, and alternative-auth flows, so the flows could not be told apart in analysis (the FXA-13896 ask).
  • Click-through on the "Sign in with passkey" button could not be measured — only page-level view events existed.
  • The shared set-password funnel and the server side lacked passkey-surface / ceremony-start / assertion-verification signals, leaving funnel drop-off invisible.

This pull request

  • Maps each sign-in surface to a distinct metric reason (otplogin, signin, alternative_auth) and renames the surface type to PasskeyMetricsSurface, merging the two mappers into toPasskeyMetricsSurface (packages/fxa-settings/src/lib/passkeys/signin-flow.ts, packages/fxa-shared/metrics/glean/fxa-ui-metrics.yaml).
  • Adds a per-surface passkey.button_view impression event, fired from usePasskeySignIn only when the button is rendered, so click-through is measurable.
  • Tags the shared post_verify_set_password.* events with the originating surface (<surface>_passkey) via SetPassword's container, keeping the page flow-agnostic.
  • Adds backend passkey.authentication_started and passkey.authentication_verification_success events (packages/fxa-auth-server/lib/routes/passkeys.ts), giving a started → verified → complete server funnel alongside login.complete.

Issue that this pull request solves

Closes: FXA-13896

Checklist

Put an x in the boxes that apply

  • My commit is GPG signed.
  • If applicable, I have modified or added tests which pass locally.
  • I have added necessary documentation (if appropriate).
  • I have verified that my changes render correctly in RTL (if appropriate).
  • I have manually reviewed all AI generated code.

How to review (Optional)

  • Key files/areas to focus on: signin-flow.ts (surface mapping + impression), passkeys.ts (backend events), and the two glean/*.yaml schemas.
  • Suggested review order: commit-by-commit — the 4 commits are each one logical change.
  • Risky or complex parts: none in auth logic — telemetry only; server_events.ts is regenerated, not hand-edited.

Screenshots (Optional)

Please attach the screenshots of the changes made in case of change in user interface.

Other information (Optional)

  • Commits 2–4 extend the ticket's original three reason corrections (button-impression event, set-password surface tagging, backend funnel events), from this session's gap analysis.
  • signin-flow.ts emits a Sentry warning if an alternative-auth user ever reaches the existing-password fallback, to measure the (currently unenforced) no-password invariant behind the reason vocabulary.
  • A Jira comment documenting the additions will be posted to FXA-13896.

Copilot AI 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.

Pull request overview

This PR updates FxA passkey sign-in telemetry to (a) disambiguate sign-in entry surfaces/reasons, (b) add a button impression event so click-through can be measured, (c) propagate passkey surface context into the shared set-password funnel, and (d) add server-side passkey funnel events for “ceremony started” and “assertion verified” steps.

Changes:

  • Adds passkey.button_view (UI) and wires it through the web metrics map and settings Glean dispatch.
  • Expands/normalizes passkey surface/reason vocab (emailfirst, signin, otplogin, alternative_auth) and threads it through passkey flows + set-password funnel tagging.
  • Adds auth-server Glean events for passkey auth start + verification success, and regenerates server event bindings.

Reviewed changes

Copilot reviewed 28 out of 28 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/fxa-shared/metrics/glean/web/passkey.ts Adds the generated passkey.button_view metric type.
packages/fxa-shared/metrics/glean/web/index.ts Registers passkey_button_view in the events map.
packages/fxa-shared/metrics/glean/fxa-ui-metrics.yaml Updates UI telemetry schema: surface-tagged passkey reasons + new passkey.button_view.
packages/fxa-shared/metrics/glean/fxa-backend-metrics.yaml Adds backend passkey funnel events (authentication_started, authentication_verification_success).
packages/fxa-settings/src/pages/Signin/SigninPasswordlessCode/index.tsx Passes isButtonVisible to drive per-surface button impressions.
packages/fxa-settings/src/pages/Signin/SigninPasskeyFallback/index.tsx Updates fallback surface type to PasskeyMetricsSurface.
packages/fxa-settings/src/pages/Signin/SigninPasskeyFallback/index.test.tsx Updates tests for signin surface naming.
packages/fxa-settings/src/pages/Signin/SigninPasskeyFallback/container.test.tsx Updates/extends tests for new surface vocab and auth_success reasons.
packages/fxa-settings/src/pages/Signin/interfaces.ts Updates router state typing to PasskeyMetricsSurface.
packages/fxa-settings/src/pages/Signin/index.tsx Computes showPasskeySignin earlier and passes isButtonVisible.
packages/fxa-settings/src/pages/Signin/index.test.tsx Extends Glean mocks to include passkey.buttonView.
packages/fxa-settings/src/pages/Signin/components/SigninAlternativeAuthOptions/index.tsx Passes isButtonVisible for impression telemetry.
packages/fxa-settings/src/pages/PostVerify/SetPassword/mocks.tsx Adds gleanReason to test subject wiring.
packages/fxa-settings/src/pages/PostVerify/SetPassword/interfaces.ts Adds gleanReason prop and updates passkey surface typing/docs.
packages/fxa-settings/src/pages/PostVerify/SetPassword/index.tsx Uses container-supplied gleanReason for funnel events.
packages/fxa-settings/src/pages/PostVerify/SetPassword/index.test.tsx Adds test ensuring gleanReason is used.
packages/fxa-settings/src/pages/PostVerify/SetPassword/container.tsx Computes surface-tagged gleanReason and uses it for success telemetry.
packages/fxa-settings/src/pages/PostVerify/SetPassword/container.test.tsx Adds tests for surface-tagged set-password success reasons.
packages/fxa-settings/src/pages/Index/index.tsx Passes isButtonVisible to drive impression telemetry on email-first.
packages/fxa-settings/src/lib/passkeys/signin-flow.ts Introduces PasskeyMetricsSurface, surface mapping, and emits passkey.button_view.
packages/fxa-settings/src/lib/passkeys/signin-flow.test.tsx Adds/updates tests for surface mapping, impressions, and Sentry warning path.
packages/fxa-settings/src/lib/glean/index.ts Adds dispatch case for passkey_button_view.
packages/fxa-settings/src/lib/glean/index.test.ts Adds tests for passkey_button_view and expanded auth_success reasons.
packages/fxa-auth-server/lib/routes/passkeys.ts Emits backend passkey start + verification-success Glean events.
packages/fxa-auth-server/lib/routes/passkeys.spec.ts Adds tests ensuring backend passkey events are emitted (or not) appropriately.
packages/fxa-auth-server/lib/metrics/glean/server_events.ts Regenerated server events (glean_parser v19.2.0) with new passkey events.
packages/fxa-auth-server/lib/metrics/glean/index.ts Wires new passkey event functions into the auth-server Glean facade.
packages/fxa-auth-server/lib/metrics/glean/index.spec.ts Updates mocks for new server event logger methods.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/fxa-settings/src/lib/passkeys/signin-flow.ts Outdated
@vpomerleau vpomerleau force-pushed the FXA-13896-passkey-glean-events branch from c72f029 to 679af86 Compare June 11, 2026 03:41
Because:
 - The passkey auth_success and enter_password events shared reason codes
   across the email-first, OTP, login, and alternative-auth flows, so the
   flows could not be told apart in analysis (FXA-13896).

This commit:
 - Maps each sign-in surface to a distinct metric reason: the passwordless
   OTP page to `otplogin`, the /signin page to `signin`, and the
   alternative-auth page to its own `alternative_auth`.
 - Renames PasskeyFallbackSurface to PasskeyMetricsSurface and merges the two
   surface mappers into a single toPasskeyMetricsSurface.
 - Keeps the `<surface>_<outcome>` reason vocabulary to reachable combinations
   only: `otplogin` and `alternative_auth` are no-password surfaces, so they
   never reach the existing-password fallback and pair only with
   `nopassword`/`createdpassword`.
Because:
 - Only page-level view events existed for the passkey sign-in surfaces, so
   click-through on the "Sign in with passkey" button could not be measured.

This commit:
 - Adds a per-surface passkey.button_view Glean event, fired once from
   usePasskeySignIn when the button is actually rendered (gated by a new
   isButtonVisible flag each surface passes), so impressions count buttons
   shown rather than hook mounts.
Because:
 - The shared post_verify_set_password.* events recorded only the password
   creation reason ('passkey'), so the create-password funnel could not be
   split by the originating passkey sign-in surface.

This commit:
 - Composes a surface-tagged reason (`<surface>_passkey`, e.g. signin_passkey)
   in SetPassword's container and passes it to the page as a ready-made
   gleanReason, keeping the shared page flow-agnostic.
 - Defaults a missing surface to `emailfirst` (`emailfirst_passkey`), matching
   the passkey.auth_success default, so the reason stays in-vocabulary.
Because:
 - The backend recorded passkey authentication completion (login.complete,
   reason=passkey) but neither the ceremony start nor the assertion
   verification, so server-side drop-off was invisible.

This commit:
 - Adds passkey.authentication_started (challenge generated) and
   passkey.authentication_verification_success (assertion verified, before
   session/token work), giving a started -> verified -> complete funnel.
 - Regenerates the server Glean bindings (glean_parser v19.0.0 -> v19.2.0).

Copilot AI 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.

Pull request overview

Copilot reviewed 28 out of 28 changed files in this pull request and generated 2 comments.

Comment on lines 367 to +371
state: completion.hasPassword
? { passkeySurface: surfaceToFallbackReason(surface) }
? { passkeySurface: toPasskeyMetricsSurface(surface) }
: {
passwordCreationReason: 'passkey' as const,
passkeySurface: surfaceToFallbackReason(surface),
passkeySurface: toPasskeyMetricsSurface(surface),
Comment on lines +377 to +382
[
'login_otp' as const,
true,
'/signin_passkey_fallback',
{ state: { passkeySurface: 'otplogin' } },
],
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