How passkeys work with custom domains
WebAuthn Relying Party ID (RPID)
WebAuthn uses a Relying Party Identifier (RPID) to scope passkey credentials. The RPID determines:- Where passkeys can be used: Passkeys are bound to the domain where they were created
- Security boundaries: Prevents passkeys from being used on unauthorized domains
- User experience: Users must enroll passkeys separately for each custom domain
Per-domain enrollment
With multiple custom domains, each domain has its own RPID, which means:- A passkey enrolled on
login.brand1.comcannot be used onlogin.brand2.com - Users who authenticate through different custom domains need to enroll passkeys for each domain
- Each domain’s passkeys are managed independently
Understanding the passkey user experience
Single-brand, single-domain
Setup: One custom domain serving one brand User experience:- User visits
login.example.com - User enrolls a passkey
- User can use the passkey for all future logins through
login.example.com
Multi-brand, separate domains
Setup: Multiple brands, each with their own custom domain User experience:- User visits
login.brand1.comand enrolls a passkey - Same user later visits
login.brand2.com(different brand) - Previously enrolled passkey is not available
- User must enroll a new passkey for
login.brand2.com
Multi-tenant with default domain
Setup: Multiple customers, with a default custom domain for shared services User experience:- Most users authenticate through the default domain
- Users enroll passkeys once for the default domain
- Passkeys work consistently for most authentication flows
- Special cases (customer-specific domains) require separate enrollment
Configuration
Enable passkeys for your tenant
Before using passkeys with custom domains, ensure passkeys are enabled:- Navigate to Auth0 Dashboard > Security > Multi-factor Auth
- Enable WebAuthn with FIDO Security Keys
- Configure passkey settings
Configure custom domains for passkeys
Each custom domain automatically gets its own RPID:- RPID format: The custom domain itself (e.g.,
login.example.com) - No additional configuration required: Auth0 automatically configures the RPID for each verified custom domain
Verify RPID configuration
To verify the RPID for a custom domain:- Navigate to Auth0 Dashboard > Branding > Custom Domains
- Select your custom domain
- In the domain details, the RPID will be displayed
Implementation patterns
Prompt for passkey enrollment per domain
Guide users to enroll passkeys for each custom domain they use:Track passkey enrollment by domain
Store which domains a user has enrolled passkeys for:Domain-specific enrollment pages
Create dedicated enrollment pages for each custom domain:Contextual enrollment prompts
Show passkey enrollment prompts based on user behavior. Key considerations:- Track when users dismiss enrollment prompts (store in
localStorage) - Check
logins_countfrom user metadata to show prompts after multiple visits - Verify passkey isn’t already enrolled for the current domain
User communication
Inform users about per-domain enrollment
Clearly communicate to users that passkeys are domain-specific: Example messaging:“For security, passkeys are specific to each login portal. You’ll need to set up a passkey separately for each brand’s login page you use.”Enrollment prompt example:
Help documentation
Provide clear help documentation: FAQ entry example: Q: Why do I need to set up a passkey again? A: Passkeys are tied to specific domains for security. If you’re logging in through a different portal (e.g., Brand A vs Brand B), you’ll need to set up a passkey for each one. This keeps your accounts secure by ensuring passkeys only work where they should. Q: Do I need a different device for each passkey? A: No! You can use the same device (phone, computer, or hardware key) for passkeys on different domains. Each passkey is just a separate credential stored on your device.Limitations and considerations
Current limitations
| Limitation | Impact | Workaround |
|---|---|---|
| No cross-domain passkey sharing | Users must enroll passkeys separately for each custom domain | Use a default domain for most authentication, or guide users to enroll on each domain |
| Cannot transfer passkeys between domains | Migrating to a new custom domain requires re-enrollment | Plan migration carefully, communicate with users, provide re-enrollment flow |
| Related origins not yet supported | Cannot share passkeys across subdomains or related domains | Planned for future release - use per-domain enrollment for now |
Related origins (future feature)
Auth0 plans to support WebAuthn related origins, which will allow passkey sharing across specified domains. This feature will:- Allow you to configure domains as “related” for passkey purposes
- Enable users to use a passkey enrolled on
login.brand1.comonlogin.brand2.comif configured as related - Provide more flexibility for multi-brand implementations
Migration scenarios
Migrating from single custom domain to multiple
Before: Single custom domain with passkeys enrolled After: Multiple custom domains for different brands Challenge: Existing passkeys only work on the original domain Migration approach:- Keep original domain active: Maintain the original custom domain as the default domain
- Gradual rollout: Introduce new custom domains gradually
- User notification: Inform users they’ll need to enroll passkeys on new domains
- Provide re-enrollment flow: Make it easy for users to enroll passkeys on new domains
- Monitor adoption: Track passkey enrollment rates per domain
“We’re introducing brand-specific login pages! Your existing passkey will continue to work on [original domain]. When you visit our new login pages, you’ll be prompted to set up a passkey for faster login there too.”
Migrating between custom domains
Scenario: Changing fromold-domain.com to new-domain.com
Challenge: Passkeys cannot be transferred
Migration steps:
- Parallel operation: Run both domains simultaneously during transition
- Detect enrolled passkeys: Track which users have passkeys on old domain
- Prompt re-enrollment: When users log in via new domain, prompt passkey enrollment
- Grace period: Keep old domain active for a transition period
- Sunset old domain: After adoption, decommission old domain
Testing
Test passkey enrollment per domain
- Set up test custom domains: Configure multiple custom domains in a development tenant
- Test enrollment flow: Enroll a passkey through one custom domain
- Verify isolation: Confirm the passkey doesn’t work on other custom domains
- Test re-enrollment: Enroll passkeys on additional domains
- Cross-browser testing: Test on different browsers and devices
Automated testing
Best practices
- Use a default domain: Configure a default custom domain to minimize the number of domains requiring passkey enrollment
- Clear communication: Inform users about per-domain enrollment requirements
- Prompt strategically: Show enrollment prompts after users demonstrate engagement (e.g., 3+ logins)
- Track enrollment: Monitor which users have enrolled passkeys on which domains
- Provide help: Offer clear documentation and support for passkey management
- Test thoroughly: Test passkey flows on all custom domains before production deployment
- Plan migrations: When changing custom domains, plan for user re-enrollment
- Monitor adoption: Track passkey enrollment and usage rates per domain
Troubleshooting
Passkey not working on custom domain
Symptoms: User enrolled passkey but cannot use it Possible causes:- User is on a different custom domain than where they enrolled
- Browser compatibility issues
- Passkey was deleted from device
- Confirm user is on the correct custom domain
- Check browser support for WebAuthn
- Guide user to re-enroll passkey if needed
User confused about multiple enrollments
Symptoms: User reports “passkey not working” when switching domains Cause: User doesn’t understand per-domain enrollment Resolution:- Provide clear messaging about per-domain passkeys
- Show which domains user has enrolled passkeys for
- Prompt enrollment when user visits a new domain