Skip to content

Commit 5dab0b7

Browse files
authored
Merge pull request #388 from passkeydeveloper/382-related-origins
Adds Related Origin Requests
2 parents 64d0ddb + d34b8f2 commit 5dab0b7

File tree

3 files changed

+233
-4
lines changed

3 files changed

+233
-4
lines changed

content/device-support/_index.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ Passkeys created in **macOS** can be used on:
4747

4848
- the same Windows device that created them
4949

50-
## Matrix
50+
## Matrix {#matrix}
5151

5252
<div id="device-support-table" class="table-responsive">
5353
<table class="table table-striped mt-0">
@@ -418,7 +418,7 @@ Passkeys created in **macOS** can be used on:
418418
</thead>
419419
</table>
420420

421-
## Advanced Capabilities
421+
## Advanced Capabilities {#advanced}
422422

423423
<details>
424424
<summary><strong>Details</strong></summary>
@@ -555,8 +555,8 @@ Passkeys created in **macOS** can be used on:
555555
</td>
556556
</tr>
557557
<tr class="align-top">
558-
<td class="fw-bold">
559-
<a href="https://w3c.github.io/webauthn/#sctn-related-origins" target="_blank">Related Origin Requests</a>
558+
<td class="fw-bold" id="ror">
559+
<a href="/docs/advanced/related-origins/" target="_blank">Related Origin Requests</a>
560560
</td>
561561
<td class="text-center">
562562
{{< icon-circle-check-filled fill="green" size=30 >}}

