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

MSC2966: Usage of OAuth 2.0 Dynamic Client Registration in Matrix #2966

Open
wants to merge 15 commits into
base: main
Choose a base branch
from

Conversation

sandhose
Copy link
Member

@sandhose sandhose commented Jan 14, 2021

@turt2live turt2live changed the title MSC2966: [WIP] Usage of OAuth 2.0 Dynamic Client Registration in Matrix [WIP] MSC2966: Usage of OAuth 2.0 Dynamic Client Registration in Matrix Jan 14, 2021
@turt2live turt2live marked this pull request as draft January 14, 2021 17:28
@turt2live turt2live added kind:feature MSC for not-core and not-maintenance stuff proposal A matrix spec change proposal labels Jan 14, 2021
| `contacts` | Array of strings representing ways to contact people responsible for this client, typically email addresses | Required | No |
| `tos_uri` | URL that points to a human-readable terms of service document for the client | Required | Yes |
| `policy_uri` | URL that points to a human-readable policy document for the client | Required | Yes |
| `redirect_uris` | Array of redirection URIs for use in redirect-based flows | Required with the `authorization_code` grant ype | No |
Copy link
Member

Choose a reason for hiding this comment

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

something I don't really understand here (or about OAuth2 dynamic registration in general):

What is to stop me, as an attacker, registering a "client" with branding (name, logo, etc) that looks like a trusted client, but with a redirect_uri that points to a site I control?

I then send the user a link which will take them through the login flow, and redirect back to my site. Assuming I can persaude the user to open the link, I can then harvest the authorization code and thence gain access to their account?

Copy link
Member Author

Choose a reason for hiding this comment

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

In this case the auth server would at least prompt for explicit consent as it would be considered as a separate client from the legitimate one.

One thing that could be enforced would be to have the different URIs (at least redirect_uris and client_uri) to be on the same origin. Quoting from RFC 7591 sec. 5:

In a situation where the authorization server is supporting open client registration, it must be extremely careful with any URL provided by the client that will be displayed to the user (e.g., logo_uri, tos_uri, client_uri, and policy_uri). For instance, a rogue client could specify a registration request with a reference to a drive-by download in the policy_uri, enticing the user to click on it during the authorization. The authorization server SHOULD check to see if the logo_uri, tos_uri, client_uri, and policy_uri have the same host and scheme as the those defined in the array of redirect_uris and that all of these URIs resolve to valid web pages.

Copy link
Member

Choose a reason for hiding this comment

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

In this case the auth server would at least prompt for explicit consent as it would be considered as a separate client from the legitimate one.

of course; but how is the user meant to tell that they are now being asked for consent to a phishing app?

One thing that could be enforced would be to have the different URIs (at least redirect_uris and client_uri) to be on the same origin.

Wouldn't this preclude the use of desktop clients, which often register custom URI schemes to get the auth code back from a browser to the client?

Copy link
Member

Choose a reason for hiding this comment

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

As discussed elsewhere: it turns out that on Windows and MacOS at least, desktop apps can register for parts of the https:// namespace. So that only really leaves Linux where you can only register for an entire URI scheme (via an x-scheme-handler/... mimetype).

So it should be possible to create a system which makes this look user-friendly for everyone except Linux users, who presumably are a bit more comfortable with obscure URIs anyway.

Copy link
Contributor

Choose a reason for hiding this comment

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

My client generates a localhost address on demand during SSO currently. This MSC makes it sound like I need to switch to a fixed schema instead, which means running multiple instances of my software in parallel will become much harder. How would I solve having 2 separate instances of my app running and I want to only sign into one of them?

Copy link
Member Author

@sandhose sandhose Jan 16, 2025

Choose a reason for hiding this comment

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

My client generates a localhost address on demand during SSO currently. This MSC makes it sound like I need to switch to a fixed schema instead, which means running multiple instances of my software in parallel will become much harder. How would I solve having 2 separate instances of my app running and I want to only sign into one of them?

This is covered by the "Native clients" part of this spec: apps can register localhost without port, and the server must accept a dynamic port during the authorisation

https://github.com/sandhose/matrix-spec-proposals/blob/msc/sandhose/oauth2-dynamic-registration/proposals/2966-oauth2-dynamic-registration.md#native-clients

## Proposal

