Skip to main content
DFNS uses WebAuthn (passkeys) for user authentication. This guide explains how to configure the relying party ID (rpId) for different scenarios.

What is rpId?

The relying party ID (rpId) is a domain identifier that ties passkey credentials to your application. It determines which domain(s) can use a passkey credential.
A passkey created with one rpId cannot be used with a different rpId. Choose your rpId carefully before deploying to production.

rpId rules

  1. Must be a valid domain - e.g., example.com, not https://example.com
  2. Must match or be a parent of the current origin - A passkey for example.com works on app.example.com, but not vice versa
  3. Cannot be a public suffix - e.g., com, co.uk are not allowed

When to specify rpId

Registration

When registering users via Delegated Registration:
Frontend

Login

When logging in via Delegated Login:
Frontend

User action signing

When signing user actions:
Frontend

Recovery

When recovering an account:
Frontend

Development vs production

Local development

For local development, use localhost:
Passkeys created on localhost only work on localhost. You’ll need to create new passkeys when moving to production.

Staging environments

For staging, use a subdomain of your production domain:
This allows passkeys to work on both staging and production.

Production

Use your root domain for maximum flexibility:

Dashboard configuration

Whitelist your domains in the DFNS dashboard:
  1. Navigate to Settings > Webauthn Relying Party
  2. Add your relying party domain (e.g., example.com)
  3. Choose origin settings:
    • All origins (*): Allows all subdomains and associated mobile apps
    • Specific origins: Restrict to specific URLs if needed
Webauthn Relying Party page listing whitelisted passkey domains and their origins
Using the root domain (e.g., example.com) as rpId allows passkeys to work across all subdomains (app.example.com, staging.example.com) and associated mobile apps.

Mobile apps

For mobile apps (iOS, Android, React Native, Flutter), the rpId must match a domain you control, and you must host association files.
Mobile apps cannot use localhost for passkeys. You must use a real domain with proper association files, even during development.

1. Whitelist your domain in DFNS

Before configuring your app, add your domain to DFNS:
  1. Go to Settings > Passkeys in the dashboard
  2. Add your domain (e.g., example.com)

2. Host domain association files

iOS and Android fetch these files to verify your app is associated with the domain. Passkeys won’t work if these files are unavailable.
Host at https://example.com/.well-known/apple-app-site-association:
Replace:
  • TEAM_ID with your Apple Developer Team ID
  • com.example.app with your app’s bundle identifier
The file must be served with Content-Type: application/json and no redirects.

3. Configure your app

Add Associated Domains entitlement:In Xcode, go to your target’s Signing & Capabilities and add:
Or in your .entitlements file:
Configure the signer:

Testing mobile passkeys

For development, you can use a staging domain (e.g., staging.example.com) with the same root rpId (example.com). Passkeys created on staging will work in production if both use the same rpId.

Troubleshooting

”The relying party ID is not a registrable domain suffix”

Your rpId is invalid. Ensure it’s:
  • A valid domain (not a URL)
  • Not a public suffix
  • A parent or exact match of your current origin

”Credential not found” during login

The passkey was created with a different rpId. Users need to re-register with the correct rpId. If you’re migrating to a new domain, see Registering passkeys on a new domain.

Cross-origin issues

If your frontend and backend are on different domains:
  • rpId should match your frontend domain
  • Backend API calls don’t use rpId (they use the auth token)

Complete example

Frontend - webauthn-config.ts

Registration flows

User registration with passkeys

Login flows

User login with passkeys

Delegated auth example

Complete working example with passkeys

Passkey settings migration

Migration guide and SDK examples
Last modified on June 8, 2026