Support signaling unknown passkey credentials - #68513
Open
rolandVi wants to merge 9 commits into
Open
Conversation
Co-authored-by: Stephen Halter <shalter+msft@microsoft.com>
…aspnetcore into roland/passkey-signals # Conflicts: # src/Identity/Core/src/PublicAPI.Unshipped.txt
rolandVi
requested
a balanced review from Copilot
and removed request for
a team
August 14, 2026 08:17
Contributor
There was a problem hiding this comment.
Pull request overview
Adds safe signaling for unknown passkey credentials after failed sign-in. The diff also introduces known-passkey synchronization APIs and template behavior.
Changes:
- Adds Identity APIs and serialization models for passkey signals.
- Integrates unknown and known signals into Blazor templates.
- Adds unit and browser coverage for signal generation and ordering.
Reviewed changes
Copilot reviewed 22 out of 22 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
Components/App.razor |
Loads the passkey signals module. |
Shared/PasskeySubmit.razor.js |
Signals unknown credentials before autofill. |
Shared/PasskeySubmit.razor |
Exposes unknown-signal options. |
Shared/PasskeySignals.razor.js |
Sends known-passkey signals. |
Shared/PasskeySignals.razor |
Builds known-passkey options. |
Manage/Passkeys.razor |
Signals updated passkey state. |
Login.razor |
Generates unknown-credential options. |
ConfirmEmailChange.razor |
Signals updated user details. |
template-baselines.json |
Registers new template files. |
BlazorTemplateTest.cs |
Tests signal behavior and ordering. |
SignInManagerTest.cs |
Tests signal API delegation. |
PasskeyHandlerSignalTest.cs |
Tests signal option generation. |
UnknownPasskeySignalOptionsResult.cs |
Adds the unknown-signal result API. |
SignInManager.cs |
Exposes signal generation APIs. |
PublicAPI.Unshipped.txt |
Records new public APIs. |
UnknownPasskeySignalOptions.cs |
Defines unknown-signal payloads. |
PublicKeyCredentialId.cs |
Adds minimal credential parsing. |
KnownPasskeysSignalOptions.cs |
Defines known-signal payloads. |
PasskeyHandler.cs |
Implements signal generation. |
KnownPasskeysSignalOptionsResult.cs |
Adds the known-signal result API. |
IPasskeyHandler.cs |
Adds signal handler contracts. |
IdentityJsonSerializerContext.cs |
Registers signal serialization types. |
Suppressed comments (1)
src/Identity/Core/src/SignInManager.cs:620
- The API returns JSON text, while
signalUnknownCredentialexpects an options object. The example omitsJSON.parse, unlike the correct example onUnknownPasskeySignalOptionsResult, so consumers copying this code will pass the wrong type.
/// await PublicKeyCredential.signalUnknownCredential?.(signalOptions);
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Tracked by #68128, API proposal in #68511.
If someone deletes a passkey from their account, their browser carries on offering it at sign-in forever. The sign-in fails every time and there is no way for them to clear it up from the website. This adds the server side of
PublicKeyCredential.signalUnknownCredential, so the app can tell the browser to delete a passkey the server has never heard of.Example usage
The JSON is
{ "rpId": "...", "credentialId": "..." }, ready to hand toPublicKeyCredential.signalUnknownCredential().What changed
MakeUnknownPasskeySignalOptionsAsynconIPasskeyHandler<TUser>,PasskeyHandler<TUser>andSignInManager<TUser>, plus anUnknownPasskeySignalOptionsResultto carry the payload.The handler returns null, do not signal, whenever it is not certain: no passkey support in the store, unparseable JSON, no credential ID, or any user found. Only a clean miss produces a payload.
The credential JSON is parsed into a one field internal type (
PublicKeyCredentialId) rather than the full assertion model, so attestation shaped JSON parses too. The assertion model marksAuthenticatorDataandSignatureas required and would throw.Testing
7 handler tests covering each null path and the success case, 3 on
SignInManager, and an E2E template test for the ordering. The E2E one holds thesignalUnknownCredentialpromise pending, asserts autofill has not started, then resolves it and waits for autofill to begin, so the ordering is pinned as a real dependency rather than a timing coincidence.Resolves #68128.