If a Matrix server wants to be used by any third-party client, its authentication server must allow dynamic registration of OAuth 2.0 clients.
The client registration endpoint is advertised in the OIDC discovery document and can be used as per [RFC 7591 sec. 3](https://tools.ietf.org/html/rfc7591#section-3).
Copy link
Member

Choose a reason for hiding this comment

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

I'm sure this is obvious if you're familiar with OAuth2, but for context I'd find it really helpful if you could clarify when a client would register itself with a given server in the context of Matrix. Presumably, whenever the user chooses a homeserver to log into? (Is the client expected to remember a list of homeservers it has registered against?)

@turt2live turt2live added the needs-implementation This MSC does not have a qualifying implementation for the SCT to review. The MSC cannot enter FCP. label Jun 8, 2021
proposals/2966-oauth2-dynamic-registration.md Outdated Show resolved Hide resolved
| `contacts` | Array of strings representing ways to contact people responsible for this client, typically email addresses | Required | No |
| `tos_uri` | URL that points to a human-readable terms of service document for the client | Required | Yes |
| `policy_uri` | URL that points to a human-readable policy document for the client | Required | Yes |
| `redirect_uris` | Array of redirection URIs for use in redirect-based flows | Required with the `authorization_code` grant ype | No |
Copy link
Contributor

Choose a reason for hiding this comment

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

My client generates a localhost address on demand during SSO currently. This MSC makes it sound like I need to switch to a fixed schema instead, which means running multiple instances of my software in parallel will become much harder. How would I solve having 2 separate instances of my app running and I want to only sign into one of them?

proposals/2966-oauth2-dynamic-registration.md Outdated Show resolved Hide resolved
If a client changes its `redirect_uris`, should the old ones be considered for a period of time?
If multiple versions of the same client coexist at the same time, should older versions of the software be able to override the metadata of the newer version?

If an authorization server allows unsigned clients, the number of client registration might explode exponentially.
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this a problem?

Copy link
Contributor

@MTRNord MTRNord Feb 24, 2023

Choose a reason for hiding this comment

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

I don't think this should be problem, imho. This is the whole goal of an open ecosystem like matrix. Anyone at any time can build a client and use it. You are not vendor bound. Allowing this to be restricted imho goes against the core idea of an open ecosystem which matrix tries to be.

Edit also see: #3861 (comment)

@turt2live turt2live added the matrix-2.0 Required for Matrix 2.0 label Mar 3, 2023
@sandhose sandhose closed this Sep 3, 2024
@sandhose sandhose deleted the msc/sandhose/oauth2-dynamic-registration branch September 3, 2024 10:23
@sandhose sandhose restored the msc/sandhose/oauth2-dynamic-registration branch September 3, 2024 10:24
@sandhose sandhose reopened this Sep 3, 2024
@sandhose sandhose changed the base branch from old_master to main September 3, 2024 10:25
 - makes some metadata optional
 - better explain how each metadata field is used
 - better explain what the restrictions on redirect_uris are
 - remove the signed metadata part
 - mention the client metadata JSON document alternative
@sandhose sandhose changed the title [WIP] MSC2966: Usage of OAuth 2.0 Dynamic Client Registration in Matrix MSC2966: Usage of OAuth 2.0 Dynamic Client Registration in Matrix Sep 13, 2024
@sandhose sandhose marked this pull request as ready for review September 13, 2024 15:41
proposals/2966-oauth2-dynamic-registration.md Outdated Show resolved Hide resolved
Comment on lines 36 to 40
It is recommended that the `client_uri` is a web page that provides information about the client.
This page should be able to be accessed without requiring authentication.

This URI is a common base for all the other URIs in the metadata: those must be either on the same host or on a subdomain of the host of the `client_uri`.
For example, if the `client_uri` is `https://example.com/`, then one of the `redirect_uris` can be `https://example.com/callback` or `https://app.example.com/callback`, but not `https://app.com/callback`.

Choose a reason for hiding this comment

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

For a self-hostable web client like Element web, the recommended uri would be element.io but if I host an instance of it on example.com, I wouldn't be able to set a proper redirect_uri with the recommended uri.
How important is this requirement really? What about informing the user about the differing host in the redirect uri during authorization?
Of course clients could also bundle in their landing pages and policies or set up a redirect to work around the issue.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think this is a feature, not a bug. "element.mycompany.corp" is "Element Web hosted by MyCompany", as there are no assurance that it's an untempered Element Web hosted by Element the company

Copy link
Member

Choose a reason for hiding this comment

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

Not for the MSC text, but Element Web could add an /about route that it ships for this purpose.

proposals/2966-oauth2-dynamic-registration.md Outdated Show resolved Hide resolved
proposals/2966-oauth2-dynamic-registration.md Outdated Show resolved Hide resolved
@sandhose sandhose force-pushed the msc/sandhose/oauth2-dynamic-registration branch from 85d1958 to 0e2f0f1 Compare January 17, 2025 09:14
@turt2live turt2live added kind:core MSC which is critical to the protocol's success implementation-needs-checking The MSC has an implementation, but the SCT has not yet checked it. and removed kind:feature MSC for not-core and not-maintenance stuff needs-implementation This MSC does not have a qualifying implementation for the SCT to review. The MSC cannot enter FCP. labels Jan 18, 2025
Copy link
Member

@turt2live turt2live left a comment

Choose a reason for hiding this comment

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

overall this looks good, though I think it needs implementations to be able to move to FCP. I'll document those requirements in a separate review.

proposals/2966-oauth2-dynamic-registration.md Outdated Show resolved Hide resolved
Comment on lines 36 to 40
It is recommended that the `client_uri` is a web page that provides information about the client.
This page should be able to be accessed without requiring authentication.

This URI is a common base for all the other URIs in the metadata: those must be either on the same host or on a subdomain of the host of the `client_uri`.
For example, if the `client_uri` is `https://example.com/`, then one of the `redirect_uris` can be `https://example.com/callback` or `https://app.example.com/callback`, but not `https://app.com/callback`.
Copy link
Member

Choose a reason for hiding this comment

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

Not for the MSC text, but Element Web could add an /about route that it ships for this purpose.

Comment on lines +48 to +49
- `tos_uri`: URL that points to a human-readable terms of service document for the client
- `policy_uri`: URL that points to a human-readable policy document for the client
Copy link
Member

Choose a reason for hiding this comment

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

blocking: what is the difference between policy and terms of service?

Copy link
Member Author

Choose a reason for hiding this comment

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

Those are all defined in RFC 7591:

tos_uri
      URL string that points to a human-readable terms of service
      document for the client that describes a contractual relationship
      between the end-user and the client that the end-user accepts when
      authorizing the client.  The authorization server SHOULD display
      this URL to the end-user if it is provided.  The value of this
      field MUST point to a valid web page.  The value of this field MAY
      be internationalized, as described in [Section 2.2](https://www.rfc-editor.org/rfc/rfc7591.html#section-2.2).

   policy_uri
      URL string that points to a human-readable privacy policy document
      that describes how the deployment organization collects, uses,
      retains, and discloses personal data.  The authorization server
      SHOULD display this URL to the end-user if it is provided.  The
      value of this field MUST point to a valid web page.  The value of
      this field MAY be internationalized, as described in [Section 2.2](https://www.rfc-editor.org/rfc/rfc7591.html#section-2.2).

Compared to the RFC, this is adding requirements on them (coherence with the client_uri), are suggestions for clients to advertise them and suggestions to servers to display them if provided

proposals/2966-oauth2-dynamic-registration.md Outdated Show resolved Hide resolved
proposals/2966-oauth2-dynamic-registration.md Outdated Show resolved Hide resolved

**Note**: in this example, the server has not registered the locale-specific values for `client_name`, `tos_uri`, and `policy_uri`, which is why they are not present in the response. The server also does not support the `urn:ietf:params:oauth:grant-type:token-exchange` grant type, which is why it is not present in the response.

The client must store the `client_id` for future use.
Copy link
Member

Choose a reason for hiding this comment

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

Mentioned in the umbrella MSC: does the client need to remember this over multiple browsers/sessions, or just while the single user session logs in?

Copy link
Member Author

Choose a reason for hiding this comment

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

Clarified in c7e55ec, plus mentioned in "Potential issues"

Copy link
Member

Choose a reason for hiding this comment

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

Implementation requirements:

  • Client using web flow
  • Client using native flow
  • Server supporting both flows (may be two different servers)

Copy link
Member Author

Choose a reason for hiding this comment

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

Known working clients with the web flow:

  • Element Web

Known working clients with the native flow:

  • Element Desktop
  • Element X iOS
  • Element X Android

Server supporting both:

  • Synapse with Matrix Authentication Service
  • Dendrite with Matrix Authentication Service (PR)

@turt2live turt2live added needs-implementation This MSC does not have a qualifying implementation for the SCT to review. The MSC cannot enter FCP. and removed implementation-needs-checking The MSC has an implementation, but the SCT has not yet checked it. labels Jan 22, 2025
Comment on lines +11 to +15
This proposal requires the client to know the following authorization server metadata about the homeserver:

- `registration_endpoint`: the URL where the client is able to register itself.

The discovery of the above metadata is out of scope for this MSC and is currently covered by [MSC2965](https://github.com/matrix-org/matrix-doc/pull/2965).
Copy link
Member

Choose a reason for hiding this comment

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

presumably if there's no registration_endpoint, the server doesn't support dynamic client registration. That should be documented in the MSC as a thing clients should expect.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm not sure how to handle this. Basically there are two possibilities:

  • make client registration mandatory. That would be aligned with the 'openness' of Matrix, as you should be able to use any client with any compliant server. Not supporting this would then mean the server not spec-compliant?
  • make it optional and explain here what this means. This makes it clearer in the spec that its possible to use this in 'closed' ecosystems, where servers impose which client is allowed to use it

@sandhose sandhose requested a review from turt2live January 22, 2025 14:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind:core MSC which is critical to the protocol's success matrix-2.0 Required for Matrix 2.0 needs-implementation This MSC does not have a qualifying implementation for the SCT to review. The MSC cannot enter FCP. proposal A matrix spec change proposal
Projects
Status: Proposed for FCP readiness
Development

Successfully merging this pull request may close these issues.

8 participants