-
Notifications
You must be signed in to change notification settings - Fork 412
MSC2967: API scopes #2967
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
MSC2967: API scopes #2967
Changes from 21 commits
a2e9656
544d75b
d49f2d8
23c7638
b609c2b
f07b466
1ce049e
5c57507
5afb697
8ec2d7c
8539ab2
0666b24
f65aef3
660946a
4dd433f
79845f5
49550fe
14b962c
58f2398
e7531fa
acc8e91
1304203
6623b96
1ddd733
a33d1e3
0800ea6
a7bb99c
abbae1e
082625d
089a789
858b7be
c9f8690
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
# 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. | ||
|
||
A 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 MSCXXX wants to introduce the `urn:matrix:client:foo` scope, it could use `urn:matrix:client:com.example.mscXXXX.foo` during development. | ||
sandhose marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm. I'm surprised that the specifics of the Device ID handling scope is included in this MSC, which otherwise is the framework for defining scopes in general. Is this because this scope is compulsory for OIDC to work? If so, we should say so. If not, at the least, we should say that the scope is defined here as a concrete example of how scopes would work... or failing that, split it into a separate MSC. If it /is/ primarily intended example of the framework, it just feels a bit weird to also be speccing specific behaviour at the same time - wouldn't it be better to give a fake example, and then clearly separate the Device ID management proposal somehow? I have a feeling i've missed something here that explains why this isn't completely out of place :D There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At a high level, this MSC defines two things:
I have to include somewhere that it is now always the responsibility of the client to allocate a device, but I'm unsure where the right place for this is? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it's fine here imho |
||
|
||
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 client by asking for its scope on login. | ||
|
||
The client can then bind the device ID to the grant by requesting a scope comprising of a [RFC3986] URN in the format: | ||
sandhose marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
| Scope | Purpose | Implementation notes | | ||
| - | - | - | | ||
| `urn:matrix:client:device:<device ID>` | bind the given device ID to the grant/access token | The homeserver must only grant exactly one device scope for a token. | | ||
|
||
The device ID scope MUST be present *at most* once in the scope. | ||
sandhose marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
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 be reasonably unique. | ||
sandhose marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
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 used characters allowed by the OAuth 2.0 scope definition in [RFC6749] section 3.3. | ||
It is defined as the following ASCII ranges: `%x21 / %x23-5B / %x5D-7E` | ||
Which is equivalent to: | ||
sandhose marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
- 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 | ||
|
||
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}} \\ | ||
sandhose marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
P \approx 0.00318 | ||
$$ | ||
sandhose marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
This does also restrict the possible alphabet of device IDs, which was not restricted before. | ||
|
||
## 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 |
Uh oh!
There was an error while loading. Please reload this page.