Skip to content

Deleting passkeys

Use the @passlock/server library from your backend. You can delete by Passlock passkey IDs or by your application userId.

backend/delete-passkey.ts
import { Passlock } from "@passlock/server";
const passlock = new Passlock({ tenancyId, apiKey });
const result = await passlock.deletePasskeys({
passkeyIds: [passkeyId],
});
if (!result.success) {
throw new Error(result.error.message);
}
// Send only this token to your frontend.
return {
deletePasskeysToken: result.value.deletePasskeysToken,
};

Use the @passlock/browser library to exchange the prepared token and signal local removal:

frontend/delete-passkey.ts
import { Passlock } from "@passlock/browser";
const passlock = new Passlock({ tenancyId });
const { deletePasskeysToken } = await fetchPreparedPasskeyDeletion();
const result = await passlock.deletePasskeys({ deletePasskeysToken });
if (result.success) {
console.log(result.value.warnings);
} else {
console.error(result.error.message);
}

To delete every passkey associated with one application user, pass userId instead of passkeyIds:

backend/delete-passkey.ts
import { Passlock } from "@passlock/server";
const passlock = new Passlock({ tenancyId, apiKey });
const result = await passlock.deletePasskeys({
userId: user.id,
});
if (!result.success) {
throw new Error(result.error.message);
}

Passlock rejects requests that include both passkeyIds and userId. Missing passkey IDs and empty user passkey sets are returned as warnings when they do not prevent the operation.

As explained in the guide to handling missing passkeys, the client and server side elements of a passkey could drift. The user might try to sign in with a passkey which exists on their device but does not exist in your backend vault.

In this scenario your frontend authenticatePasskey call will receive an OrphanedPasskeyError. Tell the user the passkey is no longer valid and give them a way to remove it from their password manager. For passkeys that still have a known vault record, use the normal prepared deletion flow instead.

frontend/authenticate.ts
import {
Passlock,
isOrphanedPasskeyError,
} from "@passlock/browser";
const passlock = new Passlock({ tenancyId });
const result = await passlock.authenticatePasskey({ ... });
if (result.failure && isOrphanedPasskeyError(result.error)) {
alert("This passkey is no longer valid. Please remove it from your password manager.");
}