The useful part, up front

What you’ll take away

  • The RP ID scopes a credential; the full origin identifies the calling web context and includes its scheme and relevant port.
  • A subdomain can satisfy the ordinary RP-ID rule while failing a service’s narrower expected-origin policy.
  • The assertion binds client context cryptographically, but valid signatures still need expected origin, challenge and policy checks.
  • Related Origin Requests are an explicit supported mechanism; publishing their allowlist does not automatically change server acceptance.
  • A credential remains associated with its registration RP ID; a later request using a parent name does not rename it.
01

Set up a service with one approved sign-in origin

Imagine a fictional service that signs people in at https://login.example.com. Its passkeys were registered for the relying party ID example.com. The service deliberately accepts authentication responses only from the origin https://login.example.com. These are two different settings: the relying party ID defines the credential's scope, while the accepted origin identifies where the web sign-in request is expected to begin. WebAuthn's specification separates those ideas, and Google's server guide requires checking the expected origin as part of authentication. [1][3] Passing the browser's domain-scope check is therefore not the same as being accepted by the service.

Now add a fictional shop at https://shop.example.com. That hostname sits under the same example.com domain. Under the ordinary domain rule, it can request example.com as the relying party ID, but our server still rejects an assertion whose origin is the shop because the shop is outside its chosen sign-in allowlist. [1][3] That is the puzzle this article explains. All addresses and outcomes are hypothetical, with top-level HTTPS pages, an available matching credential and no special cross-site authorization. A permitted request also still needs the user's participation and all remaining verification checks; the domain relationship does not sign anyone in automatically.

One fictional service has different identifiers for different jobs. All domains are examples. The server accepts only the stated login origin; no related-origin opt-in is assumed.
All domains are examples. The server accepts only the stated login origin; no related-origin opt-in is assumed. · Ameer Journal — original explanatory diagramOriginal editorial illustration; no third-party artwork reused.
02

An origin is more specific than a familiar domain name

For the HTTPS addresses in our example, an origin consists of the scheme, host and port, with the normal default port omitted when it is written as a string. A page path is not part of it. [6] Thus https://login.example.com/account and https://login.example.com/help have the same origin. Adding the usual HTTPS port, 443, does not create a different origin. Using the non-default port 8443 does: https://login.example.com:8443 is a different origin from the one our fictional service accepts. A longer address is not necessarily a different origin; the parts that changed matter.

An RP ID, by contrast, is a domain string rather than a complete origin, so our example.com value contains neither https:// nor a port. [1] The browser's domain-scope decision cannot substitute for the server's more specific origin decision. This also explains why a familiar word somewhere in an address is insufficient. In https://example.com.signin.test, the actual hostname ends in signin.test; example.com is merely an earlier part of the name. Our examples are about parsed address components and domain boundaries, not how similar a logo, title or sign-in form looks to the expected site.

03

The browser checks whether the requested RP ID fits

Start with a page at https://login.example.com. Under WebAuthn's ordinary rule, it can use login.example.com as its RP ID or explicitly use the parent example.com. It cannot choose the public suffix com, a child such as m.login.example.com, or an unrelated domain such as example.net. [1] The rule follows domain boundaries, not a service's brand ownership. The same company owning two websites does not by itself make one website's passkey available to the other. A deliberate related-origin mechanism is a separate possibility, which we will return to later.

For https://shop.example.com, requesting example.com also fits the ordinary domain rule. That says the browser may continue this part of the request; it does not say our server approves the shop as a sign-in origin. The authenticator separately uses the requested RP ID to find a credential with matching scope. [1] The steps answer different questions: is this caller allowed to request that scope, is a matching credential available, and will the service accept the returned assertion? Keeping those questions separate makes a rejected shop-origin response understandable without assuming that the browser or the passkey has failed.

The ordinary RP-ID check allows some requests and rejects others. Hypothetical top-level HTTPS calls with no Related Origin Requests. Passing this scope check is not a completed sign-in.
Hypothetical top-level HTTPS calls with no Related Origin Requests. Passing this scope check is not a completed sign-in. · Ameer Journal — original explanatory diagramOriginal editorial illustration; no third-party artwork reused.
04

