What an RP ID actually controls
The relying party ID (RP ID) is a domain string that defines the boundary within which a WebAuthn credential — such as a passkey — can be used. When a passkey is created, the browser binds it to the RP ID you specify. On subsequent authentication attempts, the browser checks the requesting origin against that RP ID and refuses to release the credential if the origin doesn't match or fall within the RP ID's scope.
An RP ID must be a valid domain string. It can be either the exact current hostname or a broader parent domain, as long as that broader domain is an eTLD+1 or higher. IP addresses and public suffixes (eTLDs) are not allowed as RP IDs.
Choosing the right scope for your domain
Whether you can use a particular RP ID depends on the origin hosting your service. For a server at https://www.example.com, both example.com and www.example.com are permissible RP IDs; the right choice depends on how widely you want the passkey to roam.
If you register a passkey under the broader eTLD+1 (example.com), it will work on any subdomain — for example, both https://login.example.com and https://shop.example.com. Choosing a more specific RP ID such as login.example.com restricts the passkey to that exact origin; it will not work on https://shop.example.com.
| 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) |
This scoping works because passkeys are cryptographically tied to the RP ID at creation time, and the origin of any future authentication request must correspond to that RP ID for the credential to be released.
Sharing passkeys across distinct sites
Standard RP IDs cannot bridge services that live on different eTLD+1s. If your product spans, say, example.com and example.co.jp, that's a cross-site configuration, and WebAuthn's default behavior won't let users carry a single passkey between them.
Related Origin Requests (ROR) exists for exactly this scenario. ROR lets a browser recognize different origins as parts of the same logical service, so a passkey created on one site can be used on another.
Implementing ROR requires three things:
- A single RP ID — choose one RP ID and reuse it across all participating sites.
- A hosted configuration file — the primary RP ID domain must serve a file at
/.well-known/webauthnlisting the authorized origins. - Consistent calls — the
rpIdpassed in the WebAuthn call must be the primary RP ID on every site, during both creation and authentication. A user onhttps://www.example.co.jpstill usesexample.comas therpId.
For an RP ID of example.com, the configuration file lives at https://example.com/.well-known/webauthn:
{
"origins": [
"https://www.example.co.jp",
"https://shop.example"
]
}
Extending RP IDs to mobile apps
Native mobile apps can use passkeys tied to your web domain, but only after you establish a verifiable relationship between the app and the domain. That relationship is proven through platform-specific files you host on your server.
Android and Digital Asset Links
Android's Credential Manager requires a Digital Asset Link (DAL) file served from the RP ID domain to associate your app with that domain.
- File location:
https://<RP ID>/.well-known/assetlinks.json - Verification: the
origininclientDataJSONmust be validated. On Android this appears asandroid:apk-key-hash:<hash>.
For an RP ID of example.com, the DAL file is 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"
]
}
}
]
iOS and Associated Domains
Apple platforms use an apple-app-site-association (AASA) file on the RP ID domain for the same purpose.
- File location:
https://<RP_ID>/.well-known/apple-app-site-association - Entitlements: add
webcredentials:<app info>to your app's entitlements.
The AASA file for example.com would be at https://example.com/.well-known/apple-app-site-association:
{
"webcredentials":
{
"apps": ["EXAMPLE123.com.example.passkey"]
}
}
Key takeaways
- Pick your RP ID scope deliberately: an eTLD+1 like
example.comcovers all subdomains, while a hostname likelogin.example.comcovers only that exact origin. - For services spread over multiple eTLD+1s, ROR is the mechanism — one shared RP ID plus a
/.well-known/webauthnconfiguration file. - Mobile passkey support depends on verified domain association: a DAL file at
/.well-known/assetlinks.jsonfor Android, and an AASA file at/.well-known/apple-app-site-associationfor iOS.



