The credential property
One area of confusion lies in the credential property. Take the result of a get passkey call:
{ "id": "sewqeeqx69cr7axut7kat", "userId": "puubifsmidah0f8c0y9bm", "enabled": true, "credential": { "id": "bW9wN3IzenE0enJ5OXVnZXoxOWF4", "userId": "MTVkMTFmdHM1Yzg0bDN0anpieG9w", "username": "jdoe@example.com" }}You’ll see there are top-level id and userId properties. The same properties also exist on the nested credential object. Why?
Indirection
Section titled “Indirection”The nested credential object represents the raw Web Authentication API credential. The identifiers are assigned during creation, and can’t be changed thereafter. Although they appear to be strings, they’re actually binary data, just base64url encoded.
We wrap the raw credential with our own identifiers, to make life easier for developers. You can deal with strings instead of binary data, and you can reassign the userId if you want.
Extension
Section titled “Extension”We add additional properties, including information about the platform that generated the passkey. Without this, you’d need to deal with attestation statements and AAGUIDs.
Commonality
Section titled “Commonality”We’ll be introducing additional authenticators in the future, e.g. social logins and TOTP. By wrapping the raw constructs we can present a common interface — id will always be a string, and you can assign the same userId to a passkey or TOTP authenticator.