The server still checks the actual calling origin

Return to the shop example. Suppose a matching credential is available and an authentication response is produced. Its client data identifies the shop's full origin. The server expects https://login.example.com, so it rejects the response under the policy we set at the start. Client data includes the origin of the requesting context, and server verification checks it against the expected sign-in origin. [2][3] The two hostnames sharing a parent domain does not erase that difference. Allowing example.com as the credential scope is not the same policy as accepting every subdomain as a sign-in page.

Now change only the page path: a request from https://login.example.com/help still has the expected origin. [6] That passes this particular check, but it does not show that the page was intended to offer sign-in or that every remaining check passes. An origin policy draws a web security boundary; it is not a review of each page's user interface. For a service owner, the useful exercise is to write down the exact origins the server should accept and compare them with the actual deployment. A response should not become acceptable merely because its origin contains a familiar name.

05

The origin belongs to the signed context

The response is more than a message that says which page asked. WebAuthn client data includes the operation type, challenge and origin. The authenticator's signature covers its authenticator data together with a SHA-256 hash of that client data. [2][5] The server uses the registered public key and the required verification procedure to check the response. [3] This connection matters: the site is not supposed to trust an origin field merely because somebody sent it. The claimed context must be part of the cryptographically verified response, and its values must also match what the server expected.

Imagine taking a genuine response from the shop and replacing its origin text with the approved login origin. That changes the client data covered by the signature, so the old signature is no longer valid for the altered data under the verification procedure. [5] This is a conceptual integrity example, not a request to manipulate a real sign-in. It also shows the limit of signature verification alone: a genuine signature over an unexpected shop origin can still be rejected by policy. Cryptographic consistency and acceptable context are both necessary; one does not stand in for the other.

06

Change one condition in the same fictional response

Consider a baseline response for our fictional login origin. Assume its credential belongs to the expected account, its RP-ID binding matches example.com, its challenge is the current one, its signature verifies, and the presence and verification flags meet the service's requirements. The illustrated checks pass. Now change just the origin to the shop in a separately validly signed response: the origin check rejects it. Keep the approved origin but supply an earlier challenge instead: the challenge check rejects it. These are hypothetical cases showing the consequences of the rules, not results from a running service or an attempt to bypass them. [1][3]

Two more changes identify other boundaries. If this service requires user verification and the corresponding flag is absent, the response fails that requirement even at the correct origin. If the signature is invalid, matching text fields cannot rescue it. [1][3] Likewise, an RP-ID hash for a different credential scope is not accepted as example.com. [1] The pattern is useful when reading a sign-in error: the correct domain does not prove every check succeeded. Each failure concerns a defined condition, and a single successful-looking field is not an overall authentication result.

Which check rejects each invented response?. All other applicable conditions are assumed satisfied in each hypothetical row. These are logical cases, not executed test vectors.
All other applicable conditions are assumed satisfied in each hypothetical row. These are logical cases, not executed test vectors. · Ameer Journal — original explanatory diagramOriginal editorial illustration; no third-party artwork reused.
07

An approved origin does not make an old response fresh

Our fictional service creates a new challenge for each sign-in attempt and keeps the expected value until it verifies that attempt. Google's guide calls for a challenge that is hard to predict, not reused, and discarded after use or expiry. [3] The returned client data contains an encoded form of that challenge. [2] In a paper example, we might label two challenges A and B, but those letters are only labels for different values; they are not suitable real challenges. A response for A does not answer a new request for B, even when both came from the approved login origin.

The signature connects the response to its context, while the server's saved expectation tells it which attempt that context belongs to. [2][3][5] That is why a familiar origin and a mathematically valid old signature are not enough. The server must compare against the correct current expectation and reject reuse according to its verification procedure. For someone investigating a failed sign-in, this suggests a bounded question: was the response checked against the challenge for that attempt? It does not justify printing private signing material or replacing a failed check with a more permissive one.

08

Adding another legitimate website requires deliberate configuration