content/docs/advanced/_index.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
title : "Advanced"
3+
description: "Implement passkeys"
4+
lead: ""
5+
date: 2024-08-22T15:19:38.508Z
6+
draft: false
7+
images: []
8+
weight: 500
9+
sidebar:
10+
collapsed: true
11+
---
Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
---
2+
title: "Related Origin Requests"
3+
description: "The Related Origin Requests (ROR)feature allows an RP to enable a passkey to be created and used across a limited set of related origins."
4+
lead: "The Related Origin Requests (ROR) feature allows an RP to enable a passkey to be created and used across a limited set of related origins."
5+
date: 2024-08-22T15:20:51.937Z
6+
draft: false
7+
images: []
8+
menu:
9+
docs:
10+
parent: "advanced"
11+
weight: 510
12+
toc: true
13+
---
14+
15+
## Use Cases
16+
17+
The two use cases for Related Origin Requests (ROR) are deployments which use different country code top-level domains (ccTLD) across the world, and deployments where different branding is used for different services.
18+
19+
To address these use cases, it is recommended to leverage industry-standard federation protocols such as [OpenID Connect](https://openid.net/specs/openid-connect-core-1_0.html). This approach facilitates a centralized login experience, by using a dedicated login page (e.g., login.example.com) that serves as the authentication point for all origins and services.
20+
21+
<strong>ROR is designed to be used when federation is <i>not</i> possible.</strong>
22+
23+
{{< callout context="note" title="Websites vs Apps" icon="outline/note" >}} ROR is a WebAuthn feature for the web. App platforms have existing mechanisms for mapping native apps to one or more web origins: [Digital Asset Links](https://developers.google.com/identity/credential-sharing/set-up) for Android and [Associated Domains](https://developer.apple.com/documentation/xcode/supporting-associated-domains) on Apple platforms. {{< /callout >}}
24+
25+
### Country Code Top Level Domains (ccTLDs) {#cctld}
26+
27+
Many global organizations utilize [country code top level domains (ccTLDs)](https://icannwiki.org/Country_code_top-level_domain#Current_ccTLDs) to cater to their international services. For instance, a shopping website might use `shopping.com` for users in the United States, while also having `shopping.ca` for Canada, `shopping.co.uk` for the United Kingdom, `shopping.ie` for Ireland, and `shopping.sg` for Singapore, among others. However, a passkey created on `shopping.com` can't be used on `shopping.sg`, and vice versa.
28+
29+
### Alternate Branding
30+
31+
Some organizations offer additional services with different or extended branding and share the same accounts. For instance, a shopping site might have their own credit card or their own travel services, which are accessed via different websites.
32+
33+
## How It Works
34+
35+
Related Origin Requests (ROR) works by allowing a Relying Party (RP) to provide a list of valid origins for a given Relying Party ID (RP ID).
36+
37+
During a WebAuthn ceremony, if the RP ID and origin do not match, the WebAuthn client can query the RP for a list of valid origins. The client processes that origin list and then re-evaluates the binding based on this additional context. If an origin is matched, the client will continue with the request in the context of the RP ID.
38+
39+
A label, in the context of this feature, is the name directly preceding the [effective top level domain](https://developer.mozilla.org/en-US/docs/Glossary/eTLD). For instance, `shopping` is the label for `https://shopping.com`, `https://shopping.co.uk`, `https://shopping.co.jp`, `https://shopping.net`, and `https://shopping.org`. Labels are used as a way to support the large number of entries required to support [ccTLDs](#cctld), while enabling clients to restrict the number of unique origins to prevent abuse.
40+
41+
If there are 30 origins in the list, all with the same label, these count as 1 unique label. WebAuthn requires client implementations to support at least 5 unique labels, however there are no known clients which support more than 5, so that should be treated as the maximum for deployments.
42+
43+
Below are three examples of origin lists and their respective label counts.
44+
45+
{{< tabs "label-examples" >}}
46+
{{< tab "1 Label" >}}
47+
48+
1. `shopping`
49+
50+
```json
51+
{
52+
"origins": [
53+
"https://shopping.com",
54+
"https://shopping.co.uk",
55+
"https://shopping.co.jp",
56+
"https://shopping.ie",
57+
"https://shopping.ca",
58+
"https://shopping.net",
59+
"https://shopping.org",
60+
"https://shopping.github.io"
61+
]
62+
}
63+
```
64+
65+
{{< /tab >}}
66+
{{< tab "3 Labels" >}}
67+
68+
1. `shopping`
69+
1. `myshoppingrewards`
70+
1. `myshoppingtravel`
71+
72+
```json
73+
{
74+
"origins": [
75+
"https://shopping.com",
76+
"https://shopping.co.uk",
77+
"https://shopping.co.jp",
78+
"https://shopping.ie",
79+
"https://shopping.ca",
80+
"https://myshoppingrewards.com",
81+
"https://myshoppingrewards.co.uk",
82+
"https://myshoppingrewards.co.jp",
83+
"https://myshoppingrewards.ie",
84+
"https://myshoppingrewards.ca",
85+
"https://myshoppingtravel.com",
86+
"https://myshoppingtravel.co.uk",
87+
"https://myshoppingtravel.co.jp",
88+
"https://myshoppingtravel.ie",
89+
"https://myshoppingtravel.ca"
90+
]
91+
}
92+
```
93+
94+
{{< /tab >}}
95+
{{< tab "5 Labels" >}}
96+
97+
1. `shopping`
98+
1. `myshoppingcard`
99+
1. `myshoppingrewards`
100+
1. `myshoppingcreditcard`
101+
1. `myshoppingtravel`
102+
103+
```json
104+
{
105+
"origins": [
106+
"https://shopping.com",
107+
"https://shopping.co.uk",
108+
"https://shopping.co.jp",
109+
"https://shopping.ie",
110+
"https://shopping.ca",
111+
"https://myshoppingcard.us",
112+
"https://myshoppingrewards.com",
113+
"https://myshoppingrewards.co.uk",
114+
"https://myshoppingrewards.co.jp",
115+
"https://myshoppingrewards.ie",
116+
"https://myshoppingrewards.ca",
117+
"https://myshoppingcreditcard.co.uk",
118+
"https://myshoppingcreditcard.co.jp",
119+
"https://myshoppingcreditcard.ie",
120+
"https://myshoppingcreditcard.ca",
121+
"https://myshoppingtravel.com",
122+
"https://myshoppingtravel.co.uk",
123+
"https://myshoppingtravel.co.jp",
124+
"https://myshoppingtravel.ie",
125+
"https://myshoppingtravel.ca"
126+
]
127+
}
128+
```
129+
130+
{{< /tab >}}
131+
{{< /tabs >}}
132+
133+
## Requirements
134+
135+
### Client Support
136+
137+
The [Device Support matrix](/device-support/#ror) lists the browsers which support Related Origin Requests. The [Passkeys Feature Detect page](https://featuredetect.passkeys.dev) will also attempt to detect ROR support in the browser in which the page was loaded.
138+
139+
To dynamically detect support for Related Origin Requests on an enrollment or login page, Relying Parties should check for `relatedOrigins` in the [WebAuthn Get Client Capabilities (`PublicKeyCredential.getClientCapabilities()`)](https://w3c.github.io/webauthn/#sctn-getClientCapabilities) response.
140+
141+
### Relying Party Changes
142+
143+
A JSON document must be hosted at the WebAuthn well-known path for the Relying Party ID, `/.well-known/webauthn`.
144+
145+
For example, if the RP ID is `shopping.com`, the full URL would be `https://shopping.com/.well-known/webauthn`.
146+
147+
The server must respond with a content type of `application/json`.
148+
149+
The JSON document must have a member named `origins`, containing an array of valid origins for use with passkeys scoped for the RP ID.
150+
151+
> See [Deployment Considerations](#deployment-considerations) below for details on choosing an RP ID.
152+
153+
Below is an example for the RP ID `shopping.com`.
154+
155+
```json {title="https://shopping.com/.well-known/webauthn"}
156+
{
157+
"origins": [
158+
"https://shopping.com",
159+
"https://myshoppingrewards.com",
160+
"https://myshoppingcreditcard.com",
161+
"https://myshoppingtravel.com",
162+
"https://shopping.co.uk",
163+
"https://shopping.co.jp",
164+
"https://shopping.ie",
165+
"https://shopping.ca"
166+
]
167+
}
168+
```
169+
170+
## Deployment Considerations
171+
172+
### Greenfield Deployments
173+
174+
The most important design decision for a greenfield deployment using ROR is picking a common Relying Party ID (RP ID) to be used for passkeys across all origins. All WebAuthn requests across all related origins will use that as `rp.id`.
175+
176+
It is recommended to pick the most commonly used and/or understood domain for the common RP ID. This is typically the domain closely associated with the organization's brand, and is often the `.com`.
177+
178+
### Existing Deployments
179+
180+
For deployments where passkeys are already rolled out with multiple RP IDs, there are some unique considerations and requirements.
181+
182+
__Considerations__
183+
184+
- Users with a passkey for the "local" RP ID / origin will be able to use all passkeys experiences as normal.
185+
- Users with a passkey for another RP ID / related origin, will require an identifier first flow and a backend lookup.
186+
187+
__Requirements__
188+
189+
- Each existing RP ID will need to host the WebAuthn well-known document, with all of the other origins listed in it. This will allow reciprocal use of passkeys
190+
- The account database will need to know which RP ID was used for each passkey (this could be an explicit property or inferred based on other data)
191+
- The username field on the login page will need to support fallback to an identifier first flow with backend lookup
192+
193+
#### Flow
194+
195+
This flow assumes the [autofill UI](/docs/reference/terms/#autofill-ui) for passkeys is being used.
196+
197+
1. Make a conditional WebAuthn request normally on page load
198+
2. If the promise resolves, process the WebAuthn response as normal and sign the user in
199+
3. If the the user enters a username and continues:
200+
- abort the conditional WebAuthn request
201+
- send a request to your backend to retrieve the RP ID for the username
202+
4. Fetch fresh WebAuthn parameters from the backend
203+
5. Call WebAuthn with the fresh parameters and the correct RP ID
204+
205+
#### Example
206+
207+
In this example, passkeys have previously been rolled out to the following users:
208+
209+
- `https://shopping.com` users, with an RP ID of `shopping.com`
210+
- `https://shopping.co.uk` users, with an RP ID or `shopping.co.uk`
211+
212+
A user with a passkey for `shopping.com` navigates to `https://shopping.com`, clicks into the username field, selects their passkey, performs user verification, and is then signed in!
213+
214+
A user with a passkey for `shopping.co.uk` has traveled to the US and navigates to `https://shopping.co.uk`. Based on location data, the user is redirected to `https://shopping.com`. They click into the username field and do not see any passkey available. They then type their username and click continue. A backend lookup occurs, and WebAuthn is now invoked with an RP ID of `shopping.co.uk` and the user selects their passkey, performs user verification, and is signed in!
215+
216+
## Additional Information
217+
218+
<a href="https://w3c.github.io/webauthn/#sctn-related-origins" target="_blank"><button type="button" class="btn btn-light">WebAuthn Spec Reference {{< icon-external-link size=24 >}}</button></a>

0 commit comments

Comments
 (0)