Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MSC2965: OIDC Provider discovery #2965

Open
wants to merge 26 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
ef474ee
OIDC discovery MSC
sandhose Jan 14, 2021
4d9345c
Add `account` field
hughns May 2, 2022
4a24cf6
Add id_token_hint to account management URL
hughns May 6, 2022
f5b54bf
Add reference to MSC3861
hughns Aug 5, 2022
1cc4976
Add missing heading
hughns Sep 22, 2022
6455b1f
Fix reference to MSC3861
hughns Feb 8, 2023
2a242bb
Update proposals/2965-oidc-discovery.md
hughns Aug 21, 2023
ae920ad
Fix typo
hughns Aug 21, 2023
d9d56f3
Update 2965-oidc-discovery.md
hughns Aug 21, 2023
74b29e0
Update proposals/2965-oidc-discovery.md
hughns Aug 21, 2023
610c22c
Update proposals/2965-oidc-discovery.md
hughns Aug 21, 2023
eed9e60
OIDC Provider -> OpenID Provider
hughns Aug 21, 2023
fdcde60
Define account management URL params
hughns Aug 21, 2023
c0b2565
Link for account management URLs
hughns Aug 21, 2023
e9e3ee1
MSC2965: move from well-known discovery to a dedicated C-S endpoint
sandhose Nov 29, 2023
a36c44a
MSC2965: add a note about why the well-known alternative has been dis…
sandhose Nov 30, 2023
7642a60
MSC2965: move the account management URL to the provider metadata
sandhose Dec 5, 2023
a0218df
MSC2965: line breaks
sandhose Dec 5, 2023
e852963
MSC2965: update note about the account endpoint metadata
sandhose Dec 5, 2023
1bb6dde
Move the /auth_issuer endpoint to the v1 prefix
sandhose Feb 21, 2024
e70cd3d
Add the `org.matrix.cross_signing_reset` action
sandhose Feb 21, 2024
754b290
Typo
sandhose Feb 21, 2024
56949de
Merge branch 'matrix-org:main' into msc/sandhose/oidc-discovery
sandhose Sep 3, 2024
45e9063
Rename MSC
sandhose Sep 4, 2024
27bb308
Remove account-related URLs
sandhose Sep 4, 2024
acabca8
Mention RFC8414 as alternative
sandhose Sep 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
180 changes: 180 additions & 0 deletions proposals/2965-oidc-discovery.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
# MSC2965: Usage of OpenID Connect Discovery for authentication server metadata discovery

