Skip to main content
Passkeys are cryptographically bound to the domain (rpId) where they were created. When you move your frontend to a new domain, existing passkeys stop working. Users must register new credentials on the new domain. The Create Credential With Code flow solves this: the user signs in on the old domain (where their passkey works), gets a one-time code, and uses it to register a new passkey on the new domain.

Prerequisites

  • Whitelist the new domain in Dashboard > Settings > Passkeys before starting. See Dashboard configuration.
  • Keep the old domain accessible during the transition. Users need to sign with their existing passkey to initiate the flow.
  • SDK v0.6.0+ for explicit rpId support.

Migration flow

1

Generate a credential code on the old domain

The user signs in on the old domain and triggers credential migration. Your backend calls Create Credential Code. This requires a user action signature with the user’s existing passkey.The API returns a 9-character one-time code, valid for 1 minute.
2

Transfer the code to the new domain

Pass the code to your new domain. How you do this is up to you: redirect with query parameter, QR code, manual entry, or any other method that fits your UX.
3

Get a credential challenge on the new domain

On the new domain, call Create Credential Challenge With Code, passing the code from step 1. This returns a registration challenge. No existing credential signature is needed.
4

Create the new passkey

Use the challenge to create a new passkey via WebAuthn. The new passkey will be bound to the new domain’s rpId.
New domain frontend
import { WebAuthn } from '@dfns/sdk-browser'

const webauthn = new WebAuthn({
  rpId: 'new-domain.com',
})

const attestation = await webauthn.create(challenge)
5

Complete registration

Call Create Credential With Code, passing the attestation and the code. No user action signature is required for this call.The user now has a passkey that works on the new domain.

After migration

Once your users have re-registered on the new domain, you can optionally deactivate their old credentials tied to the previous domain. Keep the old domain live until you’re confident all active users have migrated.
To avoid this problem in the future, use your root domain (e.g., example.com) as the rpId instead of a subdomain. Passkeys created with a root domain rpId work on all subdomains. See rpId rules.

WebAuthn configuration

rpId rules, domain setup, and troubleshooting

Credential With Code flow

API reference for the full flow

Rotating credentials

Replacing service account keys, webhook secrets, and user credentials
Last modified on April 10, 2026