Skip to content

feat(passkey): create passkey authentication methods#20216

Merged
MagentaManifold merged 1 commit intomainfrom
FXA-13062
Mar 24, 2026
Merged

feat(passkey): create passkey authentication methods#20216
MagentaManifold merged 1 commit intomainfrom
FXA-13062

Conversation

@MagentaManifold
Copy link
Copy Markdown
Contributor

Because

  • we want passkey authentication methods

This pull request

  • creates passkey authentication methods

Issue that this pull request solves

Closes: FXA-13062

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).

Screenshots (Optional)

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

Other information (Optional)

Any other information that is important to this pull request.

@MagentaManifold MagentaManifold requested a review from a team as a code owner March 18, 2026 19:46
@MagentaManifold MagentaManifold requested a review from Copilot March 18, 2026 19:47
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds high-level Passkey (WebAuthn) authentication/assertion flows to the passkey library, integrating challenge lifecycle management + SimpleWebAuthn verification.

Changes:

  • Implemented generateAuthenticationChallenge() to issue assertion options (optionally restricted to a user’s credentials).
  • Implemented verifyAuthenticationResponse() to validate challenges, verify assertions, update passkey counters/backup state, and emit metrics/logs.
  • Added comprehensive unit tests for the new service methods (including signCount rollback logging).

Reviewed changes

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

File Description
libs/accounts/passkey/src/lib/passkey.service.ts Adds authentication challenge generation + assertion verification orchestration, including metrics/logging and passkey updates.
libs/accounts/passkey/src/lib/passkey.service.spec.ts Adds unit test coverage for the new authentication flows and key error paths.

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

Comment thread libs/accounts/passkey/src/lib/passkey.service.spec.ts Outdated
Comment thread libs/accounts/passkey/src/lib/passkey.service.ts Outdated
Comment thread libs/accounts/passkey/src/lib/passkey.service.ts Outdated
Comment thread libs/accounts/passkey/src/lib/passkey.service.ts Outdated
Comment thread libs/accounts/passkey/src/lib/passkey.service.ts
Comment thread libs/accounts/passkey/src/lib/passkey.service.ts Outdated
allowCredentials = passkeys.map((p) => p.credentialId);
}

return await generateAuthenticationOptions(this.config, {
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.

It might be worth while to record a metric for the number of these challenges that we create.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

challengeManager.generateAuthenticationChallenge() already emits a metric, so there's no point in emitting another

Comment thread libs/accounts/passkey/src/lib/passkey.service.ts
Comment thread libs/accounts/passkey/src/lib/passkey.service.ts
Comment thread libs/accounts/passkey/src/lib/passkey.service.ts Outdated
Comment thread libs/accounts/passkey/src/lib/passkey.service.spec.ts
Comment thread libs/accounts/passkey/src/lib/passkey.service.ts
Copy link
Copy Markdown
Contributor

@dschom dschom left a comment

Choose a reason for hiding this comment

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

Looking good! I think this comment is important, and adding a couple more metrics so we can keep tabs on this better.

async consumeRegistrationChallenge(
uid: string,
challenge: string
challenge: string,
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.

Any particular reason to swap this back?

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.

Oh, I can see why. Since the consumeAuthenticationChallenge() only takes the challenge string, now all functions have the same first parameter

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is to ensure that all methods have consistent parameter orders. I put uid at last because it can be optional in other methods.

signCount: passkey.signCount,
});
} catch (err) {
// simplewebauthn throws when signCount decrements
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.

This was flagged as a discrepancy with the acceptance criteria, "Rollback on error". Might be useful to add a comment saying that this is done by the simplewebauthn lib.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

You mean add a comment in code or in Jira? I've updated the ticket description in Jira about it, and in code we have this comment here. Also the ticket didn't say "rollback on error", but more like "log a warning on rollback", so I'm not quite sure what you mean 🤔

try {
result = await verifyAuthenticationResponse(this.config, {
response,
challenge,
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.

nit: Could use storedChallenge.challenge instead of raw.

Because:

* we want passkey authentication methods

This commit:

* creates passkey authentication methods

Closes #FXA-13062
@MagentaManifold MagentaManifold merged commit 1c78b52 into main Mar 24, 2026
21 checks passed
@MagentaManifold MagentaManifold deleted the FXA-13062 branch March 24, 2026 22:48
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.

5 participants