diff --git a/changelogs/client_server/newsfragments/2147.new b/changelogs/client_server/newsfragments/2147.new new file mode 100644 index 00000000..c72bf35e --- /dev/null +++ b/changelogs/client_server/newsfragments/2147.new @@ -0,0 +1 @@ +Add `GET /_matrix/client/v1/auth_metadata`, as per [MSC2965](https://github.com/matrix-org/matrix-spec-proposals/pull/2965). diff --git a/changelogs/client_server/newsfragments/2149.feature b/changelogs/client_server/newsfragments/2149.feature new file mode 100644 index 00000000..6eff5607 --- /dev/null +++ b/changelogs/client_server/newsfragments/2149.feature @@ -0,0 +1 @@ +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. diff --git a/changelogs/client_server/newsfragments/2154.clarification b/changelogs/client_server/newsfragments/2154.clarification new file mode 100644 index 00000000..660e41b5 --- /dev/null +++ b/changelogs/client_server/newsfragments/2154.clarification @@ -0,0 +1 @@ +Add missing fields in example for `ExportedSessionData`. diff --git a/content/client-server-api/_index.md b/content/client-server-api/_index.md index 983ff961..a36bd051 100644 --- a/content/client-server-api/_index.md +++ b/content/client-server-api/_index.md @@ -1612,6 +1612,100 @@ managing devices for application services). 4. Refresh the access token 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. +#### Server metadata discovery + +{{% http-api spec="client-server" api="oauth_server_metadata" %}} + +#### 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-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:` | 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:` 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: ``! # $ % & ' ( ) * + , - . / : ; < = > ? @ [ ] ^ _ ` { | } ~`` + ### Account moderation #### Account locking diff --git a/data/api/client-server/definitions/key_backup_session_data.yaml b/data/api/client-server/definitions/key_backup_session_data.yaml index e2579142..b5878471 100644 --- a/data/api/client-server/definitions/key_backup_session_data.yaml +++ b/data/api/client-server/definitions/key_backup_session_data.yaml @@ -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 diff --git a/data/api/client-server/oauth_server_metadata.yaml b/data/api/client-server/oauth_server_metadata.yaml new file mode 100644 index 00000000..4cdb3aa6 --- /dev/null +++ b/data/api/client-server/oauth_server_metadata.yaml @@ -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