Associating passkeys with local user accounts
A successful passkey registration or authentication returns a Principal or ExtendedPrincipal. The two account-linking fields you will use most often are:
userId: Application user ID supplied by your backend during registrationauthenticatorId: Passkey ID
{ "authenticatorId": "spy28n0bqca11tq", "userId": "myInternalUserId"}Set your user ID during authorizePasskeyRegistration:
const result = await passlock.authorizePasskeyRegistration({ userId: user.id, username: user.email,});When you later exchange the registration code, confirm the returned userId matches the local user that started registration:
const result = await passlock.exchangeCode({ code });
if (!result.success) { throw new Error(result.error.message);}
if (result.value.userId !== user.id) { throw new Error("Passkey registration user mismatch");}You should still store authenticatorId for passkey management, deletion, audit logs, duplicate-prevention queries and support workflows. A single local user can have multiple passkeys, so your local data model will often track both fields.
---
title: Example table structure
---
erDiagram
user[user] {
string id PK
}
authenticator[authenticator] {
string authenticatorId PK "Passlock passkey ID"
string userId FK "points to user.id"
}
user ||--|{ authenticator : "User has one or more passkeys"
A passkey’s userId is immutable. If a passkey is linked to the wrong local account, delete that passkey and register another with the correct user ID.