Skip to content

Commit 1e689aa

Browse files
sandhosehughnsclokepturt2liverichvdh
authored
MSC2965: OAuth 2.0 Authorization Server Metadata discovery (#2965)
* OIDC discovery MSC * Add `account` field * Add id_token_hint to account management URL * Add reference to MSC3861 * Add missing heading * Fix reference to MSC3861 * Update proposals/2965-oidc-discovery.md Co-authored-by: Patrick Cloke <clokep@users.noreply.github.com> * Fix typo * Update 2965-oidc-discovery.md * Update proposals/2965-oidc-discovery.md Co-authored-by: Patrick Cloke <clokep@users.noreply.github.com> * Update proposals/2965-oidc-discovery.md Co-authored-by: Patrick Cloke <clokep@users.noreply.github.com> * OIDC Provider -> OpenID Provider * Define account management URL params * Link for account management URLs * MSC2965: move from well-known discovery to a dedicated C-S endpoint * MSC2965: add a note about why the well-known alternative has been discarded * MSC2965: move the account management URL to the provider metadata * MSC2965: line breaks * MSC2965: update note about the account endpoint metadata * Move the /auth_issuer endpoint to the v1 prefix * Add the `org.matrix.cross_signing_reset` action * Typo * Rename MSC * Remove account-related URLs * Mention RFC8414 as alternative * Outline another alternative: publish the metadata through a C-S API * Fix the alternative flow * Publish the auth server metadata through a new C-S API endpoint This removes the depdency on OIDC specs * renamed 2965-oidc-discovery.md -> 2965-auth-metadata.md * Clarify auth & rate limiting requirements Co-authored-by: Travis Ralston <travpc@gmail.com> * Mention the MSCs using each metadata value * Explain what to do when next-gen auth is not available * Add rationale for not using a .well-known endpoint * Reformat with prettier * Add `issuer` to the required metadata fields * Explain why we don't just use static C-S endpoints * Apply suggestions from code review Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * Move the rationale for not using a `.well-known` document to the alternatives section. * Typo * Clarify why using the .well-known would be confusing Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * Clarify what 'UIA flows' are exactly Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --------- Co-authored-by: Hugh Nimmo-Smith <hughns@users.noreply.github.com> Co-authored-by: Patrick Cloke <clokep@users.noreply.github.com> Co-authored-by: Travis Ralston <travpc@gmail.com> Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
1 parent 9e729ec commit 1e689aa

File tree

1 file changed

+234
-0
lines changed

1 file changed

+234
-0
lines changed

proposals/2965-auth-metadata.md

Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
# MSC2965: OAuth 2.0 Authorization Server Metadata discovery
2+
3+
This proposal is part of the broader [MSC3861: Next-generation auth for Matrix, based on OAuth 2.0/OIDC][MSC3861].
4+
5+
To be able to initiate an OAuth 2.0 login flow to use a Matrix server, the client needs to know the authorization server metadata, as defined in [RFC8414].
6+
7+
## Proposal
8+
9+
This introduces a new Client-Server API endpoint to discover the authorization server metadata used by the homeserver.
10+
11+
### `GET /auth_metadata`
12+
13+
A request on this endpoint should return a JSON object containing the authorization server metadata as defined in [RFC8414].
14+
This endpoint does _not_ require authentication, and MAY be rate limited per usual.
15+
16+
For example:
17+
18+
```http
19+
GET /_matrix/client/v1/auth_metadata
20+
Host: example.com
21+
Accept: application/json
22+
```
23+
24+
```http
25+
HTTP/1.1 200 OK
26+
Content-Type: application/json
27+
Cache-Control: public, max-age=3600
28+
```
29+
30+
```json
31+
{
32+
"issuer": "https://account.example.com/",
33+
"authorization_endpoint": "https://account.example.com/oauth2/auth",
34+
"token_endpoint": "https://account.example.com/oauth2/token",
35+
"registration_endpoint": "https://account.example.com/oauth2/clients/register",
36+
"revocation_endpoint": "https://account.example.com/oauth2/revoke",
37+
"jwks_uri": "https://account.example.com/oauth2/keys",
38+
"response_types_supported": ["code"],
39+
"grant_types_supported": ["authorization_code", "refresh_token"],
40+
"response_modes_supported": ["query", "fragment"],
41+
"code_challenge_methods_supported": ["S256"],
42+
"...": "some fields omitted"
43+
}
44+
```
45+
46+
**Note**: The fields required for the main flow outlined by [MSC3861] and its sub-proposals are:
47+
48+
- `issuer` (for compliance with [RFC8414])
49+
- `authorization_endpoint` ([MSC2964])
50+
- `token_endpoint` ([MSC2964])
51+
- `revocation_endpoint` ([MSC4254])
52+
- `registration_endpoint` ([MSC2966])
53+
- `response_types_supported` including the value `code` ([MSC2964])
54+
- `grant_types_supported` including the values `authorization_code` and `refresh_token` ([MSC2964])
55+
- `response_modes_supported` including the values `query` and `fragment` ([MSC2964])
56+
- `code_challenge_methods_supported` including the value `S256` ([MSC2964])
57+
58+
See individual proposals for more details on each field.
59+
60+
### Fallback
61+
62+
If the homeserver does not offer next-generation authentication as described in [MSC3861], this endpoint should return a 404 with the `M_UNRECOGNIZED` error code.
63+
64+
In this case, clients should fall back to using the existing [login/logout](https://spec.matrix.org/v1.13/client-server-api/#login) and [account-management](https://spec.matrix.org/v1.13/client-server-api/#account-registration-and-management) APIs, as well as [`/account/3pid/add`](https://spec.matrix.org/v1.13/client-server-api/#post_matrixclientv3account3pidadd), [`/delete_devices`](https://spec.matrix.org/v1.13/client-server-api/#post_matrixclientv3delete_devices) and [`DELETE /devices/{id}`](https://spec.matrix.org/v1.13/client-server-api/#delete_matrixclientv3devicesdeviceid).
65+
66+
## Potential issues
67+
68+
The authorization server metadata is relatively large and may change over time. The client should:
69+
70+
- Cache the metadata appropriately based on HTTP caching headers
71+
- Refetch the metadata if it is stale
72+
73+
## Alternatives
74+
75+
### Use static Client-Server API endpoints
76+
77+
Instead of using the standard server metadata as defined in [RFC8414], this proposal could have defined a static set of endpoints under the Client-Server API, e.g.:
78+
79+
- `/_matrix/client/v1/auth/authorize` as the `authorization_endpoint`
80+
- `/_matrix/client/v1/auth/token` as the `token_endpoint`
81+
- `/_matrix/client/v1/auth/revoke` as the `revocation_endpoint`
82+
- `/_matrix/client/v1/auth/register` as the `registration_endpoint`
83+
84+
This approach has been discarded for three reasons:
85+
86+
- The proposed approach ensures interoperability with existing OAuth 2.0 libraries/clients, complying with [RFC8414].
87+
- The `authorization_endpoint` is user-facing, and implementations may have valid reasons to expose it on a different domain than the Client-Server API. For example, iOS may display the domain name of the authorization endpoint in a confirmation prompt before the user is redirected to it, so it has to be recognizable by the end user.
88+
- While the set of metadata fields is currently relatively small and mostly consists of endpoints, it is likely that as the specification evolves and more OAuth 2.0 mechanisms are added, the set of fields will grow. Reusing the authorization server metadata concept as defined in [RFC8414] makes it easier to use existing, well-known OAuth 2.0 flows.
89+
90+
### Discovery via OpenID Connect Discovery
91+
92+
Instead of directly exposing the metadata through a Client-Server API endpoint, the homeserver could expose only the issuer URL and let clients discover the metadata using OpenID Connect Discovery.
93+
94+
In this approach, a new endpoint `/_matrix/client/v1/auth_issuer` would return just the issuer URL:
95+
96+
```http
97+
GET /_matrix/client/v1/auth_issuer
98+
Host: example.com
99+
Accept: application/json
100+
```
101+
102+
```http
103+
HTTP/1.1 200 OK
104+
Content-Type: application/json
105+
```
106+
107+
```json
108+
{
109+
"issuer": "https://account.example.com/"
110+
}
111+
```
112+
113+
The Matrix client would then discover the OpenID Connect Provider configuration by using [OpenID Connect Discovery].
114+
115+
The downside of this approach is that it requires an extra roundtrip to get the metadata.
116+
It also introduces a dependency on an OpenID Connect specification: [MSC3861] proposals tries to build on OAuth 2.0/IETF standards as much as possible.
117+
118+
### Discovery via [RFC8414] well-known endpoint
119+
120+
[RFC8414: OAuth 2.0 Authorization Server Metadata][RFC8414] already defines a standard well-known endpoint, under `.well-known/oauth-authorization-server`.
121+
However, the RFC states that an application leveraging this standard should define its own application-specific endpoint, e.g. `/.well-known/matrix-authorization-server`, and _not_ use the `.well-known/oauth-authorization-server` endpoint.
122+
123+
Considering the rest of the client-server API, there are two potential locations where this could be hosted:
124+
125+
1. On the server name domain, with well-known delegation, e.g. `https://example.com/.well-known/matrix/auth-metadata`
126+
2. On the client-server API endpoint root, e.g. `https://matrix-client.example.com/.well-known/matrix/auth-metadata`
127+
128+
The first option would require making well-known documents mandatory on the server name domain, with a document that may need to be updated more frequently than existing ones.
129+
This isn't practical for some server deployments, and clients may find it challenging to consistently perform this discovery.
130+
131+
The second option would be very confusing, as all other Matrix APIs on the client-server domain are prefixed with `/_matrix`, whereas the existing `.well-known` documents ([`/.well-known/matrix/client`](https://spec.matrix.org/v1.13/client-server-api/#getwell-knownmatrixclient) and [`/.well-known/matrix/server`](https://spec.matrix.org/v1.13/server-server-api/#getwell-knownmatrixserver)) are hosted on the server name domain.
132+
133+
### Discovery via existing `.well-known` mechanism
134+
135+
A previous version of this proposal suggested using the existing [homeserver discovery mechanism](https://spec.matrix.org/v1.13/client-server-api/#server-discovery) to discover the authentication server.
136+
137+
A new `m.authentication` field is added to the `.well-known` document to support OpenID Connect Provider (OP) discovery.
138+
It is an object containing two fields:
139+
140+
- REQUIRED `issuer` - the OpenID Connect Provider that is trusted by the homeserver
141+
- OPTIONAL `account` - the URL where the user is able to access the account management capabilities of the OpenID Connect Provider
142+
143+
For example:
144+
145+
```http
146+
GET /.well-known/matrix/client
147+
Host: example.com
148+
Accept: application/json
149+
```
150+
151+
```http
152+
HTTP/1.1 200 OK
153+
Content-Type: application/json
154+
```
155+
156+
```json
157+
{
158+
"m.homeserver": {
159+
"base_url": "https://matrix-client.example.com"
160+
},
161+
"m.identity_server": {
162+
"base_url": "https://identity.example.com"
163+
},
164+
"m.authentication": {
165+
"issuer": "https://account.example.com",
166+
"account": "https://account.example.com/myaccount"
167+
}
168+
}
169+
```
170+
171+
This proposal, although implemented in some clients and in Synapse, has the downside of making the well-known discovery mandatory.
172+
When implemented in clients, in many circumstances it was hard to go back and use well-known discovery, as they may already know the homeserver URL.
173+
Since the authentication server is always tightly coupled to the homeserver (as opposed to the identity server), it makes sense to discover it via a Client-Server API endpoint.
174+
175+
The account management URL was also part of this proposal, but it was moved to the OpenID Connect Provider metadata because it makes more sense for the provider to advertise it, and not the homeserver.
176+
177+
### Discovery via the `m.login.oauth2` authentication method
178+
179+
The spec already defines a `m.login.oauth2` authentication method, but it was never implemented.
180+
The downside of this approach is that the plan is to deprecate the old login mechanism and it does not make sense to keep it just to discover the issuer.
181+
182+
### Discovery via WebFinger
183+
184+
OIDC already has a standard way to discover OP from an identifier: WebFinger.
185+
This is already adopted by Mastodon, and might help solve logging in via 3PIDs like emails.
186+
187+
Sample exchange:
188+
189+
```
190+
GET /.well-known/webfinger?
191+
resource= mxid:@john:example.com &
192+
rel= http://openid.net/specs/connect/1.0/issuer
193+
Host: example.com
194+
```
195+
196+
```json
197+
{
198+
"subject": "mxid:@john:matrix.org",
199+
"links": [
200+
{
201+
"rel": "http://openid.net/specs/connect/1.0/issuer",
202+
"href": "https://account.example.com"
203+
}
204+
]
205+
}
206+
```
207+
208+
The `mxid` scheme is a bit arbitrary here.
209+
The parameters in the URL should be percent-encoded, this was left unencoded for clarity.
210+
211+
The benefits of this approach are that it is standard and decouples the authentication server from the Matrix server:
212+
different authentication servers could be used by different accounts on the server.
213+
214+
The downsides of this approach are:
215+
216+
- the `.well-known/webfinger` resource is dynamic, which can be harder to host/delegate & might conflict with other services leveraging it like Mastodon
217+
- this does not cover discovering the authentication server for user registration
218+
219+
## Security considerations
220+
221+
None relevant.
222+
223+
## Unstable prefix
224+
225+
While this MSC is not in a released version of the specification,
226+
clients should use the `org.matrix.msc2965` unstable prefix for the endpoint,
227+
e.g. `GET /_matrix/client/unstable/org.matrix.msc2965/auth_metadata`.
228+
229+
[RFC8414]: https://tools.ietf.org/html/rfc8414
230+
[MSC2964]: https://github.com/matrix-org/matrix-spec-proposals/pull/2964
231+
[MSC2966]: https://github.com/matrix-org/matrix-spec-proposals/pull/2966
232+
[MSC3861]: https://github.com/matrix-org/matrix-spec-proposals/pull/3861
233+
[MSC4254]: https://github.com/matrix-org/matrix-spec-proposals/pull/4254
234+
[OpenID Connect Discovery]: https://openid.net/specs/openid-connect-discovery-1_0.html

0 commit comments

Comments
 (0)