Compare commits

...

12 commits

Author SHA1 Message Date
Hugh Nimmo-Smith 325e8457f0
Merge 6f39b946fd into 6a001cccb0 2026-03-10 17:55:06 +00:00
Hugh Nimmo-Smith 6a001cccb0
Spec for MSC4335: M_USER_LIMIT_EXCEEDED error code (#2315)
Signed-off-by: Hugh Nimmo-Smith hughns@element.io
2026-03-10 17:53:14 +00:00
Guzio 0b5db68242
clarification: Correct wording in appservice docs (#2330)
Some checks failed
Spec / 🔎 Validate OpenAPI specifications (push) Has been cancelled
Spec / 🔎 Check Event schema examples (push) Has been cancelled
Spec / 🔎 Check OpenAPI definitions examples (push) Has been cancelled
Spec / 🔎 Check JSON Schemas inline examples (push) Has been cancelled
Spec / ⚙️ Calculate baseURL for later jobs (push) Has been cancelled
Spec / 📢 Run towncrier for changelog (push) Has been cancelled
Spell Check / Spell Check with Typos (push) Has been cancelled
Spec / 🐍 Build OpenAPI definitions (push) Has been cancelled
Spec / 📖 Build the spec (push) Has been cancelled
Spec / 🔎 Validate generated HTML (push) Has been cancelled
Spec / 📖 Build the historical backup spec (push) Has been cancelled
Spec / Create release (push) Has been cancelled
2026-03-06 19:21:02 +02:00
Hugh Nimmo-Smith 6f39b946fd Address review feedback 2026-03-04 10:37:56 +00:00
Hugh Nimmo-Smith 10065e8fb7
Update content/client-server-api/_index.md
Co-authored-by: Kévin Commaille <76261501+zecakeh@users.noreply.github.com>
2026-03-04 10:30:56 +00:00
Hugh Nimmo-Smith 19e6fd680b
Update data/api/client-server/oauth_server_metadata.yaml 2026-03-04 10:10:01 +00:00
Hugh Nimmo-Smith 3b2f11bd7a Iterate 2026-03-04 10:08:49 +00:00
Hugh Nimmo-Smith 4ceec843a9 Merge branch 'msc4341' of https://github.com/hughns/matrix-spec into msc4341 2026-02-27 10:46:43 +00:00
Hugh Nimmo-Smith 68732e76cf Add context about use on desktop applications 2026-02-27 10:46:41 +00:00
Hugh Nimmo-Smith 501a970202
verification_uri_complete clarification
Co-authored-by: Quentin Gliech <quenting@element.io>
2026-02-27 10:24:21 +00:00
Hugh Nimmo-Smith 9c94ec9f4a Don't use TV as an example 2026-02-24 09:15:07 +00:00
Hugh Nimmo-Smith 43d7518c3a MSC4341 2026-02-23 17:27:55 +00:00
6 changed files with 250 additions and 22 deletions

View file

@ -0,0 +1 @@
Fix various typos throughout the specification.

View file

@ -0,0 +1 @@
Add `M_USER_LIMIT_EXCEEDED` common error code, as per [MSC4335](https://github.com/matrix-org/matrix-spec-proposals/pull/4335).

View file

@ -0,0 +1 @@
Add the OAuth 2.0 Device Authorization Grant (RFC 8628) as a supported grant type, as per [MSC4341](https://github.com/matrix-org/matrix-spec-proposals/pull/4341).

View file

@ -84,7 +84,7 @@ For the `users` namespace, application services can only register interest in
homeserver). Events affecting users on other homeservers are not sent to an application
service, even if the user happens to match the one of the `users` namespaces (unless,
of course, the event affects a room that the application service is interested in
for another room - for example, because there is another user in the room that the
for another reason - for example, because there is another user in the room that the
application service is interested in).
For the `rooms` and `aliases` namespaces, all events in a matching room will be

View file

@ -147,6 +147,37 @@ state (e.g.: sending messages, account data, etc) and not routes which
only read state (e.g.: [`/sync`](#get_matrixclientv3sync),
[`/user/{userId}/account_data/{type}`](#get_matrixclientv3useruseridaccount_datatype), etc).
`M_USER_LIMIT_EXCEEDED`
: {{% added-in v="1.18" %}} The request cannot be completed because the user has
exceeded (or the request would cause them to exceed) a limit associated with
their account. For example, a user may have reached their allocated storage
quota, reached a maximum number of allowed rooms, devices, or other
account-scoped resources, or exceeded usage limits for specific features.
: The error response MUST have an `info_uri` field (string), which is a URI
that the client can present to the user to provide more context on the
encountered limit and, if applicable, guidance on how to increase the limit.
The homeserver MAY return different values for `info_uri` depending on the type
of limit reached.
: The error response MAY include a `can_upgrade` field (boolean, default `false`).
If `true`, it indicates that the specific limit encountered can be increased,
for example by upgrading the user's account tier. If absent or `false`, the
limit is a hard limit that cannot be increased.
: The HTTP status code will depend on depend on the particular endpoint.
: Example response:
```json
{
"errcode": "M_USER_LIMIT_EXCEEDED",
"error": "You have exceeded your storage quota of 10GB",
"info_uri": "https://example.com/homeserver/about?limit_type=quota",
"can_upgrade": true
}
```
`M_UNKNOWN`
: An unknown error has occurred.
@ -523,7 +554,7 @@ endpoint.
With the OAuth 2.0 API, a client can obtain an access token by using one of the
[grant types](#grant-types) supported by the homeserver and authorizing the
proper [scope](#scope), as demonstrated in the [login flow](#login-flow). To
proper [scope](#scope), as demonstrated in the [login flows](#login-flows). To
invalidate the access token the client must use [token revocation](#token-revocation).
### Using access tokens
@ -1720,19 +1751,31 @@ authentication type.
1. [Discover the OAuth 2.0 server metadata](#server-metadata-discovery).
2. [Register the client with the homeserver](#client-registration).
3. [Obtain an access token](#login-flow) by authorizing a [scope](#scope) for the client with the [authorization code grant](#authorization-code-grant).
3. [Obtain an access token](#login-flows) by authorizing a [scope](#scope) for
the client with the [authorization code grant](#authorization-code-grant) or
[device authorization grant](#device-authorization-grant).
4. [Refresh the access token](#token-refresh-flow) with the [refresh token grant](#refresh-token-grant) when it expires.
5. [Revoke the tokens](#token-revocation) when the users wants to log out of the client.
#### Login flow
#### Login flows
Logging in with the OAuth 2.0 API should be done with the [authorization code
grant](#authorization-code-grant). In the context of the Matrix specification,
this means requesting a [scope](#scope) including full client-server API
read/write access and allocating a device ID.
Logging in and obtaining an access token with the OAuth 2.0 API should be done
using either the [authorization code grant](#authorization-code-grant) or
[device authorization grant](#device-authorization-grant). In the context of the
Matrix specification, this means requesting a [scope](#scope) including full
client-server API read/write access and allocating a device ID.
Once the client has retrieved the [server metadata](#server-metadata-discovery),
it needs to generate the following values:
##### Authorization code flow
This login flow uses the [authorization code grant](#authorization-code-grant)
and is suitable for clients where the following criteria are met:
- There is a web browser available for the user to complete authentication and
authorization.
- The client can receive the callback via a redirect from the web browser.
Once the client has retrieved the [server metadata](#server-metadata-discovery)
the client needs to generate the following values:
- `device_id`: a unique identifier for this device; see the
[`urn:matrix:client:device:<device_id>`](#device-id-allocation) scope token.
@ -1873,6 +1916,143 @@ Sample response:
Finally, the client can call the [`/whoami`](#get_matrixclientv3accountwhoami)
endpoint to get the user ID that owns the access token.
##### Device authorization flow
{{% added-in v="1.18" %}}
This flow uses the [device authorization grant](#device-authorization-grant) to
allow clients to obtain an access token without needing to directly interact
with a web browser. Instead, the user completes authorization on a web browser
that can be a separate device.
This is useful for devices with limited input
capabilities (such as CLI applications or embedded devices) or where the
redirect handling may be unreliable (such as a desktop applications).
Once the client has retrieved the [server metadata](#server-metadata-discovery)
the client needs to generate following value:
- `device_id`: a unique identifier for this device; see the
[`urn:matrix:client:device:<device_id>`](#device-id-allocation) scope token.
**Device authorization request**
The client sends a `application/x-www-form-urlencoded` encoded `POST` request to
the `device_authorization_endpoint` as defined in
[RFC 8628 section 3.1](https://datatracker.ietf.org/doc/html/rfc8628#section-3.1):
| Parameter | Value |
|-------------|----------------------------------------------------------------|
| `client_id` | The client ID returned from client registration. |
| `scope` | `urn:matrix:client:api:* urn:matrix:client:device:<device_id>` with the `device_id` generated previously. |
Sample device authorization request:
```
POST /oauth2/device HTTP/1.1
Host: account.example.com
Content-Type: application/x-www-form-urlencoded
client_id=s6BhdRkqt3&scope=urn%3Amatrix%3Aclient%3Aapi%3A%2A%20urn%3Amatrix%3Aclient%3Adevice%3AAABBBCCCDDD
```
**Device authorization response**
The server responds with a JSON object as defined in
[RFC 8628 section 3.2](https://datatracker.ietf.org/doc/html/rfc8628#section-3.2),
containing:
| Parameter | |
|------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------|
| `device_code` | The device verification code. |
| `user_code` | An end-user verification code. |
| `verification_uri` | The end-user verification URI on the authorization server. |
| `verification_uri_complete` | Optionally, the URI which doesn't require the user to manually type the `user_code`, designed for non-textual transmission. |
| `expires_in` | The lifetime in seconds of the `device_code` and `user_code`. |
| `interval` | The minimum number of seconds the client should wait between polling requests to the token endpoint. If omitted, clients should default to 5. |
It is RECOMMENDED that the server provides a `verification_uri_complete` such
that the user does not need to type in the `user_code`.
Sample response:
```json
{
"device_code": "GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS",
"user_code": "WDJB-MJHT",
"verification_uri": "https://account.example.com/link",
"verification_uri_complete": "https://account.example.com/link?user_code=WDJB-MJHT",
"expires_in": 1800,
"interval": 5
}
```
**User interaction**
The client conveys the `verification_uri_complete` (and/or `verification_uri`
and `user_code`) to the user. How the client does this depends on the
specific device characteristics and use case. For example:
- A CLI application could display the `verification_uri` and `user_code` as text
for the user to type into their browser on another device.
- An embedded device with a screen could encode the `verification_uri_complete`
(with fallback to `verification_uri`) as a QR code for the user to scan with
their phone.
- A desktop application running on a platform that does not support callbacks
could launch the `verification_uri_complete` (with fallback to
`verification_uri`) in the system browser.
The user opens the verification URI in a web browser, which may be on another
device, and completes authentication and authorization.
**Token polling**
While the user is completing authorization, the client polls the
`token_endpoint` for the outcome, at intervals no shorter than the `interval`
value from the device authorization response.
The poll request is a `POST` to the `token_endpoint` with the following
parameters, encoded as `application/x-www-form-urlencoded` in the body:
| Parameter | Value |
|---------------|----------------------------------------------------------------|
| `grant_type` | `urn:ietf:params:oauth:grant-type:device_code` |
| `device_code` | The `device_code` from the device authorization response. |
| `client_id` | The client ID returned from client registration. |
Sample token polling request:
```
POST /oauth2/token HTTP/1.1
Host: account.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&device_code=GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS&client_id=s6BhdRkqt3
```
The server responds as defined in [RFC 8628 section
3.5](https://datatracker.ietf.org/doc/html/rfc8628#section-3.5):
- While authorization is pending, the server returns an `authorization_pending`
error (or `slow_down` if the client is polling too frequently).
- If authorization is denied, the server returns an `access_denied` error.
- If the device code expires, the server returns an `expired_token` error.
- On successful authorization, the server returns a JSON object containing the
access token, token type, expiration time, refresh token, and scope:
```json
{
"access_token": "2YotnFZFEjr1zCsicMWpAA",
"token_type": "Bearer",
"expires_in": 299,
"refresh_token": "tGz3JOkF0XG5Qx2TlKWIA",
"scope": "urn:matrix:client:api:* urn:matrix:client:device:AAABBBCCCDDD"
}
```
Finally, the client can call the [`/whoami`](#get_matrixclientv3accountwhoami)
endpoint to get the user ID that owns the access token.
#### Token refresh flow
Refreshing a token with the OAuth 2.0 API should be done with the [refresh token
@ -2203,6 +2383,7 @@ The client must also have obtained a `client_id` by [registering with the server
This specification supports the following grant types:
- [Authorization code grant](#authorization-code-grant)
- {{% added-in v="1.18" %}} [Device authorization grant](#device-authorization-grant)
- [Refresh token grant](#refresh-token-grant)
##### Authorization code grant
@ -2227,18 +2408,34 @@ To use this grant, homeservers and clients MUST:
Encoding Practices](https://openid.net/specs/oauth-v2-multiple-response-types-1_0.html)
for clients with an HTTPS redirect URI.
###### User registration
##### Device authorization grant
Clients can signal to the server that the user desires to register a new account
by initiating the authorization code grant with the `prompt=create` parameter
set in the authorization request as defined in [Initiating User Registration via
OpenID Connect 1.0](https://openid.net/specs/openid-connect-prompt-create-1_0.html).
{{% added-in v="1.18" %}}
Whether the homeserver supports this parameter is advertised by the
`prompt_values_supported` authorization server metadata.
As per [RFC 8628](https://datatracker.ietf.org/doc/html/rfc8628), the device
authorization grant lets clients on devices with limited input capabilities
obtain an access token by having the user complete authorization on a separate
device with a web browser.
Servers that support this parameter SHOULD show the account registration UI in
the browser.
This grant requires the client to know the following [authorization server
metadata](#server-metadata-discovery):
- `device_authorization_endpoint`
To use this grant, homeservers and clients MUST:
- Support the device authorization grant as per
[RFC 8628](https://datatracker.ietf.org/doc/html/rfc8628).
- Support the [refresh token grant](#refresh-token-grant).
As with the [authorization code grant](#authorization-code-grant), when
authorization is granted to a client, the homeserver MUST issue a refresh token
to the client in addition to the access token. The access token and refresh
token have the same lifetime constraints as described in the [refresh token
grant](#refresh-token-grant) section.
The full flow for using this grant is described in the
[device authorization flow](#device-authorization-flow).
##### Refresh token grant
@ -2345,6 +2542,22 @@ The server SHOULD return one of the following responses:
- For other errors, the server returns a `400 Bad Request` response with error
details
#### User registration
Clients can signal to the server that the user desires to register a new account
by initiating the [authorization code grant](#authorization-code-grant) with the `prompt=create` parameter
set in the authorization request as defined in [Initiating User Registration via
OpenID Connect 1.0](https://openid.net/specs/openid-connect-prompt-create-1_0.html).
Whether the homeserver supports this parameter is advertised by the
`prompt_values_supported` authorization server metadata.
Servers that support this parameter SHOULD show the account registration UI in
the browser.
The `prompt=create` parameter is not supported when using the [device
authorization grant](#device-authorization-grant).
#### Account management {id="oauth-20-account-management"}
{{% added-in v="1.18" %}}

View file

@ -67,8 +67,7 @@ paths:
type: string
format: uri
description: |-
URL of the token endpoint, necessary to use the authorization code grant and
the refresh token grant.
URL of the token endpoint, used by the grants.
revocation_endpoint:
type: string
format: uri
@ -101,6 +100,10 @@ paths:
This array MUST contain at least the `authorization_code` and `refresh_token`
values, for clients to be able to use the authorization code grant and refresh
token grant, respectively.
{{% added-in v="1.18" %}} It MAY also contain
`urn:ietf:params:oauth:grant-type:device_code` to indicate support for the
[device authorization grant](/client-server-api/#device-authorization-grant).
items:
type: string
description: A grant type that the server supports.
@ -165,6 +168,14 @@ paths:
- "org.matrix.account_deactivate"
- "org.matrix.cross_signing_reset"
description: An action that the account management URL supports.
device_authorization_endpoint:
x-addedInMatrixVersion: "1.18"
type: string
format: uri
description: |-
URL of the device authorization endpoint, as defined in
[RFC 8628](https://datatracker.ietf.org/doc/html/rfc8628), necessary to use
the [device authorization grant](/client-server-api/#device-authorization-grant).
required:
- issuer
- authorization_endpoint
@ -180,9 +191,10 @@ paths:
"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",
"device_authorization_endpoint": "https://account.example.com/oauth2/device",
"revocation_endpoint": "https://account.example.com/oauth2/revoke",
"response_types_supported": ["code"],
"grant_types_supported": ["authorization_code", "refresh_token"],
"grant_types_supported": ["authorization_code", "refresh_token", "urn:ietf:params:oauth:grant-type:device_code"],
"response_modes_supported": ["query", "fragment"],
"code_challenge_methods_supported": ["S256"],
"account_management_uri": "https://account.example.com/manage",