mirror of
https://github.com/matrix-org/matrix-spec
synced 2026-04-27 21:04:09 +02:00
Compare commits
22 commits
99675efc3f
...
a744513e93
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a744513e93 | ||
|
|
7d2de48cb4 | ||
|
|
fb4a0d8f66 | ||
|
|
4c87e0e745 | ||
|
|
3e1e9fa8df | ||
|
|
c8380d9552 | ||
|
|
3877598b1e | ||
|
|
0e280ed014 | ||
|
|
625ed5c599 | ||
|
|
484a777572 | ||
|
|
6edb6ba1cd | ||
|
|
40065811a1 | ||
|
|
1c06ed9cf7 | ||
|
|
6353b46add | ||
|
|
0e05e45d84 | ||
|
|
b278a4e0ec | ||
|
|
ccd9e50eb1 | ||
|
|
e4740e36e8 | ||
|
|
9244c84a32 | ||
|
|
979264e923 | ||
|
|
51ccbbd240 | ||
|
|
a2a9a02efa |
5
.github/workflows/main.yml
vendored
5
.github/workflows/main.yml
vendored
|
|
@ -155,6 +155,11 @@ jobs:
|
|||
--api server-server \
|
||||
-r "$RELEASE" \
|
||||
-o spec/server-server-api/api.json
|
||||
scripts/dump-openapi.py \
|
||||
--base-url "https://spec.matrix.org${{ needs.calculate-baseurl.outputs.baseURL }}" \
|
||||
--api identity \
|
||||
-r "$RELEASE" \
|
||||
-o spec/identity-service-api/api.json
|
||||
tar -czf openapi.tar.gz spec
|
||||
- name: "📤 Artifact upload"
|
||||
uses: actions/upload-artifact@v4
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
Correct null value handling for the AS Registration's `url` property.
|
||||
|
|
@ -0,0 +1 @@
|
|||
Minor fixes to JSON schemas.
|
||||
|
|
@ -1 +0,0 @@
|
|||
Clarify behaviour when the `topic` key of a `m.room.topic` event is absent, null, or empty.
|
||||
|
|
@ -1 +0,0 @@
|
|||
Fix the example of the `GET /sync` endpoint and the `m.room.member` example used in several places.
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
Clarify the format of third-party invites, including the fact that identity
|
||||
server public keys can be encoded using standard or URL-safe base64.
|
||||
|
|
@ -1 +0,0 @@
|
|||
Add `m.topic` content block to enable rich text in `m.room.topic` events as per [MSC3765](https://github.com/matrix-org/matrix-spec-proposals/pull/3765).
|
||||
|
|
@ -1 +0,0 @@
|
|||
"Public" rooms in profile look-ups are defined through their join rule and history visibility.
|
||||
|
|
@ -1 +0,0 @@
|
|||
"Public" rooms in user directory queries are defined through their join rule and history visibility.
|
||||
|
|
@ -1 +0,0 @@
|
|||
Rooms published in `/publicRooms` don't necessarily have `public` join rules or `world_readable` history visibility.
|
||||
|
|
@ -1 +0,0 @@
|
|||
"Public" rooms with respect to call invites are defined through their join rule.
|
||||
|
|
@ -1 +0,0 @@
|
|||
"Public" rooms have no specific meaning with respect to moderation policy lists.
|
||||
|
|
@ -1 +0,0 @@
|
|||
"Public" rooms with respect to presence are defined through their join rule.
|
||||
|
|
@ -1 +0,0 @@
|
|||
Spaces are subject to the same access mechanisms as rooms.
|
||||
|
|
@ -1 +0,0 @@
|
|||
Include device keys with Olm-encrypted events as per [MSC4147](https://github.com/matrix-org/matrix-spec-proposals/pull/4147).
|
||||
|
|
@ -1 +0,0 @@
|
|||
Add `/_matrix/client/v1/room_summary/{roomIdOrAlias}` and extend `/_matrix/client/v1/rooms/{roomId}/hierarchy` with the new optional properties `allowed_room_ids`, `encryption` and `room_version` as per [MSC3266](https://github.com/matrix-org/matrix-spec-proposals/pull/3266).
|
||||
|
|
@ -1 +0,0 @@
|
|||
Clarify that Well-Known URIs are available on the server name's hostname. Contributed by @HarHarLinks.
|
||||
|
|
@ -1 +0,0 @@
|
|||
Add the OAuth 2.0 based authentication API, as per [MSC3861](https://github.com/matrix-org/matrix-spec-proposals/pull/3861) and its sub-proposals.
|
||||
|
|
@ -1 +0,0 @@
|
|||
Fix typo: as->has.
|
||||
|
|
@ -1 +0,0 @@
|
|||
Add `/_matrix/client/v1/room_summary/{roomIdOrAlias}` and extend `/_matrix/client/v1/rooms/{roomId}/hierarchy` with the new optional properties `allowed_room_ids`, `encryption` and `room_version` as per [MSC3266](https://github.com/matrix-org/matrix-spec-proposals/pull/3266).
|
||||
|
|
@ -0,0 +1 @@
|
|||
Clarify that `format` is required if `formatted_body` is specified.
|
||||
|
|
@ -0,0 +1 @@
|
|||
The `latest_event` in an aggregated set of thread events uses the same format as the event itself.
|
||||
1
changelogs/client_server/newsfragments/2175.feature
Normal file
1
changelogs/client_server/newsfragments/2175.feature
Normal file
|
|
@ -0,0 +1 @@
|
|||
Add `format` query parameter to `GET /state/{eventType}/{stateKey}` to allow fetching metadata of a specific state event.
|
||||
|
|
@ -0,0 +1 @@
|
|||
Fix various typos throughout the specification.
|
||||
|
|
@ -0,0 +1 @@
|
|||
Minor fixes to JSON schemas.
|
||||
|
|
@ -1 +0,0 @@
|
|||
Clarify that public keys can be encoded using standard or URL-safe base64.
|
||||
|
|
@ -1 +0,0 @@
|
|||
Adjust margins in rendered endpoints.
|
||||
|
|
@ -1 +0,0 @@
|
|||
Replace Hugo shortcodes in OpenAPI output.
|
||||
|
|
@ -1 +0,0 @@
|
|||
Add [well-known funding manifest urls](https://floss.fund/funding-manifest/) to spec to authorise https://matrix.org/funding.json. Contributed by @HarHarLinks.
|
||||
|
|
@ -1 +0,0 @@
|
|||
Fix the historical info box when generating the historical spec in CI.
|
||||
|
|
@ -1 +0,0 @@
|
|||
Update the header navigation menu with links to modern matrix.org. Contributed by @HarHarLinks.
|
||||
1
changelogs/internal/newsfragments/2157.feature
Normal file
1
changelogs/internal/newsfragments/2157.feature
Normal file
|
|
@ -0,0 +1 @@
|
|||
Add "placeholder MSC" process definition.
|
||||
1
changelogs/internal/newsfragments/2172.clarification
Normal file
1
changelogs/internal/newsfragments/2172.clarification
Normal file
|
|
@ -0,0 +1 @@
|
|||
GitHub actions are now building the OpenAPI `spec/identity-service-api/api.json` file.
|
||||
|
|
@ -1 +0,0 @@
|
|||
Add a note to the invite endpoints that invites to local users may be received twice over federation if the homeserver is already in the room.
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
Clarify the format of third-party invites, including the fact that identity
|
||||
server public keys can be encoded using standard or URL-safe base64.
|
||||
|
|
@ -1 +0,0 @@
|
|||
Add `m.topic` content block to enable rich text in `m.room.topic` events as per [MSC3765](https://github.com/matrix-org/matrix-spec-proposals/pull/3765).
|
||||
|
|
@ -1 +0,0 @@
|
|||
Clarify that auth event of `content.join_authorised_via_users_server` is only necessary for `m.room.member` with a `membership` of `join`.
|
||||
|
|
@ -1 +0,0 @@
|
|||
Rooms published in `/publicRooms` don't necessarily have `public` join rules or `world_readable` history visibility.
|
||||
|
|
@ -1 +0,0 @@
|
|||
Extend `/_matrix/federation/v1/hierarchy/{roomId}` with the new optional properties `encryption` and `room_version` as per [MSC3266](https://github.com/matrix-org/matrix-spec-proposals/pull/3266).
|
||||
|
|
@ -1 +0,0 @@
|
|||
Clarify that Well-Known URIs are available on the server name's hostname. Contributed by @HarHarLinks.
|
||||
|
|
@ -67,7 +67,7 @@ current_version_url = "https://spec.matrix.org/latest"
|
|||
# The following is used when status = "stable", and is displayed in various UI elements on a released version
|
||||
# of the spec.
|
||||
# major = "1"
|
||||
# minor = "14"
|
||||
# minor = "15"
|
||||
|
||||
# User interface configuration
|
||||
[params.ui]
|
||||
|
|
|
|||
97
content/changelog/v1.15.md
Normal file
97
content/changelog/v1.15.md
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
---
|
||||
title: v1.15 Changelog
|
||||
linkTitle: v1.15
|
||||
type: docs
|
||||
layout: changelog
|
||||
outputs:
|
||||
- html
|
||||
- checklist
|
||||
date: 2025-06-26
|
||||
---
|
||||
|
||||
## Client-Server API
|
||||
|
||||
**New Endpoints**
|
||||
|
||||
- Add `GET /_matrix/client/v1/room_summary/{roomIdOrAlias}`, as per [MSC3266](https://github.com/matrix-org/matrix-spec-proposals/pull/3266). ([#2125](https://github.com/matrix-org/matrix-spec/issues/2125))
|
||||
- Add `GET /_matrix/client/v1/auth_metadata`, as per [MSC2965](https://github.com/matrix-org/matrix-spec-proposals/pull/2965). ([#2147](https://github.com/matrix-org/matrix-spec/issues/2147))
|
||||
|
||||
**Backwards Compatible Changes**
|
||||
|
||||
- Add `m.topic` content block to enable rich text in `m.room.topic` events as per [MSC3765](https://github.com/matrix-org/matrix-spec-proposals/pull/3765). ([#2095](https://github.com/matrix-org/matrix-spec/issues/2095))
|
||||
- Include device keys with Olm-encrypted events as per [MSC4147](https://github.com/matrix-org/matrix-spec-proposals/pull/4147). ([#2122](https://github.com/matrix-org/matrix-spec/issues/2122))
|
||||
- Add `/_matrix/client/v1/room_summary/{roomIdOrAlias}` and extend `/_matrix/client/v1/rooms/{roomId}/hierarchy` with the new optional properties `allowed_room_ids`, `encryption` and `room_version` as per [MSC3266](https://github.com/matrix-org/matrix-spec-proposals/pull/3266). ([#2125](https://github.com/matrix-org/matrix-spec/issues/2125), [#2158](https://github.com/matrix-org/matrix-spec/issues/2158))
|
||||
- Add the OAuth 2.0 based authentication API, as per [MSC3861](https://github.com/matrix-org/matrix-spec-proposals/pull/3861) and its sub-proposals. ([#2141](https://github.com/matrix-org/matrix-spec/issues/2141), [#2148](https://github.com/matrix-org/matrix-spec/issues/2148), [#2149](https://github.com/matrix-org/matrix-spec/issues/2149), [#2150](https://github.com/matrix-org/matrix-spec/issues/2150), [#2151](https://github.com/matrix-org/matrix-spec/issues/2151), [#2159](https://github.com/matrix-org/matrix-spec/issues/2159), [#2164](https://github.com/matrix-org/matrix-spec/issues/2164))
|
||||
|
||||
**Spec Clarifications**
|
||||
|
||||
- Clarify behaviour when the `topic` key of a `m.room.topic` event is absent, null, or empty. ([#2068](https://github.com/matrix-org/matrix-spec/issues/2068))
|
||||
- Fix the example of the `GET /sync` endpoint and the `m.room.member` example used in several places. ([#2077](https://github.com/matrix-org/matrix-spec/issues/2077))
|
||||
- Clarify the format of third-party invites, including the fact that identity server public keys can be encoded using standard or URL-safe base64. ([#2083](https://github.com/matrix-org/matrix-spec/issues/2083))
|
||||
- "Public" rooms in profile look-ups are defined through their join rule and history visibility. ([#2101](https://github.com/matrix-org/matrix-spec/issues/2101))
|
||||
- "Public" rooms in user directory queries are defined through their join rule and history visibility. ([#2102](https://github.com/matrix-org/matrix-spec/issues/2102))
|
||||
- Rooms published in `/publicRooms` don't necessarily have `public` join rules or `world_readable` history visibility. ([#2104](https://github.com/matrix-org/matrix-spec/issues/2104))
|
||||
- "Public" rooms with respect to call invites are defined through their join rule. ([#2106](https://github.com/matrix-org/matrix-spec/issues/2106))
|
||||
- "Public" rooms have no specific meaning with respect to moderation policy lists. ([#2107](https://github.com/matrix-org/matrix-spec/issues/2107))
|
||||
- "Public" rooms with respect to presence are defined through their join rule. ([#2108](https://github.com/matrix-org/matrix-spec/issues/2108))
|
||||
- Spaces are subject to the same access mechanisms as rooms. ([#2109](https://github.com/matrix-org/matrix-spec/issues/2109))
|
||||
- Fix various typos throughout the specification. ([#2121](https://github.com/matrix-org/matrix-spec/issues/2121), [#2144](https://github.com/matrix-org/matrix-spec/issues/2144))
|
||||
- Clarify that Well-Known URIs are available on the server name's hostname. Contributed by @HarHarLinks. ([#2140](https://github.com/matrix-org/matrix-spec/issues/2140))
|
||||
- Add missing fields in example for `ExportedSessionData`. ([#2154](https://github.com/matrix-org/matrix-spec/issues/2154))
|
||||
|
||||
|
||||
## Server-Server API
|
||||
|
||||
**Backwards Compatible Changes**
|
||||
|
||||
- Add `m.topic` content block to enable rich text in `m.room.topic` events as per [MSC3765](https://github.com/matrix-org/matrix-spec-proposals/pull/3765). ([#2095](https://github.com/matrix-org/matrix-spec/issues/2095))
|
||||
- Extend `/_matrix/federation/v1/hierarchy/{roomId}` with the new optional properties `encryption` and `room_version` as per [MSC3266](https://github.com/matrix-org/matrix-spec-proposals/pull/3266). ([#2125](https://github.com/matrix-org/matrix-spec/issues/2125))
|
||||
|
||||
**Spec Clarifications**
|
||||
|
||||
- Add a note to the invite endpoints that invites to local users may be received twice over federation if the homeserver is already in the room. ([#2067](https://github.com/matrix-org/matrix-spec/issues/2067))
|
||||
- Clarify the format of third-party invites, including the fact that identity server public keys can be encoded using standard or URL-safe base64. ([#2083](https://github.com/matrix-org/matrix-spec/issues/2083))
|
||||
- Clarify that auth event of `content.join_authorised_via_users_server` is only necessary for `m.room.member` with a `membership` of `join`. ([#2100](https://github.com/matrix-org/matrix-spec/issues/2100))
|
||||
- Rooms published in `/publicRooms` don't necessarily have `public` join rules or `world_readable` history visibility. ([#2104](https://github.com/matrix-org/matrix-spec/issues/2104))
|
||||
- Fix various typos throughout the specification. ([#2128](https://github.com/matrix-org/matrix-spec/issues/2128))
|
||||
- Clarify that Well-Known URIs are available on the server name's hostname. Contributed by @HarHarLinks. ([#2140](https://github.com/matrix-org/matrix-spec/issues/2140))
|
||||
|
||||
|
||||
## Application Service API
|
||||
|
||||
**Spec Clarifications**
|
||||
|
||||
- Clarify in the application service registration schema the `url: null` behaviour. ([#2130](https://github.com/matrix-org/matrix-spec/issues/2130))
|
||||
|
||||
|
||||
## Identity Service API
|
||||
|
||||
**Spec Clarifications**
|
||||
|
||||
- Clarify that public keys can be encoded using standard or URL-safe base64. ([#2083](https://github.com/matrix-org/matrix-spec/issues/2083))
|
||||
|
||||
|
||||
## Push Gateway API
|
||||
|
||||
No significant changes.
|
||||
|
||||
|
||||
## Room Versions
|
||||
|
||||
No significant changes.
|
||||
|
||||
|
||||
## Appendices
|
||||
|
||||
No significant changes.
|
||||
|
||||
|
||||
## Internal Changes/Tooling
|
||||
|
||||
**Spec Clarifications**
|
||||
|
||||
- Adjust margins in rendered endpoints. ([#2081](https://github.com/matrix-org/matrix-spec/issues/2081))
|
||||
- Replace Hugo shortcodes in OpenAPI output. ([#2088](https://github.com/matrix-org/matrix-spec/issues/2088))
|
||||
- Add [well-known funding manifest urls](https://floss.fund/funding-manifest/) to spec to authorise https://matrix.org/funding.json. Contributed by @HarHarLinks. ([#2115](https://github.com/matrix-org/matrix-spec/issues/2115))
|
||||
- Fix the historical info box when generating the historical spec in CI. ([#2123](https://github.com/matrix-org/matrix-spec/issues/2123))
|
||||
- Update the header navigation menu with links to modern matrix.org. Contributed by @HarHarLinks. ([#2137](https://github.com/matrix-org/matrix-spec/issues/2137))
|
||||
|
|
@ -12,6 +12,12 @@ clients which maintain a full local persistent copy of server state.
|
|||
|
||||
## API Standards
|
||||
|
||||
{{% boxes/note %}}
|
||||
These standards only apply to the APIs defined in the Matrix specification. APIs
|
||||
used by this specification but defined in other specifications, like the [OAuth
|
||||
2.0 API](#oauth-20-api), use their own rules.
|
||||
{{% /boxes/note %}}
|
||||
|
||||
The mandatory baseline for client-server communication in Matrix is
|
||||
exchanging JSON objects over HTTP APIs. More efficient transports may be
|
||||
specified in future as optional extensions.
|
||||
|
|
@ -292,9 +298,8 @@ and the two requests would be considered distinct because the two are
|
|||
considered separate endpoints. Similarly, if a client logs out and back in
|
||||
between two requests using the same transaction ID, the requests are distinct
|
||||
because the act of logging in and out creates a new device (unless an existing
|
||||
`device_id` is passed to [`POST
|
||||
/_matrix/client/v3/login`](#post_matrixclientv3login)). On the other hand, if a
|
||||
client re-uses a transaction ID for the same endpoint after
|
||||
`device_id` is given during the [login](#login) process). On the other hand, if
|
||||
a client re-uses a transaction ID for the same endpoint after
|
||||
[refreshing](#refreshing-access-tokens) an access token, it will be assumed to
|
||||
be a duplicate request and ignored. See also
|
||||
[Relationship between access tokens and devices](#relationship-between-access-tokens-and-devices).
|
||||
|
|
@ -436,6 +441,8 @@ endpoints it supports.
|
|||
|
||||
## Client Authentication
|
||||
|
||||
{{% changed-in v="1.15" %}} OAuth 2.0 API added to the specification.
|
||||
|
||||
Most API endpoints require the user to identify themselves by presenting
|
||||
previously obtained credentials in the form of an access token.
|
||||
An access token is typically obtained via the [Login](#login) or
|
||||
|
|
@ -449,6 +456,60 @@ free to choose an appropriate format. Server implementors may like to
|
|||
investigate [macaroons](http://research.google.com/pubs/pub41892.html).
|
||||
{{% /boxes/note %}}
|
||||
|
||||
Since Matrix 1.15, the Client-Server specification supports two authentication
|
||||
APIs:
|
||||
|
||||
* The [legacy API](#legacy-api)
|
||||
* The [OAuth 2.0 API](#oauth-20-api)
|
||||
|
||||
The legacy API has existed since the first version of the Matrix specification,
|
||||
while the OAuth 2.0 API has been introduced to rely on a industry standard and
|
||||
its experience rather than implementing a custom protocol that might not follow
|
||||
the best practices.
|
||||
|
||||
A homeserver may support one of those two APIs, or both. The two APIs are
|
||||
mutually incompatible, which means that after logging in, clients MUST only use
|
||||
the API that was used to obtain their current access token.
|
||||
|
||||
{{% boxes/note %}}
|
||||
Currently the OAuth 2.0 API doesn't cover all the use cases of the legacy API,
|
||||
such as automated applications that cannot use a web browser, or
|
||||
user management by [application services](application-service-api/#server-admin-style-permissions).
|
||||
{{% /boxes/note %}}
|
||||
|
||||
### Authentication API discovery
|
||||
|
||||
To discover if a homeserver supports the legacy API, the [`GET /login`](#get_matrixclientv3login)
|
||||
endpoint can be used.
|
||||
|
||||
To discover if a homeserver supports the OAuth 2.0 API, the
|
||||
[`GET /auth_metadata`](#get_matrixclientv1auth_metadata) endpoint can be used.
|
||||
|
||||
In both cases, the server SHOULD respond with 404 and an `M_UNRECOGNIZED` error
|
||||
code if the corresponding API is not supported.
|
||||
|
||||
### Account registration
|
||||
|
||||
With the legacy API, a client can register a new account with the
|
||||
[`/register`](#post_matrixclientv3register) endpoint.
|
||||
|
||||
With the OAuth 2.0 API, a client can't register a new account directly. The end
|
||||
user must do that directly in the homeserver's web UI. However, the client can
|
||||
signal to the homeserver that the user wishes to create a new account with the
|
||||
[`prompt=create`](#user-registration) parameter during authorization.
|
||||
|
||||
### Login
|
||||
|
||||
With the legacy API, a client can obtain an access token by using one of the
|
||||
[login](#legacy-login) methods supported by the homeserver at the [`POST /login`](#post_matrixclientv3login)
|
||||
endpoint. To invalidate the access token the client must call the [`/logout`](#post_matrixclientv3logout)
|
||||
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
|
||||
invalidate the access token the client must use [token revocation](#token-revocation).
|
||||
|
||||
### Using access tokens
|
||||
|
||||
Access tokens may be provided via a request header, using the Authentication
|
||||
|
|
@ -494,12 +555,14 @@ used to generate a new access token and refresh token, the new access
|
|||
and refresh tokens are now bound to the device associated with the
|
||||
initial refresh token.
|
||||
|
||||
By default, the [Login](#login) and [Registration](#account-registration)
|
||||
processes auto-generate a new `device_id`. A client is also free to
|
||||
generate its own `device_id` or, provided the user remains the same,
|
||||
reuse a device: in either case the client should pass the `device_id` in
|
||||
the request body. If the client sets the `device_id`, the server will
|
||||
invalidate any access and refresh tokens previously assigned to that device.
|
||||
During login or registration, the generated access token should be associated
|
||||
with a `device_id`. The legacy [Login](#legacy-login) and [Registration](#legacy-account-registration)
|
||||
processes auto-generate a new `device_id`, but a client is also free to provide
|
||||
its own `device_id`. With the OAuth 2.0 API, the `device_id` is always provided
|
||||
by the client. The client can generate a new `device_id` or, provided the user
|
||||
remains the same, reuse an existing device. If the client sets the `device_id`,
|
||||
the server will invalidate any access and refresh tokens previously assigned to
|
||||
that device.
|
||||
|
||||
### Refreshing access tokens
|
||||
|
||||
|
|
@ -508,14 +571,13 @@ invalidate any access and refresh tokens previously assigned to that device.
|
|||
Access tokens can expire after a certain amount of time. Any HTTP calls that
|
||||
use an expired access token will return with an error code `M_UNKNOWN_TOKEN`,
|
||||
preferably with `soft_logout: true`. When a client receives this error and it
|
||||
has a refresh token, it should attempt to refresh the access token by calling
|
||||
[`/refresh`](#post_matrixclientv3refresh). Clients can also refresh their
|
||||
access token at any time, even if it has not yet expired. If the token refresh
|
||||
succeeds, the client should use the new token for future requests, and can
|
||||
re-try previously-failed requests with the new token. When an access token is
|
||||
refreshed, a new refresh token may be returned; if a new refresh token is
|
||||
given, the old refresh token will be invalidated, and the new refresh token
|
||||
should be used when the access token needs to be refreshed.
|
||||
has a refresh token, it should attempt to refresh the access token. Clients can
|
||||
also refresh their access token at any time, even if it has not yet expired. If
|
||||
the token refresh succeeds, the client should use the new token for future
|
||||
requests, and can re-try previously-failed requests with the new token. When an
|
||||
access token is refreshed, a new refresh token may be returned; if a new refresh
|
||||
token is given, the old refresh token will be invalidated, and the new refresh
|
||||
token should be used when the access token needs to be refreshed.
|
||||
|
||||
The old refresh token remains valid until the new access token or refresh token
|
||||
is used, at which point the old refresh token is revoked. This ensures that if
|
||||
|
|
@ -528,6 +590,7 @@ and attempt to obtain a new access token by re-logging in. If the error
|
|||
response does not include a `soft_logout: true` property, the client should
|
||||
consider the user as being logged out.
|
||||
|
||||
With the legacy API, refreshing access tokens is done by calling [`/refresh`](#post_matrixclientv3refresh).
|
||||
Handling of clients that do not support refresh tokens is up to the homeserver;
|
||||
clients indicate their support for refresh tokens by including a
|
||||
`refresh_token: true` property in the request body of the
|
||||
|
|
@ -537,6 +600,11 @@ may allow the use of non-expiring access tokens, or may expire access tokens
|
|||
anyways and rely on soft logout behaviour on clients that don't support
|
||||
refreshing.
|
||||
|
||||
With the OAuth 2.0 API, refreshing access tokens is done with the [refresh token
|
||||
grant type](#refresh-token-grant), as demonstrated in the [token refresh
|
||||
flow](#token-refresh-flow). Support for refreshing access tokens is mandatory
|
||||
with this API.
|
||||
|
||||
### Soft logout
|
||||
|
||||
A client can be in a "soft logout" state if the server requires
|
||||
|
|
@ -560,8 +628,24 @@ specifying the device ID it is already using to the login API.
|
|||
with an `M_USER_LOCKED` error code, cannot obtain a new access token until
|
||||
the account has been [unlocked](#account-locking).
|
||||
|
||||
### Account management
|
||||
|
||||
With the legacy API, a client can use several endpoints to allow the user to
|
||||
manage their account like [changing their password](#password-management),
|
||||
[managing their devices](#device-management) or
|
||||
[deactivating their account](#account-deactivation).
|
||||
|
||||
With the OAuth 2.0 API, all account management is done via the homeserver's web
|
||||
UI.
|
||||
|
||||
### Legacy API
|
||||
|
||||
This is the original authentication API that was introduced in the first version
|
||||
of the Client-Server specification and uses custom APIs. Contrary to the OAuth
|
||||
2.0 API, account management is primarily done in the client's interface and as
|
||||
such it does not usually require the end user to be redirected to a web UI in
|
||||
their browser.
|
||||
|
||||
#### User-Interactive Authentication API
|
||||
|
||||
##### Overview
|
||||
|
|
@ -1329,7 +1413,7 @@ The `country` is the two-letter uppercase ISO-3166-1 alpha-2 country
|
|||
code that the number in `phone` should be parsed as if it were dialled
|
||||
from.
|
||||
|
||||
#### Login
|
||||
#### Login {id="legacy-login"}
|
||||
|
||||
A client can obtain access tokens using the [`/login`](#post_matrixclientv3login) API.
|
||||
|
||||
|
|
@ -1458,11 +1542,11 @@ forwarded to the login endpoint during the login process. For example:
|
|||
|
||||
GET /_matrix/static/client/login/?device_id=GHTYAJCE
|
||||
|
||||
#### Account registration
|
||||
#### Account registration {id="legacy-account-registration"}
|
||||
|
||||
{{% http-api spec="client-server" api="registration" %}}
|
||||
|
||||
#### Account management
|
||||
#### Account management {id="legacy-account-management"}
|
||||
|
||||
##### Password management
|
||||
|
||||
|
|
@ -1481,6 +1565,658 @@ MAY reject weak passwords with an error code `M_WEAK_PASSWORD`.
|
|||
|
||||
### OAuth 2.0 API
|
||||
|
||||
{{% added-in v="1.15" %}}
|
||||
|
||||
Contrary to the legacy API that uses custom endpoints and UIA, this
|
||||
authentication API is based on the [OAuth 2.0](https://oauth.net/2/) industry
|
||||
standard introduced in [RFC 6749](https://datatracker.ietf.org/doc/html/rfc6749)
|
||||
and extended by other RFCs, with a few features from [OpenID Connect](https://openid.net/connect/).
|
||||
This allows us to benefit from its experience and from any further enhancements
|
||||
or best practice recommendations.
|
||||
|
||||
The main change for end users with this API is that all the account management
|
||||
occurs in their browser on the homeserver's web UI. This is where they will
|
||||
register a new account or log into an existing account and authorize a client to
|
||||
access their Matrix account. This means that the homeserver has complete control
|
||||
over the requirements to create a new account and is not limited by the steps
|
||||
defined in this specification. It also means that less trust is given to clients
|
||||
because they don't have access to the user's credentials anymore.
|
||||
|
||||
{{% boxes/warning %}}
|
||||
The [User-Interactive Authentication API](#user-interactive-authentication-api)
|
||||
is not compatible with the OAuth 2.0 API, so the endpoints that depend on it for
|
||||
authentication can't be used when an access token is obtained with this API.
|
||||
{{% /boxes/warning %}}
|
||||
|
||||
**Sample flow**
|
||||
|
||||
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).
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
Once the client has retrieved the [server metadata](#server-metadata-discovery),
|
||||
it 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.
|
||||
- `state`: a unique opaque identifier, like a [transaction ID](#transaction-identifiers),
|
||||
that will allow the client to maintain state between the authorization request
|
||||
and the callback.
|
||||
- `code_verifier`: a cryptographically random value that will allow to make sure
|
||||
that the client that makes the token request for a given `code` is the same
|
||||
one that made the authorization request.
|
||||
|
||||
It is defined in [RFC 7636](https://datatracker.ietf.org/doc/html/rfc7636) as
|
||||
a high-entropy cryptographic random string using the characters `[A-Z]`,
|
||||
`[a-z]`, `[0-9]`, `-`, `.`, `_` and `~` with a minimum length of 43 characters
|
||||
and a maximum length of 128 characters.
|
||||
|
||||
**Authorization request**
|
||||
|
||||
The client then constructs the authorization request URL using the
|
||||
`authorization_endpoint` value, with the following query parameters:
|
||||
|
||||
| Parameter | Value |
|
||||
|-------------------------|----------------------------------------------------|
|
||||
| `response_type` | `code` |
|
||||
| `client_id` | The client ID returned from client registration. |
|
||||
| `redirect_uri` | The redirect URI that MUST match one of the values registered in the client metadata |
|
||||
| `scope` | `urn:matrix:client:api:* urn:matrix:client:device:<device_id>` with the `device_id` generated previously. |
|
||||
| `state` | The `state` value generated previously. |
|
||||
| `response_mode` | `fragment` or `query` (see "[Callback](#callback)" below). |
|
||||
| `code_challenge` | Computed from the `code_verifier` value generated previously using the SHA-256 algorithm, as described in [RFC 7636](https://datatracker.ietf.org/doc/html/rfc7636). |
|
||||
| `code_challenge_method` | `S256` |
|
||||
|
||||
This authorization request URL must be opened in the user's browser:
|
||||
|
||||
- For web-based clients, this can be done through a redirection or by opening
|
||||
the URL in a new tab.
|
||||
- For native clients, this can be done by opening the URL using the system
|
||||
browser, or, when available, through platform-specific APIs such as
|
||||
[`ASWebAuthenticationSession`](https://developer.apple.com/documentation/authenticationservices/aswebauthenticationsession)
|
||||
on iOS or [Android Custom Tabs](https://developer.chrome.com/docs/android/custom-tabs).
|
||||
|
||||
Sample authorization request, with extra whitespaces for readability:
|
||||
|
||||
```
|
||||
https://account.example.com/oauth2/auth?
|
||||
client_id = s6BhdRkqt3 &
|
||||
response_type = code &
|
||||
response_mode = fragment &
|
||||
redirect_uri = https://app.example.com/oauth2-callback &
|
||||
scope = urn:matrix:client:api:* urn:matrix:client:device:AAABBBCCCDDD &
|
||||
state = ewubooN9weezeewah9fol4oothohroh3 &
|
||||
code_challenge = 72xySjpngTcCxgbPfFmkPHjMvVDl2jW1aWP7-J6rmwU &
|
||||
code_challenge_method = S256
|
||||
```
|
||||
|
||||
<a id="callback"></a> **Callback**
|
||||
|
||||
Once completed, the user is redirected to the `redirect_uri`, with either a
|
||||
successful or failed authorization in the URL fragment or query parameters.
|
||||
Whether the parameters are in the URL fragment or query parameters is determined
|
||||
by the `response_mode` value:
|
||||
|
||||
- If set to `fragment`, the parameters will be placed in the URL fragment, like
|
||||
`https://example.com/callback#param1=value1¶m2=value2`.
|
||||
- If set to `query`, the parameters will be in placed the query string, like
|
||||
`com.example.app:/callback?param1=value1¶m2=value2`.
|
||||
|
||||
To avoid disclosing the parameters to the web server hosting the `redirect_uri`,
|
||||
clients SHOULD use the `fragment` response mode if the `redirect_uri` is an
|
||||
HTTPS URI with a remote host.
|
||||
|
||||
In both success and failure cases, the parameters will include the `state` value
|
||||
used in the authorization request.
|
||||
|
||||
A successful authorization will have a `code` value, for example:
|
||||
|
||||
```
|
||||
https://app.example.com/oauth2-callback#state=ewubooN9weezeewah9fol4oothohroh3&code=iuB7Eiz9heengah1joh2ioy9ahChuP6R
|
||||
```
|
||||
|
||||
A failed authorization will have the following values:
|
||||
|
||||
- `error`: the error code
|
||||
- `error_description`: the error description (optional)
|
||||
- `error_uri`: the URI where the user can find more information about the error (optional)
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
https://app.example.com/oauth2-callback#state=ewubooN9weezeewah9fol4oothohroh3&error=access_denied&error_description=The+resource+owner+or+authorization+server+denied+the+request.&error_uri=https%3A%2F%2Ferrors.example.com%2F
|
||||
```
|
||||
|
||||
**Token request**
|
||||
|
||||
The client then exchanges the authorization code to obtain an access token using
|
||||
the token endpoint.
|
||||
|
||||
This is done by making a POST request to the `token_endpoint` with the following
|
||||
parameters, encoded as `application/x-www-form-urlencoded` in the body:
|
||||
|
||||
| Parameter | Value |
|
||||
|-----------------|------------------------------------------------------------|
|
||||
| `grant_type` | `authorization_code` |
|
||||
| `code` | The value of `code` obtained from the callback. |
|
||||
| `redirect_uri` | The same `redirect_uri` used in the authorization request. |
|
||||
| `client_id` | The client ID returned from client registration. |
|
||||
| `code_verifier` | The value generated at the start of the authorization flow. |
|
||||
|
||||
The server replies with a JSON object containing the access token, the token
|
||||
type, the expiration time, and the refresh token.
|
||||
|
||||
Sample token request:
|
||||
|
||||
```
|
||||
POST /oauth2/token HTTP/1.1
|
||||
Host: account.example.com
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Accept: application/json
|
||||
|
||||
grant_type=authorization_code
|
||||
&code=iuB7Eiz9heengah1joh2ioy9ahChuP6R
|
||||
&redirect_uri=https://app.example.com/oauth2-callback
|
||||
&client_id=s6BhdRkqt3
|
||||
&code_verifier=ogie4iVaeteeKeeLaid0aizuimairaCh
|
||||
```
|
||||
|
||||
Sample response:
|
||||
|
||||
```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
|
||||
grant](#refresh-token-grant).
|
||||
|
||||
When the access token expires, the client must refresh it by making a `POST`
|
||||
request to the `token_endpoint` with the following parameters, encoded as
|
||||
`application/x-www-form-urlencoded` in the body:
|
||||
|
||||
| Parameter | Value |
|
||||
|-----------------|------------------------------------------------------------|
|
||||
| `grant_type` | `refresh_token` |
|
||||
| `refresh_token` | The `refresh_token` obtained from the token response during the last token request. |
|
||||
| `client_id` | The client ID returned from client registration. |
|
||||
|
||||
The server replies with a JSON object containing the new access token, the token
|
||||
type, the expiration time, and a new refresh token, like in the authorization
|
||||
flow.
|
||||
|
||||
#### Server metadata discovery
|
||||
|
||||
{{% http-api spec="client-server" api="oauth_server_metadata" %}}
|
||||
|
||||
#### Client registration
|
||||
|
||||
Before being able to use the authorization flow to obtain an access token, a
|
||||
client needs to obtain a `client_id` by registering itself with the server.
|
||||
|
||||
This should be done via OAuth 2.0 Dynamic Client Registration as defined in
|
||||
[RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591).
|
||||
|
||||
##### Client metadata
|
||||
|
||||
In OAuth 2.0, clients register a set of metadata values with the authorization
|
||||
server, which associates it with a newly generated `client_id`. These values are
|
||||
used to describe the client to the user and define how the client interacts with
|
||||
the server.
|
||||
|
||||
{{% definition path="schemas/oauth2-client-metadata" %}}
|
||||
|
||||
###### Metadata localization
|
||||
|
||||
As per [RFC 7591 section 2.2](https://tools.ietf.org/html/rfc7591#section-2.2),
|
||||
all the human-readable metadata values MAY be localized.
|
||||
|
||||
The human-readable values include:
|
||||
- `client_name`
|
||||
- `logo_uri`
|
||||
- `tos_uri`
|
||||
- `policy-uri`
|
||||
|
||||
For example:
|
||||
|
||||
```json
|
||||
{
|
||||
"client_name": "Digital mailbox",
|
||||
"client_name#en-US": "Digital mailbox",
|
||||
"client_name#en-GB": "Digital postbox",
|
||||
"client_name#fr": "Boîte aux lettres numérique",
|
||||
"tos_uri": "https://example.com/tos.html",
|
||||
"tos_uri#fr": "https://example.com/fr/tos.html",
|
||||
"policy_uri": "https://example.com/policy.html",
|
||||
"policy_uri#fr": "https://example.com/fr/policy.html"
|
||||
}
|
||||
```
|
||||
|
||||
###### Redirect URI validation
|
||||
|
||||
The redirect URI plays a critical role in validating the authenticity of the
|
||||
client. The client "proves" its identity by demonstrating that it controls the
|
||||
redirect URI. This is why it is critical to have strict validation of the
|
||||
redirect URI.
|
||||
|
||||
The `application_type` metadata is used to determine the type of client.
|
||||
|
||||
In all cases, the redirect URI MUST NOT have a fragment component.
|
||||
|
||||
**Web clients**
|
||||
|
||||
`web` clients can use redirect URIs that:
|
||||
|
||||
- MUST use the `https` scheme.
|
||||
- MUST NOT use a user or password in the authority component of the URI.
|
||||
- MUST use the client URI as a common base for the authority component, as
|
||||
defined previously.
|
||||
- MAY include an `application/x-www-form-urlencoded` formatted query component.
|
||||
|
||||
For example, with `https://example.com/` as the client URI, the following are
|
||||
valid redirect URIs:
|
||||
- `https://example.com/callback`
|
||||
- `https://app.example.com/callback`
|
||||
- `https://example.com:5173/?query=value`
|
||||
|
||||
With the same client URI, the following are invalid redirect URIs:
|
||||
- `https://example.com/callback#fragment`
|
||||
- `http://example.com/callback`
|
||||
- `http://localhost/`
|
||||
|
||||
**Native clients**
|
||||
|
||||
`native` clients can use three types of redirect URIs:
|
||||
|
||||
1. **Private-Use URI Scheme**
|
||||
- The scheme MUST be prefixed with the client URI hostname in reverse-DNS
|
||||
notation. For example, if the client URI is `https://example.com/`, then a
|
||||
valid custom URI scheme would be `com.example.app:/`.
|
||||
- There MUST NOT be an authority component. This means that the URI MUST have
|
||||
either a single slash or none immediately following the scheme, with no
|
||||
hostname, username, or port.
|
||||
2. **`http` URI on the loopback interface**
|
||||
- The scheme MUST be `http`.
|
||||
- The host part MUST be `localhost`, `127.0.0.1`, or `[::1]`.
|
||||
- There MUST NOT be a port. The homeserver MUST then accept any port number
|
||||
during the authorization flow.
|
||||
3. **Claimed `https` Scheme URI**
|
||||
|
||||
Some operating systems allow apps to claim `https` scheme URIs in the
|
||||
domains they control. When the browser encounters a claimed URI, instead of
|
||||
the page being loaded in the browser, the native app is launched with the
|
||||
URI supplied as a launch parameter. The same rules as for `web` clients
|
||||
apply.
|
||||
|
||||
These restrictions are the same as defined by [RFC 8252 section 7](https://tools.ietf.org/html/rfc8252#section-7).
|
||||
|
||||
For example, with `https://example.com/` as the client URI,
|
||||
|
||||
These are valid redirect URIs:
|
||||
- `com.example.app:/callback`
|
||||
- `com.example:/`
|
||||
- `com.example:callback`
|
||||
- `http://localhost/callback`
|
||||
- `http://127.0.0.1/callback`
|
||||
- `http://[::1]/callback`
|
||||
|
||||
These are invalid redirect URIs:
|
||||
- `example:/callback`
|
||||
- `com.example.app://callback`
|
||||
- `https://localhost/callback`
|
||||
- `http://localhost:1234/callback`
|
||||
|
||||
##### Dynamic client registration flow
|
||||
|
||||
To register, the client sends an HTTP `POST` request to the
|
||||
`registration_endpoint`, which can be found in the [server metadata](#server-metadata-discovery).
|
||||
The body of the request is the JSON-encoded [`OAuthClientMetadata`](#client-metadata).
|
||||
|
||||
For example, the client could send the following registration request:
|
||||
|
||||
```http
|
||||
POST /register HTTP/1.1
|
||||
Content-Type: application/json
|
||||
Accept: application/json
|
||||
Server: auth.example.com
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"client_name": "My App",
|
||||
"client_name#fr": "Mon application",
|
||||
"client_uri": "https://example.com/",
|
||||
"logo_uri": "https://example.com/logo.png",
|
||||
"tos_uri": "https://example.com/tos.html",
|
||||
"tos_uri#fr": "https://example.com/fr/tos.html",
|
||||
"policy_uri": "https://example.com/policy.html",
|
||||
"policy_uri#fr": "https://example.com/fr/policy.html",
|
||||
"redirect_uris": ["https://app.example.com/callback"],
|
||||
"token_endpoint_auth_method": "none",
|
||||
"response_types": ["code"],
|
||||
"grant_types": [
|
||||
"authorization_code",
|
||||
"refresh_token",
|
||||
"urn:ietf:params:oauth:grant-type:token-exchange"
|
||||
],
|
||||
"application_type": "web"
|
||||
}
|
||||
```
|
||||
|
||||
Upon successful registration, the server replies with an `HTTP 201 Created`
|
||||
response, with a JSON object containing the allocated `client_id` and all the
|
||||
registered metadata values.
|
||||
|
||||
With the registration request above, the server might reply with:
|
||||
|
||||
```json
|
||||
{
|
||||
"client_id": "s6BhdRkqt3",
|
||||
"client_name": "My App",
|
||||
"client_uri": "https://example.com/",
|
||||
"logo_uri": "https://example.com/logo.png",
|
||||
"tos_uri": "https://example.com/tos.html",
|
||||
"policy_uri": "https://example.com/policy.html",
|
||||
"redirect_uris": ["https://app.example.com/callback"],
|
||||
"token_endpoint_auth_method": "none",
|
||||
"response_types": ["code"],
|
||||
"grant_types": ["authorization_code", "refresh_token"],
|
||||
"application_type": "web"
|
||||
}
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
To avoid the number of client registrations growing over time, the server MAY
|
||||
choose to delete client registrations that don't have an active session. The
|
||||
server MUST NOT delete client registrations that have an active session.
|
||||
|
||||
Clients MUST perform a new client registration at the start of each
|
||||
authorization flow.
|
||||
|
||||
{{% boxes/note %}}
|
||||
Because each client on each user device will do its own registration, they may
|
||||
all have different `client_id`s. This means that the server may store the same
|
||||
client registration multiple times, which could lead to a large number of client
|
||||
registrations.
|
||||
|
||||
This can be mitigated by de-duplicating client registrations that have identical
|
||||
metadata. By doing so, different users on different devices using the same
|
||||
client can share a single `client_id`, reducing the overall number of
|
||||
registrations.
|
||||
{{% /boxes/note %}}
|
||||
|
||||
#### Scope
|
||||
|
||||
The client requests a scope in the OAuth 2.0 authorization flow, which is then
|
||||
associated to the generated access and refresh tokens. This provides a framework
|
||||
for obtaining user consent.
|
||||
|
||||
A scope is defined in [RFC 6749 section 3.3](https://datatracker.ietf.org/doc/html/rfc6749#section-3.3)
|
||||
as a string containing a list of space-separated scope tokens.
|
||||
|
||||
{{% boxes/note %}}
|
||||
The framework encourages the practice of obtaining additional user consent when
|
||||
a client asks for a new scope that was not granted previously. This could be
|
||||
used by future MSCs to replace the legacy [User-Interactive Authentication API](#user-interactive-authentication-api).
|
||||
{{% /boxes/note %}}
|
||||
|
||||
##### Scope token format
|
||||
|
||||
All scope tokens related to Matrix should start with `urn:matrix:` and use the
|
||||
`:` delimiter for further sub-division.
|
||||
|
||||
Scope tokens related to mapping of Client-Server API access levels should start
|
||||
with `urn:matrix:client:`.
|
||||
|
||||
{{% boxes/note %}}
|
||||
For 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`.
|
||||
{{% /boxes/note %}}
|
||||
|
||||
##### Allocated scope tokens
|
||||
|
||||
This specification defines the following scope tokens:
|
||||
- [`urn:matrix:client:api:*`](#full-client-server-api-readwrite-access)
|
||||
- [`urn:matrix:client:device:<device_id>`](#device-id-allocation)
|
||||
|
||||
###### Full client-server API read/write access
|
||||
|
||||
| Scope | Purpose |
|
||||
|---------------------------|---------------------------------------------|
|
||||
| `urn:matrix:client:api:*` | Grants full access to the Client-Server API. |
|
||||
|
||||
{{% boxes/note %}}
|
||||
This token matches the behavior of the legacy authentication API. Future MSCs
|
||||
could introduce more fine-grained scope tokens like
|
||||
`urn:matrix:client:api:read:*` for read-only access.
|
||||
{{% /boxes/note %}}
|
||||
|
||||
###### Device ID allocation
|
||||
|
||||
| Scope | Purpose |
|
||||
|----------------------------------------|----------------------------------------------------------------------------------------------|
|
||||
| `urn:matrix:client:device:<device_id>` | Allocates the given `device_id` and associates it to the generated access and refresh tokens. |
|
||||
|
||||
Contrary to the legacy login and registration APIs where the homeserver is
|
||||
typically the one generating a `device_id` and providing it to the client, with
|
||||
the OAuth 2.0 API, the client is responsible for allocating the `device_id`.
|
||||
|
||||
There MUST be exactly one `urn:matrix:client:device:<device_id>` token in the
|
||||
requested scope in the login flow.
|
||||
|
||||
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 [RFC 3986 section 2.3](https://datatracker.ietf.org/doc/html/rfc3986#section-2.3):
|
||||
|
||||
```
|
||||
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 [RFC 6749 section 3.3](https://datatracker.ietf.org/doc/html/rfc6749#section-3.3),
|
||||
which is defined as the following ASCII ranges:
|
||||
|
||||
```
|
||||
%x21 / %x23-5B / %x5D-7E
|
||||
```
|
||||
|
||||
This definition matches:
|
||||
- alphanumeric characters: `A-Z`, `a-z`, `0-9`
|
||||
- the following characters: ``! # $ % & ' ( ) * + , - . / : ; < = > ? @ [ ] ^ _ ` { | } ~``
|
||||
|
||||
#### Grant types
|
||||
|
||||
[RFC 6749](https://datatracker.ietf.org/doc/html/rfc6749) and other RFCs define
|
||||
several "grant types": ways to obtain an ["access token"](#using-access-tokens).
|
||||
|
||||
All these grants types require the client to know the following [authorization
|
||||
server metadata](#server-metadata-discovery):
|
||||
- `token_endpoint`
|
||||
- `grant_types_supported`
|
||||
|
||||
The client must also have obtained a `client_id` by [registering with the server](#client-registration).
|
||||
|
||||
This specification supports the following grant types:
|
||||
- [Authorization code grant](#authorization-code-grant)
|
||||
- [Refresh token grant](#refresh-token-grant)
|
||||
|
||||
##### Authorization code grant
|
||||
|
||||
As per [RFC 6749 section 4.1](https://datatracker.ietf.org/doc/html/rfc6749#section-4.1),
|
||||
the authorization code grant lets the client obtain an access token through a
|
||||
browser redirect.
|
||||
|
||||
This grant requires the client to know the following [authorization server
|
||||
metadata](#server-metadata-discovery):
|
||||
- `authorization_endpoint`
|
||||
- `response_types_supported`
|
||||
- `response_mode_supported`
|
||||
|
||||
To use this grant, homeservers and clients MUST:
|
||||
|
||||
- Support the authorization code grant as per [RFC 6749 section 4.1](https://datatracker.ietf.org/doc/html/rfc6749#section-4.1).
|
||||
- Support the [refresh token grant](#refresh-token-grant).
|
||||
- Support PKCE using the `S256` code challenge method as per [RFC 7636](https://datatracker.ietf.org/doc/html/rfc7636).
|
||||
- Use [pre-registered](#client-registration), strict redirect URIs.
|
||||
- Use the `fragment` response mode as per [OAuth 2.0 Multiple Response Type
|
||||
Encoding Practices](https://openid.net/specs/oauth-v2-multiple-response-types-1_0.html)
|
||||
for clients with an HTTPS redirect URI.
|
||||
|
||||
###### User registration
|
||||
|
||||
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).
|
||||
|
||||
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.
|
||||
|
||||
##### Refresh token grant
|
||||
|
||||
As per [RFC 6749 section 6](https://datatracker.ietf.org/doc/html/rfc6749#section-6),
|
||||
the refresh token grant lets the client exchange a refresh token for an access
|
||||
token.
|
||||
|
||||
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 MUST be short-lived and SHOULD be refreshed using the
|
||||
`refresh_token` when expired.
|
||||
|
||||
The homeserver SHOULD issue a new refresh token each time an old one is used,
|
||||
and invalidate the old one. However, it MUST ensure that the client is able to
|
||||
retry the refresh request in the case that the response to the request is lost.
|
||||
|
||||
The homeserver SHOULD consider that the session is compromised if an old,
|
||||
invalidated refresh token is used, and SHOULD revoke the session.
|
||||
|
||||
The client MUST handle access token refresh failures as follows:
|
||||
|
||||
- If the refresh fails due to network issues or a `5xx` HTTP status code from
|
||||
the server, the client should retry the request with the old refresh token
|
||||
later.
|
||||
- If the refresh fails due to a `4xx` HTTP status code from the server, the
|
||||
client should consider the session logged out.
|
||||
|
||||
#### Token revocation
|
||||
|
||||
When a user wants to log out from a client, the client SHOULD use OAuth 2.0
|
||||
token revocation as defined in [RFC 7009](https://datatracker.ietf.org/doc/html/rfc7009).
|
||||
|
||||
The client makes a `POST` request to the `revocation_endpoint` that can be found
|
||||
in the [authorization server metadata](#server-metadata-discovery).
|
||||
|
||||
The body of the request includes the following parameters, encoded as
|
||||
`application/x-www-form-urlencoded`:
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Parameter</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>token</code></td>
|
||||
<td>
|
||||
<strong>Required.</strong> MUST contain either the access token or the
|
||||
refresh token to be revoked.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>token_type_hint</code></td>
|
||||
<td>
|
||||
<strong>Optional.</strong> If present, MUST have a value of either
|
||||
<code>access_token</code> or <code>refresh_token</code>. The server MAY
|
||||
use this value to optimize the token lookup process.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>client_id</code></td>
|
||||
<td>
|
||||
<p>
|
||||
<strong>Optional.</strong> The client identifier obtained during
|
||||
<a href="#client-registration">client registration</a>.
|
||||
</p>
|
||||
<p>
|
||||
If the <code>client_id</code> is not provided, or does not match the
|
||||
client associated with the token, the server SHOULD still revoke the
|
||||
token. This behavior is meant to help good actors like secret scanning
|
||||
tools to proactively revoke leaked tokens. The server MAY also warn
|
||||
the user that one of their sessions may be compromised in this
|
||||
scenario.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
For example, revoking using the access token:
|
||||
|
||||
```
|
||||
POST /oauth2/revoke HTTP/1.1
|
||||
Host: auth.example.com
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
token=mat_ooreiPhei2wequu9fohkai3AeBaec9oo&
|
||||
token_type_hint=access_token&
|
||||
client_id=s6BhdRkqt3
|
||||
```
|
||||
|
||||
The server MUST revoke both the access token and refresh token associated with
|
||||
the token provided in the request.
|
||||
|
||||
The server SHOULD return one of the following responses:
|
||||
|
||||
- If the token is already revoked or invalid, the server returns a `200 OK`
|
||||
response
|
||||
- If the client is not authorized to revoke the token, the server returns a
|
||||
`401 Unauthorized` response
|
||||
- For other errors, the server returns a `400 Bad Request` response with error
|
||||
details
|
||||
|
||||
### Account moderation
|
||||
|
||||
#### Account locking
|
||||
|
|
|
|||
|
|
@ -1124,7 +1124,7 @@ The process between Alice and Bob verifying each other would be:
|
|||
framework as described above.
|
||||
3. Alice's client displays a QR code that Bob is able to scan if Bob's client
|
||||
indicated the ability to scan, an option to scan Bob's QR code if her client
|
||||
is able to scan. Bob's client prompts displays a QR code that Alice can
|
||||
is able to scan. Bob's client displays a QR code that Alice can
|
||||
scan if Alice's client indicated the ability to scan, and an option to scan
|
||||
Alice's QR code if his client is able to scan. The format for the QR code
|
||||
is described below. Other options, like starting SAS Emoji verification,
|
||||
|
|
|
|||
|
|
@ -364,7 +364,7 @@ property under `m.new_content`.
|
|||
|
||||
A particular constraint applies to events which replace a [reply](#rich-replies):
|
||||
in contrast to the original reply, there should be no `m.in_reply_to` property
|
||||
in the the `m.relates_to` object, since it would be redundant (see
|
||||
in the `m.relates_to` object, since it would be redundant (see
|
||||
[Applying `m.new_content`](#applying-mnew_content) above, which notes that the
|
||||
original event's `m.relates_to` is preserved), as well as being contrary to the
|
||||
spirit of the event relationships mechanism which expects only one "parent" per
|
||||
|
|
|
|||
|
|
@ -6,9 +6,10 @@ allow users to log into applications via a single web-based
|
|||
authentication portal. Examples include OpenID Connect, "Central
|
||||
Authentication Service" (CAS) and SAML.
|
||||
|
||||
This module allows a Matrix homeserver to delegate user authentication
|
||||
to an external authentication server supporting one of these protocols.
|
||||
In this process, there are three systems involved:
|
||||
This module allows a Matrix homeserver that supports the [legacy authentication
|
||||
API](#legacy-api) to delegate user authentication to an external authentication
|
||||
server supporting one of these protocols. In this process, there are three
|
||||
systems involved:
|
||||
|
||||
- A Matrix client, using the APIs defined in this specification, which
|
||||
is seeking to authenticate a user to a Matrix homeserver.
|
||||
|
|
@ -24,7 +25,7 @@ used to communicate with the authentication server. Different Matrix
|
|||
homeserver implementations might support different SSO protocols.
|
||||
|
||||
Clients and homeservers implementing the SSO flow will need to consider
|
||||
both [login](#login) and [user-interactive authentication](#user-interactive-authentication-api). The flow is
|
||||
both [login](#legacy-login) and [user-interactive authentication](#user-interactive-authentication-api). The flow is
|
||||
similar in both cases, but there are slight differences.
|
||||
|
||||
Typically, SSO systems require a single "callback" URI to be configured
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ included under the `m.relations` property in `unsigned` for the thread root. For
|
|||
```
|
||||
|
||||
`latest_event` is the most recent event (topologically to the server) in the thread sent by an
|
||||
un-[ignored user](#ignoring-users).
|
||||
un-[ignored user](#ignoring-users). It should be serialized in the same form as the event itself.
|
||||
|
||||
Note that, as in the example above, child events of the `latest_event` should
|
||||
themselves be aggregated and included under `m.relations` for that event. The
|
||||
|
|
|
|||
|
|
@ -185,6 +185,10 @@ is as follows:
|
|||
- Take care in creating your proposal. Specify your intended
|
||||
changes, and give reasoning to back them up. Changes without
|
||||
justification will likely be poorly received by the community.
|
||||
- At the time of creating your draft you will not yet know the PR number, so you
|
||||
should use a placeholder number to name your file and edit that
|
||||
after PR submission. The suggested steps are described in
|
||||
detail [in the proposals guide](https://github.com/matrix-org/matrix-spec-proposals#1-writing-the-proposal).
|
||||
- Fork and make a PR to the
|
||||
[matrix-spec-proposals](https://github.com/matrix-org/matrix-spec-proposals) repository.
|
||||
The ID of your PR will become the MSC ID for the lifetime of your
|
||||
|
|
@ -493,6 +497,42 @@ In summary:
|
|||
a small table at the bottom mapping the various values from stable
|
||||
to unstable.
|
||||
|
||||
### Placeholder MSCs
|
||||
|
||||
Some proposals may contain security-sensitive or private context which can't be
|
||||
publicly disclosed until a later stage in the idea or solution process. Typically,
|
||||
the initial idea is validated using some amount of implementation or experimentation
|
||||
and may require an MSC number to make that implementation easier.
|
||||
|
||||
Placeholder MSCs are used to represent proposals in a state where implementation
|
||||
is ongoing, but the MSC details can't yet be disclosed. Authors which feel as
|
||||
though their MSC could be highly sensitive MUST get in contact with the Spec Core
|
||||
Team or [Security Team](https://matrix.org/security-disclosure-policy/) prior to
|
||||
opening their MSC. If either team determines that a placeholder MSC is required,
|
||||
it may be opened as such.
|
||||
|
||||
There are a few expectations attached to placeholder MSCs:
|
||||
|
||||
* They have a title which marks them WIP, and are in the "draft" state.
|
||||
* They have the following labels: `[proposal-placeholder, action-required, needs-implementation]`.
|
||||
* Notably, *not* `proposal`.
|
||||
* They are relatively short-lived (ideally less than 6-12 months in placeholder).
|
||||
* They propose solutions which are reasonably likely to be accepted. If a placeholder
|
||||
needs to be closed because the idea won't work, isn't needed, etc, then the MSC's
|
||||
content MUST be published ahead of that closure.
|
||||
* Note: the MSC's publication (and therefore closure) may be delayed until an
|
||||
appropriate point in the security disclosure cycle. For example, an alternative
|
||||
MSC being published, or a stream of work being completed.
|
||||
* When they are updated to receive real content, the following happens:
|
||||
1. The Spec Core Team or the author leaves a comment to cause a notification
|
||||
that the MSC has been replaced with real content.
|
||||
2. The `proposal` label (or its equivalent) is added to trigger chat notifications
|
||||
in the public Matrix rooms. The `proposal-placeholder` and `action-required`
|
||||
labels should be removed at this stage as well. Other labels are removed/applied
|
||||
per normal process.
|
||||
* The Spec Core Team is aware of the intended MSC's title and purpose. This is
|
||||
especially important if the Security Team approved the use of a placeholder MSC.
|
||||
|
||||
## Proposal Tracking
|
||||
|
||||
This is a living document generated from the list of proposals on the
|
||||
|
|
|
|||
|
|
@ -23,3 +23,4 @@ allOf:
|
|||
type: array
|
||||
items:
|
||||
$ref: protocol_instance.yaml
|
||||
required: ['instances']
|
||||
|
|
|
|||
|
|
@ -77,4 +77,4 @@ properties:
|
|||
"placeholder": "#foobar"
|
||||
}
|
||||
}
|
||||
required: ['user_fields', 'location_fields', 'icon', 'field_types', 'instances']
|
||||
required: ['user_fields', 'location_fields', 'icon', 'field_types']
|
||||
|
|
|
|||
|
|
@ -201,6 +201,11 @@ paths:
|
|||
|
||||
Homeservers should prevent the caller from adding a 3PID to their account if it has
|
||||
already been added to another user's account on the homeserver.
|
||||
|
||||
{{% boxes/warning %}}
|
||||
Since this endpoint uses User-Interactive Authentication, it cannot be used when the access token was obtained
|
||||
via the [OAuth 2.0 API](/client-server-api/#oauth-20-api).
|
||||
{{% /boxes/warning %}}
|
||||
operationId: add3PID
|
||||
security:
|
||||
- accessTokenQuery: []
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ paths:
|
|||
Publishes cross-signing keys for the user.
|
||||
|
||||
This API endpoint uses the [User-Interactive Authentication API](/client-server-api/#user-interactive-authentication-api).
|
||||
|
||||
|
||||
User-Interactive Authentication MUST be performed, except in these cases:
|
||||
- there is no existing cross-signing master key uploaded to the homeserver, OR
|
||||
- there is an existing cross-signing master key and it exactly matches the
|
||||
|
|
@ -34,11 +34,16 @@ paths:
|
|||
keys provided in the request (self-signing key, user-signing key) they MUST also
|
||||
match the existing keys stored on the server. In other words, the request contains
|
||||
no new keys.
|
||||
|
||||
|
||||
This allows clients to freely upload one set of keys, but not modify/overwrite keys if
|
||||
they already exist. Allowing clients to upload the same set of keys more than once
|
||||
they already exist. Allowing clients to upload the same set of keys more than once
|
||||
makes this endpoint idempotent in the case where the response is lost over the network,
|
||||
which would otherwise cause a UIA challenge upon retry.
|
||||
|
||||
{{% boxes/warning %}}
|
||||
When this endpoint requires User-Interactive Authentication, it cannot be used when the access token was obtained
|
||||
via the [OAuth 2.0 API](/client-server-api/#oauth-20-api).
|
||||
{{% /boxes/warning %}}
|
||||
operationId: uploadCrossSigningKeys
|
||||
security:
|
||||
- accessTokenQuery: []
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ properties:
|
|||
type: string
|
||||
description: |-
|
||||
The end-to-end message encryption algorithm that the key is for. Must be `m.megolm.v1.aes-sha2`.
|
||||
example: "m.megolm.v1.aes-sha2"
|
||||
forwarding_curve25519_key_chain:
|
||||
type: array
|
||||
items:
|
||||
|
|
@ -30,31 +31,24 @@ properties:
|
|||
description: |-
|
||||
Chain of Curve25519 keys through which this session was forwarded, via [m.forwarded_room_key](/client-server-api/#mforwarded_room_key)
|
||||
events.
|
||||
example: [ "hPQNcabIABgGnx3/ACv/jmMmiQHoeFfuLB17tzWp6Hw" ]
|
||||
sender_key:
|
||||
type: string
|
||||
description: |-
|
||||
Unpadded base64-encoded device Curve25519 key.
|
||||
example: "RF3s+E7RkTQTGF2d8Deol0FkQvgII2aJDf3/Jp5mxVU"
|
||||
sender_claimed_keys:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: |-
|
||||
A map from algorithm name (`ed25519`) to the Ed25519 signing key of the sending device.
|
||||
example: { "ed25519": "aj40p+aw64yPIdsxoog8jhPu9i7l7NcFRecuOQblE3Y" }
|
||||
session_key:
|
||||
type: string
|
||||
description: |-
|
||||
Unpadded base64-encoded session key in [session-export format](https://gitlab.matrix.org/matrix-org/olm/blob/master/docs/megolm.md#session-export-format).
|
||||
example: {
|
||||
"algorithm": "m.megolm.v1.aes-sha2",
|
||||
"forwarding_curve25519_key_chain": [
|
||||
"hPQNcabIABgGnx3/ACv/jmMmiQHoeFfuLB17tzWp6Hw"
|
||||
],
|
||||
"sender_key": "RF3s+E7RkTQTGF2d8Deol0FkQvgII2aJDf3/Jp5mxVU",
|
||||
"sender_claimed_keys": {
|
||||
"ed25519": "aj40p+aw64yPIdsxoog8jhPu9i7l7NcFRecuOQblE3Y",
|
||||
},
|
||||
"session_key": "AgAAAADxKHa9uFxcXzwYoNueL5Xqi69IkD4sni8Llf..."
|
||||
}
|
||||
example: "AgAAAADxKHa9uFxcXzwYoNueL5Xqi69IkD4sni8Llf..."
|
||||
required:
|
||||
- algorithm
|
||||
- forwarding_curve25519_key_chain
|
||||
|
|
|
|||
|
|
@ -37,7 +37,8 @@ allOf:
|
|||
A unique identifier for this instance on the homeserver. This field is added
|
||||
to the response of [`GET /_matrix/app/v1/thirdparty/protocol/{protocol}`](/application-service-api/#get_matrixappv1thirdpartyprotocolprotocol)
|
||||
by the homeserver.
|
||||
|
||||
|
||||
This is the identifier to use as the `third_party_instance_id` in a request to
|
||||
[`POST /_matrix/client/v3/publicRooms`](/client-server-api/#post_matrixclientv3publicrooms).
|
||||
example: "irc-freenode"
|
||||
required: ['instances']
|
||||
|
|
|
|||
|
|
@ -42,9 +42,3 @@ allOf:
|
|||
room_version:
|
||||
description: The version of the room.
|
||||
type: string
|
||||
|
||||
required:
|
||||
- room_id
|
||||
- num_joined_members
|
||||
- world_readable
|
||||
- guest_can_join
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@
|
|||
accessTokenQuery:
|
||||
type: apiKey
|
||||
description: |-
|
||||
**Deprecated.** The `access_token` returned by a call to `/login` or `/register`, as a query
|
||||
parameter.
|
||||
**Deprecated.** The `access_token` obtained during [account registration](/client-server-api/#account-registration)
|
||||
or [login](/client-server-api/#login), as a query parameter.
|
||||
|
||||
It can also be the `as_token` of an application service.
|
||||
name: access_token
|
||||
|
|
@ -23,11 +23,11 @@ accessTokenQuery:
|
|||
accessTokenBearer:
|
||||
type: http
|
||||
description: |-
|
||||
The `access_token` returned by a call to `/login` or `/register`, using the
|
||||
`Authorization: Bearer` header.
|
||||
The `access_token` obtained during [account registration](/client-server-api/#account-registration)
|
||||
or [login](/client-server-api/#login), using the `Authorization: Bearer` header.
|
||||
|
||||
It can also be the `as_token` of an application service.
|
||||
|
||||
|
||||
This is the preferred method.
|
||||
scheme: bearer
|
||||
appserviceAccessTokenQuery:
|
||||
|
|
@ -42,6 +42,6 @@ appserviceAccessTokenBearer:
|
|||
description: |-
|
||||
The `as_token` of an application service, using the `Authorization: Bearer`
|
||||
header.
|
||||
|
||||
|
||||
This is the preferred method.
|
||||
scheme: bearer
|
||||
|
|
|
|||
|
|
@ -137,6 +137,11 @@ paths:
|
|||
This API endpoint uses the [User-Interactive Authentication API](/client-server-api/#user-interactive-authentication-api).
|
||||
|
||||
Deletes the given device, and invalidates any access token associated with it.
|
||||
|
||||
{{% boxes/warning %}}
|
||||
Since this endpoint uses User-Interactive Authentication, it cannot be used when the access token was obtained
|
||||
via the [OAuth 2.0 API](/client-server-api/#oauth-20-api).
|
||||
{{% /boxes/warning %}}
|
||||
operationId: deleteDevice
|
||||
security:
|
||||
- accessTokenQuery: []
|
||||
|
|
@ -189,6 +194,11 @@ paths:
|
|||
This API endpoint uses the [User-Interactive Authentication API](/client-server-api/#user-interactive-authentication-api).
|
||||
|
||||
Deletes the given devices, and invalidates any access token associated with them.
|
||||
|
||||
{{% boxes/warning %}}
|
||||
Since this endpoint uses User-Interactive Authentication, it cannot be used when the access token was obtained
|
||||
via the [OAuth 2.0 API](/client-server-api/#oauth-20-api).
|
||||
{{% /boxes/warning %}}
|
||||
operationId: deleteDevices
|
||||
security:
|
||||
- accessTokenQuery: []
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ paths:
|
|||
deleted alongside the device.
|
||||
|
||||
This endpoint does not use the [User-Interactive Authentication API](/client-server-api/#user-interactive-authentication-api) because
|
||||
User-Interactive Authentication is designed to protect against attacks where the
|
||||
User-Interactive Authentication is designed to protect against attacks where
|
||||
someone gets hold of a single access token then takes over the account. This
|
||||
endpoint invalidates all access tokens for the user, including the token used in
|
||||
the request, and therefore the attacker is unable to take over the account in
|
||||
|
|
|
|||
176
data/api/client-server/oauth_server_metadata.yaml
Normal file
176
data/api/client-server/oauth_server_metadata.yaml
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
# Copyright 2025 The Matrix.org Foundation C.I.C.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
openapi: 3.1.0
|
||||
info:
|
||||
title: Matrix Client-Server OAuth 2.0 Server Metadata Discovery API
|
||||
version: 1.0.0
|
||||
paths:
|
||||
"/auth_metadata":
|
||||
get:
|
||||
summary: Get the OAuth 2.0 authorization server metadata.
|
||||
description: |-
|
||||
Gets the OAuth 2.0 authorization server metadata, as defined in
|
||||
[RFC 8414](https://datatracker.ietf.org/doc/html/rfc8414), including the
|
||||
endpoint URLs and the supported parameters that can be used by the
|
||||
clients.
|
||||
|
||||
This endpoint definition includes only the fields that are meaningful in
|
||||
the context of the Matrix specification. The full list of possible
|
||||
fields is available in the [OAuth Authorization Server Metadata
|
||||
registry](https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#authorization-server-metadata),
|
||||
and normative definitions of them are available in their respective
|
||||
RFCs.
|
||||
|
||||
{{% boxes/note %}}
|
||||
The authorization server metadata is relatively large and may change
|
||||
over time. Clients should:
|
||||
|
||||
- Cache the metadata appropriately based on HTTP caching headers
|
||||
- Refetch the metadata if it is stale
|
||||
{{% /boxes/note %}}
|
||||
operationId: getAuthMetadata
|
||||
responses:
|
||||
"200":
|
||||
description: The OAuth 2.0 authorization server metadata.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
issuer:
|
||||
type: string
|
||||
format: uri
|
||||
description: |-
|
||||
The authorization server's issuer identifier, which is a URL that uses the
|
||||
`https` scheme and has no query or fragment components.
|
||||
|
||||
This is not used in the context of the Matrix specification, but is required
|
||||
by [RFC 8414](https://datatracker.ietf.org/doc/html/rfc8414).
|
||||
authorization_endpoint:
|
||||
type: string
|
||||
format: uri
|
||||
description: |-
|
||||
URL of the authorization endpoint, necessary to use the authorization code
|
||||
grant.
|
||||
token_endpoint:
|
||||
type: string
|
||||
format: uri
|
||||
description: |-
|
||||
URL of the token endpoint, necessary to use the authorization code grant and
|
||||
the refresh token grant.
|
||||
revocation_endpoint:
|
||||
type: string
|
||||
format: uri
|
||||
description: |-
|
||||
URL of the revocation endpoint, necessary to log out a client by invalidating
|
||||
its access and refresh tokens.
|
||||
registration_endpoint:
|
||||
type: string
|
||||
format: uri
|
||||
description: |-
|
||||
URL of the client registration endpoint, necessary to perform dynamic
|
||||
registration of a client.
|
||||
response_types_supported:
|
||||
type: array
|
||||
description: |-
|
||||
List of OAuth 2.0 response type strings that the server supports at the
|
||||
authorization endpoint.
|
||||
|
||||
This array MUST contain at least the `code` value, for clients to be able to
|
||||
use the authorization code grant.
|
||||
items:
|
||||
type: string
|
||||
description: A response type that the server supports.
|
||||
grant_types_supported:
|
||||
type: array
|
||||
description: |-
|
||||
List of OAuth 2.0 grant type strings that the server supports at the token
|
||||
endpoint.
|
||||
|
||||
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.
|
||||
items:
|
||||
type: string
|
||||
description: A grant type that the server supports.
|
||||
response_modes_supported:
|
||||
type: array
|
||||
description: |-
|
||||
List of OAuth 2.0 response mode strings that the server supports at the
|
||||
authorization endpoint.
|
||||
|
||||
This array MUST contain at least the `query` and `fragment` values, for
|
||||
improved security in the authorization code grant.
|
||||
items:
|
||||
type: string
|
||||
description: A response mode that the server supports.
|
||||
code_challenge_methods_supported:
|
||||
type: array
|
||||
description: |-
|
||||
List of OAuth 2.0 Proof Key for Code Exchange (PKCE) code challenge methods
|
||||
that the server supports at the authorization endpoint.
|
||||
|
||||
This array MUST contain at least the `S256` value, for improved security in
|
||||
the authorization code grant.
|
||||
items:
|
||||
type: string
|
||||
description: A PKCE code challenge method that the server supports.
|
||||
prompt_values_supported:
|
||||
type: array
|
||||
description: |-
|
||||
List of OpenID Connect prompt values that the server supports at the
|
||||
authorization endpoint.
|
||||
|
||||
Only the `create` value defined in [Initiating User Registration via OpenID
|
||||
Connect](https://openid.net/specs/openid-connect-prompt-create-1_0.html) is
|
||||
supported, for a client to signal to the server that the user desires to
|
||||
register a new account.
|
||||
items:
|
||||
type: string
|
||||
description: A prompt value that the server supports.
|
||||
required:
|
||||
- issuer
|
||||
- authorization_endpoint
|
||||
- token_endpoint
|
||||
- revocation_endpoint
|
||||
- registration_endpoint
|
||||
- response_types_supported
|
||||
- grant_types_supported
|
||||
- response_modes_supported
|
||||
- code_challenge_methods_supported
|
||||
example: {
|
||||
"issuer": "https://account.example.com/",
|
||||
"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",
|
||||
"revocation_endpoint": "https://account.example.com/oauth2/revoke",
|
||||
"response_types_supported": ["code"],
|
||||
"grant_types_supported": ["authorization_code", "refresh_token"],
|
||||
"response_modes_supported": ["query", "fragment"],
|
||||
"code_challenge_methods_supported": ["S256"],
|
||||
}
|
||||
tags:
|
||||
- Session management
|
||||
servers:
|
||||
- url: "{protocol}://{hostname}{basePath}"
|
||||
variables:
|
||||
protocol:
|
||||
enum:
|
||||
- http
|
||||
- https
|
||||
default: https
|
||||
hostname:
|
||||
default: localhost:8008
|
||||
basePath:
|
||||
default: /_matrix/client/v1
|
||||
|
|
@ -89,11 +89,6 @@ paths:
|
|||
- leave
|
||||
- ban
|
||||
type: string
|
||||
required:
|
||||
- guest_can_join
|
||||
- num_joined_members
|
||||
- room_id
|
||||
- world_readable
|
||||
examples:
|
||||
response:
|
||||
value: {
|
||||
|
|
|
|||
|
|
@ -105,13 +105,31 @@ paths:
|
|||
example: ""
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: format
|
||||
x-addedInMatrixVersion: "1.16"
|
||||
description: |-
|
||||
The format to use for the returned data. `content` (the default) will
|
||||
return only the content of the state event. `event` will return the entire
|
||||
event in the usual format suitable for clients, including fields like event
|
||||
ID, sender and timestamp.
|
||||
example: event
|
||||
schema:
|
||||
type: string
|
||||
enum:
|
||||
- content
|
||||
- event
|
||||
responses:
|
||||
"200":
|
||||
description: The content of the state event.
|
||||
description: |-
|
||||
The content of the state event, or the entire client-formatted event
|
||||
if `?format=event` was used.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
oneOf:
|
||||
- type: object
|
||||
- $ref: "../../event-schemas/schema/core-event-schema/state_event.yaml"
|
||||
examples:
|
||||
response:
|
||||
value: {
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
title: RoomEvent
|
||||
description: Room Events have the following fields.
|
||||
allOf:
|
||||
- $ref: sync_room_event.yaml
|
||||
description: Room Events have the following fields.
|
||||
properties:
|
||||
room_id:
|
||||
description: |-
|
||||
The ID of the room associated with this event. Will not be present on events
|
||||
that arrive through `/sync`, despite being required everywhere else.
|
||||
type: string
|
||||
required:
|
||||
- room_id
|
||||
title: RoomEvent
|
||||
type: object
|
||||
- type: object
|
||||
properties:
|
||||
room_id:
|
||||
description: |-
|
||||
The ID of the room associated with this event. Will not be present on events
|
||||
that arrive through `/sync`, despite being required everywhere else.
|
||||
type: string
|
||||
required:
|
||||
- room_id
|
||||
|
|
|
|||
|
|
@ -17,27 +17,27 @@
|
|||
# be on events, so we give it a whole event structure as a base for room_event.
|
||||
# This base doesn't declare a room_id, which instead appears in the room_event.
|
||||
|
||||
allOf:
|
||||
- $ref: event.yaml
|
||||
title: SyncRoomEvent
|
||||
description: In addition to the Event fields, Room Events have the following additional
|
||||
fields.
|
||||
properties:
|
||||
event_id:
|
||||
description: The globally unique event identifier.
|
||||
type: string
|
||||
sender:
|
||||
description: Contains the fully-qualified ID of the user who sent this event.
|
||||
type: string
|
||||
origin_server_ts:
|
||||
description: Timestamp in milliseconds on originating homeserver
|
||||
when this event was sent.
|
||||
type: integer
|
||||
format: int64
|
||||
unsigned:
|
||||
$ref: unsigned_prop.yaml
|
||||
required:
|
||||
- event_id
|
||||
- sender
|
||||
- origin_server_ts
|
||||
title: SyncRoomEvent
|
||||
type: object
|
||||
allOf:
|
||||
- $ref: event.yaml
|
||||
- type: object
|
||||
properties:
|
||||
event_id:
|
||||
description: The globally unique event identifier.
|
||||
type: string
|
||||
sender:
|
||||
description: Contains the fully-qualified ID of the user who sent this event.
|
||||
type: string
|
||||
origin_server_ts:
|
||||
description: Timestamp in milliseconds on originating homeserver
|
||||
when this event was sent.
|
||||
type: integer
|
||||
format: int64
|
||||
unsigned:
|
||||
$ref: unsigned_prop.yaml
|
||||
required:
|
||||
- event_id
|
||||
- sender
|
||||
- origin_server_ts
|
||||
|
|
|
|||
|
|
@ -14,21 +14,21 @@
|
|||
|
||||
# See sync_room_event.yaml for why this file is here.
|
||||
|
||||
allOf:
|
||||
- $ref: sync_room_event.yaml
|
||||
title: SyncStateEvent
|
||||
description: In addition to the Room Event fields, State Events have the following
|
||||
additional fields.
|
||||
properties:
|
||||
state_key:
|
||||
description: A unique key which defines the overwriting semantics for this piece
|
||||
of room state. This value is often a zero-length string. The presence of this
|
||||
key makes this event a State Event.
|
||||
allOf:
|
||||
- $ref: sync_room_event.yaml
|
||||
- type: object
|
||||
properties:
|
||||
state_key:
|
||||
description: A unique key which defines the overwriting semantics for this piece
|
||||
of room state. This value is often a zero-length string. The presence of this
|
||||
key makes this event a State Event.
|
||||
|
||||
State keys starting with an `@` are reserved for referencing user IDs, such
|
||||
as room members. With the exception of a few events, state events set with a
|
||||
given user's ID as the state key MUST only be set by that user.
|
||||
type: string
|
||||
required:
|
||||
- state_key
|
||||
title: SyncStateEvent
|
||||
type: object
|
||||
State keys starting with an `@` are reserved for referencing user IDs, such
|
||||
as room members. With the exception of a few events, state events set with a
|
||||
given user's ID as the state key MUST only be set by that user.
|
||||
type: string
|
||||
required:
|
||||
- state_key
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ properties:
|
|||
"1.10": This property can act as a caption for the audio.
|
||||
format:
|
||||
description: |-
|
||||
The format used in the `formatted_body`. Currently only
|
||||
`org.matrix.custom.html` is supported.
|
||||
The format used in the `formatted_body`. This is required if `formatted_body`
|
||||
is specified. Currently only `org.matrix.custom.html` is supported.
|
||||
type: string
|
||||
x-addedInMatrixVersion: "1.10"
|
||||
formatted_body:
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ properties:
|
|||
type: string
|
||||
format:
|
||||
description: |-
|
||||
The format used in the `formatted_body`. Currently only
|
||||
`org.matrix.custom.html` is supported.
|
||||
The format used in the `formatted_body`. This is required if `formatted_body`
|
||||
is specified. Currently only `org.matrix.custom.html` is supported.
|
||||
type: string
|
||||
formatted_body:
|
||||
description: |-
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ properties:
|
|||
"1.10": This property can act as a caption for the file.
|
||||
format:
|
||||
description: |-
|
||||
The format used in the `formatted_body`. Currently only
|
||||
`org.matrix.custom.html` is supported.
|
||||
The format used in the `formatted_body`. This is required if `formatted_body`
|
||||
is specified. Currently only `org.matrix.custom.html` is supported.
|
||||
type: string
|
||||
x-addedInMatrixVersion: "1.10"
|
||||
formatted_body:
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ properties:
|
|||
"1.10": This property can act as a caption for the image.
|
||||
format:
|
||||
description: |-
|
||||
The format used in the `formatted_body`. Currently only
|
||||
`org.matrix.custom.html` is supported.
|
||||
The format used in the `formatted_body`. This is required if `formatted_body`
|
||||
is specified. Currently only `org.matrix.custom.html` is supported.
|
||||
type: string
|
||||
x-addedInMatrixVersion: "1.10"
|
||||
formatted_body:
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ properties:
|
|||
verification.
|
||||
format:
|
||||
description: |-
|
||||
The format used in the `formatted_body`. Currently only
|
||||
`org.matrix.custom.html` is supported.
|
||||
The format used in the `formatted_body`. This is required if `formatted_body`
|
||||
is specified. Currently only `org.matrix.custom.html` is supported.
|
||||
type: string
|
||||
formatted_body:
|
||||
description: |-
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ properties:
|
|||
type: string
|
||||
format:
|
||||
description: |-
|
||||
The format used in the `formatted_body`. Currently only
|
||||
`org.matrix.custom.html` is supported.
|
||||
The format used in the `formatted_body`. This is required if `formatted_body`
|
||||
is specified. Currently only `org.matrix.custom.html` is supported.
|
||||
type: string
|
||||
formatted_body:
|
||||
description: |-
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ properties:
|
|||
type: string
|
||||
format:
|
||||
description: |-
|
||||
The format used in the `formatted_body`. Currently only
|
||||
`org.matrix.custom.html` is supported.
|
||||
The format used in the `formatted_body`. This is required if `formatted_body`
|
||||
is specified. Currently only `org.matrix.custom.html` is supported.
|
||||
type: string
|
||||
formatted_body:
|
||||
description: |-
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ properties:
|
|||
"1.10": This property can act as a caption for the video.
|
||||
format:
|
||||
description: |-
|
||||
The format used in the `formatted_body`. Currently only
|
||||
`org.matrix.custom.html` is supported.
|
||||
The format used in the `formatted_body`. This is required if `formatted_body`
|
||||
is specified. Currently only `org.matrix.custom.html` is supported.
|
||||
type: string
|
||||
x-addedInMatrixVersion: "1.10"
|
||||
formatted_body:
|
||||
|
|
|
|||
140
data/schemas/oauth2-client-metadata.yaml
Normal file
140
data/schemas/oauth2-client-metadata.yaml
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
# Copyright 2025 The Matrix.org Foundation C.I.C.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
title: OAuthClientMetadata
|
||||
type: object
|
||||
description: |-
|
||||
This definition of the metadata specifies only the fields that are meaningful
|
||||
in the context of the Matrix specification. All the possible values are
|
||||
registered in the [OAuth Dynamic Client Registration Metadata registry](https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#client-metadata),
|
||||
and normative definitions of them are available in their respective RFCs.
|
||||
properties:
|
||||
client_uri:
|
||||
type: string
|
||||
format: uri
|
||||
description: |-
|
||||
A URL to a valid web page that SHOULD give the user more information about
|
||||
the client.
|
||||
|
||||
This URL MUST use the `https` scheme and SHOULD NOT require authentication
|
||||
to access. It MUST NOT use a user or password in the authority component
|
||||
of the URI.
|
||||
|
||||
The server MAY reject client registrations if this field is invalid or
|
||||
missing.
|
||||
|
||||
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`. The port number, path and query components MAY be different.
|
||||
|
||||
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`.
|
||||
client_name:
|
||||
type: string
|
||||
description: |-
|
||||
Human-readable name of the client to be presented to the user.
|
||||
|
||||
This field can be [localized](/client-server-api/#metadata-localization).
|
||||
logo_uri:
|
||||
type: string
|
||||
format: uri
|
||||
description: |-
|
||||
URL that references a logo for the client.
|
||||
|
||||
This URL MUST use the `https` scheme.
|
||||
|
||||
This field can be [localized](/client-server-api/#metadata-localization).
|
||||
tos_uri:
|
||||
type: string
|
||||
format: uri
|
||||
description: |-
|
||||
URL that points to a human-readable terms of service document for the
|
||||
client.
|
||||
|
||||
This URL MUST use the `https` scheme and SHOULD NOT require authentication
|
||||
to access. It MUST NOT use a user or password in the authority component
|
||||
of the URI.
|
||||
|
||||
If this field is set, the server SHOULD show or link to this URL.
|
||||
|
||||
This field can be [localized](/client-server-api/#metadata-localization).
|
||||
policy_uri:
|
||||
type: string
|
||||
format: uri
|
||||
description: |-
|
||||
URL that points to a human-readable policy document for the client.
|
||||
|
||||
This URL MUST use the `https` scheme and SHOULD NOT require authentication
|
||||
to access. It MUST NOT use a user or password in the authority component
|
||||
of the URI.
|
||||
|
||||
If this field is set, the server SHOULD show or link to this URL.
|
||||
|
||||
This field can be [localized](/client-server-api/#metadata-localization).
|
||||
redirect_uris:
|
||||
type: array
|
||||
description: |-
|
||||
Array of redirection URIs for use in redirect-based flows.
|
||||
|
||||
At least one URI is required to use the authorization code grant.
|
||||
|
||||
The server MUST perform [validation on redirect URIs](/client-server-api/#redirect-uri-validation).
|
||||
items:
|
||||
type: string
|
||||
format: uri
|
||||
description: A redirection URI.
|
||||
response_types:
|
||||
type: array
|
||||
description: |-
|
||||
Array of the OAuth 2.0 response types that the client may use.
|
||||
|
||||
This MUST include the `code` value to use the authorization code grant.
|
||||
|
||||
The server MUST ignore values that it does not understand.
|
||||
items:
|
||||
type: string
|
||||
description: A response type that the client may use.
|
||||
grant_types:
|
||||
type: array
|
||||
description: |-
|
||||
Array of the OAuth 2.0 grant types that the client may use.
|
||||
|
||||
This MUST include:
|
||||
- the `authorization_code` value to use the authorization code grant,
|
||||
- the `refresh_token` value to use the refresh token grant.
|
||||
|
||||
The server MUST ignore values that it does not understand.
|
||||
items:
|
||||
type: string
|
||||
description: A grant type that the client may use.
|
||||
token_endpoint_auth_method:
|
||||
type: string
|
||||
description: |-
|
||||
String indicator of the requested authentication method for the token
|
||||
endpoint.
|
||||
|
||||
The homeserver MUST support the `none` value, as most Matrix clients are
|
||||
client-side only, do not have a server component, and therefore are public
|
||||
clients.
|
||||
application_type:
|
||||
type: string
|
||||
description: |-
|
||||
Kind of the application.
|
||||
|
||||
The homeserver MUST support the `web` and `native` values to be able to
|
||||
perform [redirect URI validation](/client-server-api/#redirect-uri-validation).
|
||||
|
||||
Defaults to `web` if omitted.
|
||||
required:
|
||||
- client_uri
|
||||
Loading…
Reference in a new issue