Skip to content

Latest commit

 

History

History
138 lines (81 loc) · 6.93 KB

2967-api-scopes.md

File metadata and controls

138 lines (81 loc) · 6.93 KB

MSC2967: API scopes

This proposal is part of the broader MSC3861: Next-generation auth for Matrix, based on OAuth 2.0/OIDC.

When a user signs in with a Matrix client, it currently gives the client full access to their Matrix account.

This proposal introduces access scopes to allow restricting client access to only part(s) of the Matrix client API.

Proposal

MSC2964 introduces the usage of the OAuth 2.0 authorization code grant to authenticate against a Matrix homeserver.

An OAuth 2.0 grant has a scope associated to it which provides a framework for obtaining user consent.

The framework encourages the practise of obtaining additional use consent when a client asks for a new scope that was not granted previously.

This MSC does not attempt to define all the scopes necessary to cover all Matrix APIs and use cases, but proposes the structure of a namespace and a few scopes to cover existing use cases.

Scope format

All scopes related to Matrix should start with urn:matrix: and use the : delimiter for further sub-division.

Scopes related to mapping of Client-Server API access levels should start with urn:matrix:client:.

For future MSCs that build on this namespace, unstable subdivisions should be used whilst in development.

For example, if MSCXXXX wants to introduce the urn:matrix:client:foo scope, it could use urn:matrix:client:com.example.mscXXXX.foo during development. If it needs to introduce multiple scopes, like urn:matrix:client:foo and urn:matrix:client:bar, it could use urn:matrix:client:com.example.mscXXXX:foo and urn:matrix:client:com.example.mscXXXX:bar.

Allocated scopes

Full API read/write access

To support the existing semantic of granting full access to the Matrix C-S API the following scope is assigned:

Scope Purpose
urn:matrix:client:api:* Grants full access to the Client-Server API

In the future, a client would request more specific actions when required. e.g. something like urn:matrix:client:api:read:*

Device ID handling

Presently a device ID is typically generated by the homeserver and is associated with a specific series of access tokens.

This MSC proposes that the Matrix client is responsible for generating/allocating a device ID. A client can create a new device ID by generating a random string and asking for its associated scope on login. A client can adopt and rehydrate an existing device ID by asking for its associated scope on login.

The client must then add the requested device ID to the grant by including following token in the requested scope: urn:matrix:client:device:<device ID>, where <device ID> is the requested device ID.

There MUST be exactly one urn:matrix:client:device:<device ID> token in the requested scope.

When generating a new device ID, the client SHOULD generate a random string with enough entropy. It SHOULD only use characters from the unreserved character list defined by RFC3986:

unreserved = a-z / A-Z / 0-9 / "-" / "." / "_" / "~"

Using this alphabet, a 10 character string is enough to stand a sufficient chance of being unique per user. The homeserver MAY reject a request for a device ID that is not long enough or contains characters outside the unreserved list.

In any case it MUST only use characters allowed by the OAuth 2.0 scope definition in RFC6749 section 3.3, which is defined as the following ASCII ranges: %x21 / %x23-5B / %x5D-7E, i.e:

  • alphanumeric characters (A-Z, a-z, 0-9)
  • the following characters: ! # $ % & ' ( ) * + , - . / : ; < = > ? @ [ ] ^ _ \ { | } ~`

Future scopes

Exact scopes for the whole API are intentionally not specified in this MSC.

It is envisioned that the namespace could be further partitioned to support use cases such as read only, write only, limited to one or more rooms etc.

Some thoughts/ideas for possible scopes are:

  • urn:matrix:client:api:<permission> or urn:matrix:client:api:<permission>:* - grant limited access to the client API in all rooms. Permissions could be read, write, delete, append.
  • urn:matrix:client:api:read:<resource> - read-only access to the client API for just the named resource. e.g. urn:matrix:client:api:read:#matrix-auth

New MSCs should be created for proposing and discussing such new scopes.

Potential issues

Device ID collision

The Device ID handling involves a change in where device IDs are generated. Because the device ID is now generated by the client, it is possible to have a device ID collision.

Requiring enough entropy on the device ID ensures that the device ID is unique. With a 66 character alphabet and a 10 character device ID, the probability of a collision between 100 million devices is around 0.3%:

$$N = 66^{10}$$ $$K = 10^{8}$$ $$P \approx 1 - e^{-\frac{K^2}{2N}}$$ $$P \approx 0.00318$$

This does also restrict the possible alphabet of device IDs, which was not restricted before.

Generating the device ID on the client

This proposal effectively changes where the device ID is generated, from "most of the time on the server" to "every time on the client."

This doesn't introduce a new mechanism, as clients could already select a device ID instead of letting the server generate one.

One of the original motivation for this change was to adopt existing OAuth 2.0 mechanisms as much as possible. This meant not introducing Matrix-specific parameters (hence encoding the device ID in the scope) and not relying on non-standard server behaviour (hence the device ID being generated on the client).

In retrospect, because the whole proposal requires a Matrix-specific implementation anyway, compatibility with existing off-the-shelf OAuth 2.0 server implementations isn't a goal anymore: we could adopt a Matrix-specific parameter to specify the device ID, and let the server generate it if it's not provided.

As generating the device ID on the client hasn't been a problem in practice, this proposal kept it like that to avoid the cost of aligning the implementations.

Alternatives

Scopes

Scope could also have an URL format, e.g. https://matrix.org/api/*/read.

The URL prefix could either be static (https://matrix.org) or dependant on the homeserver (https://matrix.example.com). In both cases, the URL could be confused with API endpoints and in the second case it would require discovery to know what scopes to ask.

The actual namespace prefix and subdivisions are open to debate.

Security considerations

As we are just representing existing access models there shouldn't be anything special.

Unstable prefix

While this feature is in development the following unstable scope prefixes should be used:

  • urn:matrix:client --> urn:matrix:org.matrix.msc2967.client