All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
PasskeyControllerverifies registration and authentication responses withrequireUserVerification: true, so the WebAuthn user verification (UV) flag must be set; assertions with user presence only no longer pass verification (#8696)
generateAuthenticationOptionsnow setsuserVerification: 'required'so client WebAuthn requests align with server-side verification requirements and do not fail on authenticators that skip UV when set to'preferred'(#8696)
generatePostRegistrationAuthenticationOptionsto issuenavigator.credentials.get()options afternavigator.credentials.create(), keyed to the in-flight registration ceremony (including PRF eval when a salt was used) (#8663)already_enrolled(PasskeyControllerErrorCode.AlreadyEnrolled) when callingprotectVaultKeyWithPasskeywhile a passkey is already enrolled (#8663)
- BREAKING: Enrollment completes in three steps:
generateRegistrationOptions→create()→generatePostRegistrationAuthenticationOptions→get()→protectVaultKeyWithPasskey;protectVaultKeyWithPasskeynow requiresauthenticationResponse, and the vault wrapping key is derived from that post-registration assertion (same path as unlock: PRF when present, otherwiseuserHandle) (#8663) - BREAKING:
PasskeyControllerconstructor optionrpIDis replaced withexpectedRPID: string | string[](normalized to a string array, which may be empty). OptionalrpIdsetsrp.id/rpIdin generated WebAuthn options; when omitted, those fields are omitted. Verification passes that array toverifyRegistrationResponse/verifyAuthenticationResponseasexpectedRPIDs(#8663) - BREAKING:
verifyRegistrationResponseandverifyAuthenticationResponsenow takeexpectedRPIDs: string[]instead ofexpectedRPID: string(#8663) verifyRegistrationResponse/verifyAuthenticationResponseaccept an emptyexpectedRPIDsarray to skip RP ID hash allowlist matching; successful authentication then reportsauthenticationInfo.rpIDas an empty string (#8663)- Increase
CEREMONY_TTL_SLACK_MSto 2 minutes so in-flight ceremony state (CEREMONY_MAX_AGE_MS, 3 minutes including WebAuthn timeout) tolerates longer gaps between WebAuthn options and completion (e.g. post-registration authentication) (#8663) - Bump
@metamask/messengerfrom^1.1.1to^1.2.0(#8632)
protectVaultKeyWithPasskeyrejects post-registration assertions whoseuserHandleis missing or does not match the in-flight registration ceremony when usinguserHandlekey derivation (assertionuserHandleis not signature-bound) (#8663)
- Initial
@metamask/passkey-controller:PasskeyControllerfor WebAuthn passkey vault key protection (HKDF-derived keys, AES-256-GCM wrap/unwrap), PRF oruserHandlederivation, challenge-keyedCeremonyManager, enrollment/unlock/renewal flows,verifyPasskeyAuthentication, selectors, and exported ceremony timing constants. (#8422) PasskeyControllerErrorwith stablecode, optionalcause/context,toJSON, andtoString;PasskeyControllerErrorCode,PasskeyControllerErrorMessage, andcontrollerName. ReplacesPasskeyAuthenticationRejectedError—usePasskeyControllerErrorandcodefor auth failures.- BREAKING: Operational error messages are prefixed with
PasskeyController -; prefercodeorinstanceof PasskeyControllerErrorover matching raw strings. renewVaultKeyProtectionuses the samevault_key_decryption_failedcode asretrieveVaultKeyWithPasskeywhen AES-GCM decrypt fails.- Thrown failures from
verifyRegistrationResponse/verifyAuthenticationResponseare wrapped inPasskeyControllerErrorwithregistration_verification_failed/authentication_verification_failedand the underlying error ascause(aligned with theverified: falsepath). - Debug logging (via
@metamask/utils) for registration/authentication verification failures, missing ceremony state, vault decrypt failures, and vault key mismatch during renewal.
- Registration verification requires the credential
id/rawIdto match the credential id in authenticator data; vault wrapping key derivation uses that verified credential id so enrollment keys align with the stored credential. - Registration options request attestation conveyance
'none'so clients are not asked for direct attestation formats the verifier does not implement (noneand self-attestedpackedonly).