Passkey reuse across sites you control

Passkeys are scoped to the site they were created for. A passkey made on example.com can't be used to sign in on example.co.uk, even if the same company operates both domains. Similarly, a user can't use one credential across acme.com and acmerewards.com, and mobile apps present their own challenge when they don't own a domain at all.

This restriction comes from the WebAuthn relying party ID (RP ID), which for a domain like example.com might be set to www.example.com or example.com. The RP ID prevents a single passkey from becoming a universal sign-in credential, but it creates friction for organizations that operate multiple domains or a branded domain plus an app.

Existing workarounds rely on identity federation or iframe-based approaches, which aren't always convenient. Related Origin Requests is a more direct solution.

Related Origin Requests lets a website declare which other origins are allowed to use its RP ID. A site serves a JSON file at https://{RP ID}/.well-known/webauthn. If example.com wants to let other origins use it as an RP ID, it hosts that file:

{
  "origins": [
    "https://example.co.uk",
    "https://example.de",
    "https://example-rewards.com"
  ]
}

When a browser sees a passkey creation (navigator.credentials.create) or authentication (navigator.credentials.get) call that uses example.com as the RP ID but the requesting origin doesn't match, it consults the .well-known/webauthn file at https://{RP ID}/.well-known/webauthn (assuming the browser supports Related Origin Requests). If the file lists the requesting origin in its allowlist, the browser proceeds with the operation. Browsers that don't support the feature throw a SecurityError.

Chrome and Safari support Related Origin Requests. As of January 2026, Firefox hasn't committed; tracking is in the Mozilla standards position issue.

Setting it up across two sites

Consider a scenario with two sites, https://ror-1.glitch.me and https://ror-2.glitch.me. The goal is a shared passkey that works on both. The demo at ror-2.glitch.me implements this by letting ror-2.glitch.me use ror-1.glitch.me as its RP ID, backed by a shared account database. The observable behavior:

  • Users can create and authenticate with a passkey on ror-2, even though the RP ID is ror-1.
  • A passkey created on either site authenticates on both.
  • Chrome can autofill credentials on both sites after creation on either one.
  • Credentials always carry the RP ID ror-1.

Set up the JSON file

First, configure site-1.com to allow site-2.com as an RP ID:

{
    "origins": [
        "https://site-2.com"
    ]
}

The JSON object requires a key named origins, whose value is an array of one or more web-origin strings. Note that each origin is reduced to its eTLD + 1 label: example.co.uk and example.de both reduce to example, but example-rewards.com stays example-rewards. In Chrome, the maximum number of labels is 5.

Serve the file

Serve the file at site-1.com/.well-known/webauthn. In an Express app:

app.get("/.well-known/webauthn", (req, res) => {
  const origins = {
    origins: ["https://site-2.com"],
  };
  return res.json(origins);
});

The res.json call sets the content-type to 'application/json' automatically. Set up the equivalent in the ror-1 codebase as a reference.

Point site-2 at site-1's RP ID

In the site-2 codebase, use site-1.com as the RP ID in every place it's needed:

  • Credential creation: set site-1.com as the RP ID in the options passed to navigator.credentials.create (typically generated server-side), and expect that RP ID when verifying the credential before saving.
  • Authentication: set site-1.com in the options passed to navigator.credentials.get, and expect it during server-side verification.

See the RP_ID_ROR references in the ror-2 codebase as a working example.

Troubleshooting

Error message popup in Chrome.
Error message in Chrome upon credential creation. This error is thrown if your `.well-known/webauthn` file can't be found at `https://{RP ID}/.well-known/webauthn`.
Error message popup in Chrome.
Error message in Chrome upon credential creation. This error is thrown if your `.well-known/webauthn` file can be found, but doesn't list the origin you're trying to create a credential from.

Apps, passwords, and credential managers

Related Origin Requests only bridges passkeys across sites you control. Different techniques are needed for other scenarios:

Also consider how credentials are presented to users. In the long term, credential managers and user agents should display where a credential has been used rather than expose the RP ID as a user-visible concept. That transition takes time, and until then it may help to surface both the current site and the site where the account was originally registered.