Manage passkeys across multiple domains and apps with RP ID

In WebAuthn and passkeys, the relying party ID (RP ID) specifies the scope of a credential by the domain name. When you create a passkey, the browser ties it to a specific RP ID. The browser then prevents use of that passkey on a domain that does not match or fall within the scope of that ID. Defining your RP ID correctly ensures a seamless passkey experience across subdomains, cross-sites origins, and first-party mobile apps.

RP ID basics

The Relying Party ID (RP ID) is a unique string that identifies your service or website. An RP ID must be a domain string. It can be the exact current hostname or a broader parent domain, provided it is an eTLD+1 or higher. You cannot use IP addresses and Public Suffixes (eTLDs) as an RP ID.

For example, if you host your server at https://www.example.com, you can use example.com or www.example.com as its RP ID, depending on specific needs. The following table shows examples of permissible RP IDs depending on your origin host:

Origin host Permissible RP ID (eTLD+1)
https://login.example.com example.com or login.example.com
https://example.com:8080 example.com (port numbers are excluded)
https://mobile.example.co.jp example.co.jp or mobile.example.co.jp
https://sub.project.org.uk project.org.uk or sub.project.org.uk
https://user.github.io user.github.io (github.io is an eTLD)
https://myapp.pages.dev myapp.pages.dev (pages.dev is an eTLD)
http://localhost localhost (an exception to the HTTPS requirement)

The browser cryptographically ties passkeys to the RP ID when you create them. To use a credential, the origin of the authentication request must match that RP ID.

When you use an eTLD+1 as the RP ID, the passkey works across related subdomains. For example, an RP ID of example.com works for https://login.example.com and https://shop.example.com. A more specific RP ID like login.example.com works on its exact origin but not on https://shop.example.com.

RP ID in cross-site contexts

If your service spans multiple eTLD+1s (for example, example.com and example.co.jp), it is a cross-site configuration. Standard RP IDs don't support cross-site setups.

To share passkeys between distinct sites, use Related Origin Requests (ROR). ROR lets you share passkeys between distinct sites because the client (browser) recognizes different origins as part of the same logical service.

Requirements for ROR:

  • Choose one RP ID: You must choose one RP ID and use it across all sites.
  • Host a configuration file: The primary RP ID domain must host a configuration file at /.well-known/webauthn that lists authorized origins.
  • Maintain consistency: Even if the user is on https://www.example.co.jp, the rpId in the WebAuthn call must be the primary one (for example, example.com) both on creation and authentication.

Example ROR for RP ID example.com: https://example.com/.well-known/webauthn

{
  "origins": [
    "https://www.example.co.jp",
    "https://shop.example"
  ]
}

For more information about Related Origin Requests implementation details, see Allow passkey reuse across your sites with Related Origin Requests

RP ID on mobile apps

Mobile applications can use passkeys by associating with a web domain. You must host a verification file on your server to establish this relationship.

The Android Credential Manager requires a Digital Asset Link (DAL) file on the RP ID domain to associate with the app.

  • Hosting: Host the file at https://<RP ID>/.well-known/assetlinks.json.
  • Verification: Verify the origin in clientDataJSON. For Android, this is a string such as android:apk-key-hash:<hash>.

Example DAL for RP ID example.com (hosted at https://example.com/.well-known/assetlinks.json)

[
  {
    "relation": [
      "delegate_permission/common.handle_all_urls",
      "delegate_permission/common.get_login_creds"
    ],
    "target": {
      "namespace": "android_app",
      "package_name": "com.google.credentialmanager.sample",
      "sha256_cert_fingerprints": [
        "4F:20:47:1F:D9:9A:BA:96:47:8D:59:27:C2:C8:A6:EA:8E:D2:8D:14:C0:B6:A2:39:99:9F:A3:4D:47:3D:FA:11"
      ]
    }
  }
]

For more information, see Configure Digital Asset Links between your app and website

iOS: Associated Domains

Apple platforms require an apple-app-site-association (AASA) file on the RP ID domain to associate with the app.

  • AASA File: Host https://<RP_ID>/.well-known/apple-app-site-association.
  • Entitlements: Add webcredentials:<app info> to the app entitlements.

Example AASA for RP ID example.com: https://example.com/.well-known/apple-app-site-association:

{
  "webcredentials":
    {
      "apps": ["EXAMPLE123.com.example.passkey"]
    }
}

For more information, see Connecting to a service with passkeys in the Apple Developer Documentation.

Summary

The RP ID determines where your users access their passkeys. Keep these points in mind as you implement:

  • Hierarchy and subdomains: The RP ID must be a domain string (eTLD+1 or higher). Using a broader domain like example.com lets passkeys work across all subdomains (for example, login.example.com and shop.example.com).
  • Cross-site solutions: Use Related Origin Requests (ROR) for services spanning multiple eTLDs+1. This requires one RP ID and a configuration file at /.well-known/webauthn.
  • Mobile integration: Establish a verified relationship between your website and mobile apps using a Digital Asset Links (DAL) file at /.well-known/assetlinks.json for Android and an apple-app-site-association (AASA) file at /.well-known/apple-app-site-association for iOS.

Learn more