This proposal is part of the broader [MSC3861: Next-generation auth for Matrix, based on OAuth 2.0/OIDC](https://github.com/matrix-org/matrix-spec-proposals/pull/3861).

To be able to initiate an OAuth 2.0 login flow to use a Matrix server, the client needs to know the location of the authentication server in use.

## Proposal

This introduces a new Client-Server API endpoint to discover the authentication server used by the homeserver.

### `GET /auth_issuer`

A request on this endpoint should return a JSON object with one field:

- _REQUIRED_ `issuer`: the OpenID Connect Provider that is trusted by the homeserver
Comment on lines +11 to +15
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what should homeservers that do not use OIDC do here? Return a 404? With a matrix error code, or not?

We should specify exactly what responses mean "I don't do OIDC", so that clients can distinguish servers that don't do OIDC from those that are unreachable or having a transient problem.

We also need to be mindful of backwards-compatibility, of course.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I haven't seen this addressed anywhere but why does the mapping need to be 1:1? Could a homeserver not trust and work with several OPs letting the user choose between them?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. It is not uncommon to see multiple choices:

  • Log in with GitHub
  • Log in with Google
  • Log in with ...


For example:

```http
GET /_matrix/client/v1/auth_issuer
Host: example.com
Accept: application/json
```

```http
HTTP/1.1 200 OK
Content-Type: application/json
```

```json
{
"issuer": "https://account.example.com/"
}
```

The Matrix client can then discover the OpenID Connect Provider configuration by using [OpenID Connect Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html).

```http
GET /.well-known/openid-configuration
Host: account.example.com
Accept: application/json
```

```http
HTTP/1.1 200 OK
Content-Type: application/json
```

```json
{
"issuer": "https://account.example.com/",
"authorization_endpoint": "https://account.example.com/oauth2/auth",
"token_endpoint": "https://account.example.com/oauth2/token",
"registration_endpoint": "https://account.example.com/oauth2/clients/register",
"end_session_endpoint": "https://account.example.com/oauth2/logout",
"jwks_uri": "https://account.example.com/oauth2/keys",
"response_types_supported": ["code"],
"grant_types_supported": ["authorization_code", "refresh_token"],
"response_mode_supported": ["query", "fragment"],
"...": "some fields omitted"
}
```

## Potential issues

Using a separate endpoint for discovery makes the request chain to initiate a login flow longer.
A full discovery flow would be as follows:

- `GET [domain]/.well-known/matrix/client` to discover the homeserver
- `GET [homeserver]/_matrix/client/v1/auth_issuer` to discover the issuer
- `GET [issuer]/.well-known/openid-configuration` to discover the OpenID Connect Provider configuration
- `POST [issuer client registration endpoint]` to register the OAuth 2.0 client
(see [MSC2966](https://github.com/matrix-org/matrix-spec-proposals/pull/2966))
- Redirect to `[issuer authorization endpoint]` to initiate the login flow

## Alternatives

The authentication server discovery could be done by other mechanisms.

### Discovery via [RFC8414](https://tools.ietf.org/html/rfc8414)

[RFC8414](https://tools.ietf.org/html/rfc8414): OAuth 2.0 Authorization Server Metadata is a standard similar to OpenID Connect Discovery.
The main differences is that the well-known endpoint is under `.well-known/oauth-authorization-server` and this standard is defined by the IETF and not the OpenID Foundation.

### Discovery via the well-known client discovery

A previous version of this proposal suggested using the well-known client discovery mechanism to discover the authentication server.
Clients already discover the homeserver when doing a server discovery via the well-known document.

A new `m.authentication` field is added to this document to support OpenID Connect Provider (OP) discovery.
It is an object containing two fields:

- REQUIRED `issuer` - the OpenID Connect Provider that is trusted by the homeserver
- OPTIONAL `account` - the URL where the user is able to access the account management capabilities of the OpenID Connect Provider

For example:

```http
GET /.well-known/matrix/client
Host: example.com
Accept: application/json
```

```http
HTTP/1.1 200 OK
Content-Type: application/json
```

```json
{
"m.homeserver": {
"base_url": "https://matrix-client.example.com"
},
"m.identity_server": {
"base_url": "https://identity.example.com"
},
"m.authentication": {
"issuer": "https://account.example.com",
"account": "https://account.example.com/myaccount"
}
}
```

This proposal, although implemented in some clients and in Synapse, has the downside of making the well-known discovery mandatory.
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.
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.

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.

### Discovery via the `m.login.oauth2` authentication method

The spec already defines a `m.login.oauth2` authentication method, but it was never implemented.
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.

### Discovery via WebFinger

OIDC already has a standard way to discover OP from an identifier: WebFinger.
This is already adopted by Mastodon, and might help solve logging in via 3PIDs like emails.

Sample exchange:

```
GET /.well-known/webfinger?
resource= mxid:@john:example.com &
rel= http://openid.net/specs/connect/1.0/issuer
Host: example.com
```

```json
{
"subject": "mxid:@john:matrix.org",
"links": [
{
"rel": "http://openid.net/specs/connect/1.0/issuer",
"href": "https://account.example.com"
}
]
}
```

The `mxid` scheme is a bit arbitrary here.
The parameters in the URL should be percent-encoded, this was left unencoded for clarity.

The benefits of this approach are that it is standard and decouples the authentication server from the Matrix server:
different authentication servers could be used by different accounts on the server.

The downsides of this approach are:

- the `.well-known` resource is dynamic, which can be harder to host/delegate & might conflict with other services like Mastodon
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An alternative viewpoint is that it might mean you only need to setup a single endpoint to handle authentication for multiple services.

It is dynamic because you need to return the subject back in the response?

- this does not cover discovering the authentication server for user registration
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this left to outside the OIDC standards?


## Security considerations

None relevant.

## Unstable prefix

While this MSC is not in a released version of the specification,
clients should use the `org.matrix.msc2965` unstable prefix for the endpoint,
e.g. `GET /_matrix/client/unstable/org.matrix.msc2965/auth_issuer`.