Some services need one passkey to work across separate domains, such as example.com and example.net. Related Origin Requests provide a deliberate way to authorize additional web origins. Google's explanation describes an HTTPS document at https://example.com/.well-known/webauthn that lists approved origins for the shared RP ID. A supporting browser can consult it when the ordinary domain relationship does not fit. [4] This is explicit configuration by the RP-ID domain, not an exception granted because two sites use the same logo or say they belong to the same company.

Browser support matters, and the server's origin checks still matter. The related-origin document can allow a request to proceed in a supporting browser, while authentication verification still needs the expected sign-in origin and RP ID. [3][4] If a service legitimately adds example.net, it must consider that accepted-origin policy as part of the deployment. This does not contradict our shop example: the original scenario deliberately enabled no extra origins and accepted only the login origin. The broader feature is a separate configured case, so neither 'any domain can ask' nor 'a passkey can never work across domains' is an adequate explanation.

Related origins require coordinated configuration. The ordinary-domain example changes only through an explicit supported mechanism; a public allowlist does not update server policy by itself.
The ordinary-domain example changes only through an explicit supported mechanism; a public allowlist does not update server policy by itself. · Ameer Journal — original explanatory diagramOriginal editorial illustration; no third-party artwork reused.
09

Changing the requested RP ID does not rename a credential

There is another way a request can pass the browser's domain check and still lack the expected credential. Suppose a fictional passkey was originally registered for login.example.com, not example.com. A page on the login host is allowed to request either scope under the ordinary rule, but the existing credential remains associated with the RP ID used when it was created. The specification and Google's guide require that authentication use the credential's matching RP ID. [1][3] Writing the broader parent domain in a later request does not relabel the earlier credential.

Keep this case separate from allowing a second origin for credentials that were already registered under example.com. In one case, the intended credential scope changed; in the other, the scope stayed fixed while the accepted calling contexts changed. [1][4] Those different changes explain different failures. A useful configuration record therefore includes the registration RP ID as well as the current request RP ID and expected origin. The record should use ordinary identifiers and documented settings. It does not need secret keys, and it should not infer the registered scope merely from the website address visible today.

10

Keep a verification record with a clear boundary

For the fictional service, a useful review record answers five questions: which RP ID was registered and requested, which complete origins are accepted, which challenge belongs to this attempt, whether the signature verifies with the stored credential, and whether the required user checks were satisfied. Those are explanations of what the verifier must establish, not instructions to collect authentication secrets. The official server guide recommends using an appropriate FIDO server library for the verification work. [3] The small cases in this article are a way to understand its inputs and failures, not a replacement implementation.

Read the result at the right level. A browser allowing example.com as the RP ID tells you about the caller's permitted scope. A server accepting https://login.example.com tells you about its origin policy. A complete accepted assertion requires the other checks too. [1][3] This makes the original shop rejection unsurprising: the parent domain matched, but the service had deliberately chosen a narrower sign-in origin. Clear settings and explicit expected values turn a confusing passkey failure into a question that can be investigated without weakening the mechanism that produced it.

Five questions for the acceptance record. This is a conceptual review aid, not complete verification code. Keep secrets out of ordinary configuration notes.
This is a conceptual review aid, not complete verification code. Keep secrets out of ordinary configuration notes. · Ameer Journal — original explanatory diagramOriginal editorial illustration; no third-party artwork reused.
Follow the evidence

Sources & further reading

Explore the references behind this guide. External pages may change after our review.

  1. Web Authentication: An API for accessing Public Key Credentials - Level 2
    W3C · Accessed 6 Nov 2026
  2. AuthenticatorResponse: clientDataJSON property - Web APIs | MDN
    MDN Web Docs · Accessed 6 Nov 2026
  3. Server-side passkey authentication | Web guides | Google for Developers
    Google for Developers · Accessed 6 Nov 2026
  4. Allow passkey reuse across your sites with Related Origin Requests | web.dev
    Google web.dev · Accessed 6 Nov 2026
  5. AuthenticatorAssertionResponse: signature property - Web APIs | MDN
    MDN Web Docs · Accessed 6 Nov 2026
  6. URL: origin property - Web APIs | MDN
    MDN Web Docs · Accessed 6 Nov 2026

Article updated 6 Nov 2026.

Found something we should revisit?

Good explanations get better with thoughtful feedback.

Suggest a correction