MSC2967: API scopes (#2967)
* API Scopes MSC * Proposed insufficient privilege response format * Remove realm as not required * Clarifications + update on latest device management proposal * Revised namespace structure + unstable prefixes * Revise prefix for device ID * Reference to MSC3861 + cleanup * Add scope for guest access and tidy up * No need for UIA scope * Update proposals/2967-api-scopes.md Co-authored-by: Patrick Cloke <clokep@users.noreply.github.com> * Clarification about encoding of device ID within URN scope * Rework MSC - Remove insufficient privilege response - Remove guest scopes - Reword some parts * Update proposals/2967-api-scopes.md Co-authored-by: Travis Ralston <travpc@gmail.com> * Reword as dbkr suggested * Reword how unstable subdivisions are used * Remove confusing sentence * Gather all the links at the bottom of the document * Tyding up, define exactly how device IDs are handled * Don't use a table for a single row * Typo Co-authored-by: David Baker <dbkr@users.noreply.github.com> * Fix math rendering * Fix the math * Minor rewording on device uniqueness Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * Simplify wording around the ASCII range Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * Typo Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * Scope vs scope token is confusing Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * Reword how the device ID is requested * Explain why we keep the device ID generation on the client * MSCXXXX is a better placeholder Co-authored-by: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> * The scope MUST have a device ID * Clarify that device IDs are still unique per user Co-authored-by: Patrick Cloke <clokep@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: David Baker <dbkr@users.noreply.github.com> Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Co-authored-by: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com>richvdh-patch-2
parent
d83a46e498
commit
b2ea1a7f9e
@ -0,0 +1,138 @@
|
||||
# MSC2967: API scopes
|
||||
|
||||
This proposal is part of the broader [MSC3861: Next-generation auth for Matrix, based on OAuth 2.0/OIDC][MSC3861].
|
||||
|
||||
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`
|
||||
|
||||
[MSC1597]: https://github.com/matrix-org/matrix-spec-proposals/pull/1597
|
||||
[MSC2964]: https://github.com/matrix-org/matrix-spec-proposals/pull/2964
|
||||
[MSC3861]: https://github.com/matrix-org/matrix-spec-proposals/pull/3861
|
||||
[RFC3986]: https://datatracker.ietf.org/doc/html/rfc3986
|
||||
[RFC6749]: https://datatracker.ietf.org/doc/html/rfc6749
|
||||
Loading…
Reference in New Issue