Merge remote-tracking branch 'matrix-org/master' into travis/general/room-versions

pull/1516/head
Travis Ralston 6 years ago
commit 3869f68a5c

@ -32,6 +32,10 @@ paths:
description: |-
This API is called by the homeserver when it wants to push an event
(or batch of events) to the application service.
Note that the application service should distinguish state events
from message events via the presence of a ``state_key``, rather than
via the event type.
operationId: sendTransaction
parameters:
- in: path
@ -44,7 +48,7 @@ paths:
x-example: "35"
- in: body
name: body
description: A list of events
description: A list of events.
schema:
type: object
example: {
@ -92,121 +96,6 @@ paths:
}
schema:
type: object
"/rooms/{roomAlias}":
get:
summary: Query if a room alias should exist on the application service.
description: |-
This endpoint is invoked by the homeserver on an application service to query
the existence of a given room alias. The homeserver will only query room
aliases inside the application service's ``aliases`` namespace. The
homeserver will send this request when it receives a request to join a
room alias within the application service's namespace.
operationId: queryRoomByAlias
parameters:
- in: path
name: roomAlias
type: string
description: The room alias being queried.
required: true
x-example: "#magicforest:example.com"
responses:
200:
description: |-
The application service indicates that this room alias exists. The
application service MUST have created a room and associated it with
the queried room alias using the client-server API. Additional
information about the room such as its name and topic can be set
before responding.
examples:
application/json: {
}
schema:
type: object
401:
description: |-
The homeserver has not supplied credentials to the application service.
Optional error information can be included in the body of this response.
examples:
application/json: {
"errcode": "COM.EXAMPLE.MYAPPSERVICE_UNAUTHORIZED"
}
schema:
$ref: ../client-server/definitions/errors/error.yaml
403:
description: |-
The credentials supplied by the homeserver were rejected.
examples:
application/json: {
"errcode": "COM.EXAMPLE.MYAPPSERVICE_FORBIDDEN"
}
schema:
$ref: ../client-server/definitions/errors/error.yaml
404:
description: |-
The application service indicates that this room alias does not exist.
Optional error information can be included in the body of this response.
examples:
application/json: {
"errcode": "COM.EXAMPLE.MYAPPSERVICE_NOT_FOUND"
}
schema:
$ref: ../client-server/definitions/errors/error.yaml
"/users/{userId}":
get:
summary: Query if a user should exist on the application service.
description: |-
This endpoint is invoked by the homeserver on an application service to query
the existence of a given user ID. The homeserver will only query user IDs
inside the application service's ``users`` namespace. The homeserver will
send this request when it receives an event for an unknown user ID in
the application service's namespace.
operationId: queryUserById
parameters:
- in: path
name: userId
type: string
description: The user ID being queried.
required: true
x-example: "@alice:example.com"
responses:
200:
description: |-
The application service indicates that this user exists. The application
service MUST create the user using the client-server API.
examples:
application/json: {
}
schema:
type: object
401:
description: |-
The homeserver has not supplied credentials to the application service.
Optional error information can be included in the body of this response.
examples:
application/json: {
"errcode": "COM.EXAMPLE.MYAPPSERVICE_UNAUTHORIZED"
}
schema:
$ref: ../client-server/definitions/errors/error.yaml
403:
description: |-
The credentials supplied by the homeserver were rejected.
examples:
application/json: {
"errcode": "COM.EXAMPLE.MYAPPSERVICE_FORBIDDEN"
}
schema:
$ref: ../client-server/definitions/errors/error.yaml
404:
description: |-
The application service indicates that this user does not exist.
Optional error information can be included in the body of this response.
examples:
application/json: {
"errcode": "COM.EXAMPLE.MYAPPSERVICE_NOT_FOUND"
}
schema:
$ref: ../client-server/definitions/errors/error.yaml
"/_matrix/app/unstable/thirdparty/protocol/{protocol}":
get:
summary: Retrieve metadata about a specific protocol that the application service supports.

@ -0,0 +1,86 @@
# Copyright 2016 OpenMarket Ltd
# Copyright 2018 New Vector Ltd
#
# 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.
swagger: '2.0'
info:
title: "Matrix Application Service API"
version: "1.0.0"
host: localhost:8008
schemes:
- https
- http
basePath: "/"
consumes:
- application/json
produces:
- application/json
paths:
"/rooms/{roomAlias}":
get:
summary: Query if a room alias should exist on the application service.
description: |-
This endpoint is invoked by the homeserver on an application service to query
the existence of a given room alias. The homeserver will only query room
aliases inside the application service's ``aliases`` namespace. The
homeserver will send this request when it receives a request to join a
room alias within the application service's namespace.
operationId: queryRoomByAlias
parameters:
- in: path
name: roomAlias
type: string
description: The room alias being queried.
required: true
x-example: "#magicforest:example.com"
responses:
200:
description: |-
The application service indicates that this room alias exists. The
application service MUST have created a room and associated it with
the queried room alias using the client-server API. Additional
information about the room such as its name and topic can be set
before responding.
examples:
application/json: {}
schema:
type: object
401:
description: |-
The homeserver has not supplied credentials to the application service.
Optional error information can be included in the body of this response.
examples:
application/json: {
"errcode": "COM.EXAMPLE.MYAPPSERVICE_UNAUTHORIZED"
}
schema:
$ref: ../client-server/definitions/errors/error.yaml
403:
description: |-
The credentials supplied by the homeserver were rejected.
examples:
application/json: {
"errcode": "COM.EXAMPLE.MYAPPSERVICE_FORBIDDEN"
}
schema:
$ref: ../client-server/definitions/errors/error.yaml
404:
description: |-
The application service indicates that this room alias does not exist.
Optional error information can be included in the body of this response.
examples:
application/json: {
"errcode": "COM.EXAMPLE.MYAPPSERVICE_NOT_FOUND"
}
schema:
$ref: ../client-server/definitions/errors/error.yaml

@ -0,0 +1,83 @@
# Copyright 2016 OpenMarket Ltd
# Copyright 2018 New Vector Ltd
#
# 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.
swagger: '2.0'
info:
title: "Matrix Application Service API"
version: "1.0.0"
host: localhost:8008
schemes:
- https
- http
basePath: "/"
consumes:
- application/json
produces:
- application/json
paths:
"/users/{userId}":
get:
summary: Query if a user should exist on the application service.
description: |-
This endpoint is invoked by the homeserver on an application service to query
the existence of a given user ID. The homeserver will only query user IDs
inside the application service's ``users`` namespace. The homeserver will
send this request when it receives an event for an unknown user ID in
the application service's namespace, such as a room invite.
operationId: queryUserById
parameters:
- in: path
name: userId
type: string
description: The user ID being queried.
required: true
x-example: "@alice:example.com"
responses:
200:
description: |-
The application service indicates that this user exists. The application
service MUST create the user using the client-server API.
examples:
application/json: {}
schema:
type: object
401:
description: |-
The homeserver has not supplied credentials to the application service.
Optional error information can be included in the body of this response.
examples:
application/json: {
"errcode": "COM.EXAMPLE.MYAPPSERVICE_UNAUTHORIZED"
}
schema:
$ref: ../client-server/definitions/errors/error.yaml
403:
description: |-
The credentials supplied by the homeserver were rejected.
examples:
application/json: {
"errcode": "COM.EXAMPLE.MYAPPSERVICE_FORBIDDEN"
}
schema:
$ref: ../client-server/definitions/errors/error.yaml
404:
description: |-
The application service indicates that this user does not exist.
Optional error information can be included in the body of this response.
examples:
application/json: {
"errcode": "COM.EXAMPLE.MYAPPSERVICE_NOT_FOUND"
}
schema:
$ref: ../client-server/definitions/errors/error.yaml

@ -66,7 +66,7 @@ paths:
medium:
type: string
description: The medium of the third party identifier.
enum: ["email"]
enum: ["email", "msisdn"]
address:
type: string
description: The third party identifier address.
@ -143,7 +143,21 @@ paths:
validation tokens when adding an email address to an account. This API's
parameters and response is identical to that of the HS API
|/register/email/requestToken|_ endpoint.
operationId: requestTokenTo3PID
operationId: requestTokenTo3PIDEmail
responses:
200:
description: An email was sent to the given address
description: An email was sent to the given address.
"/account/3pid/msisdn/requestToken":
post:
summary: Requests a validation token be sent to the given email address for the purpose of adding a phone number to an account.
description: |-
Proxies the identity server API ``validate/msisdn/requestToken``, but
first checks that the given phone number is **not** already associated
with an account on this Home Server. This API should be used to request
validation tokens when adding a phone number to an account. This API's
parameters and response is identical to that of the HS API
|/register/msisdn/requestToken|_ endpoint.
operationId: requestTokenTo3PIDMSISDN
responses:
200:
description: An SMS message was sent to the given phone number.

@ -39,16 +39,20 @@ paths:
apply the events implied by the request in the following order:
0. A default ``m.room.power_levels`` event, giving the room creator
(and not other members) permission to send state events.
(and not other members) permission to send state events. Overridden
by the ``power_level_content_override`` parameter.
1. Events set by the ``preset``.
1. Events set by the ``preset``. Currently these are the ``m.room.join_rules``,
``m.room.history_visibility``, and ``m.room.guest_access`` state events.
2. Events listed in ``initial_state``, in the order that they are
listed.
3. Events implied by ``name`` and ``topic``.
3. Events implied by ``name`` and ``topic`` (``m.room.name`` and ``m.room.topic``
state events).
4. Invite events implied by ``invite`` and ``invite_3pid``.
4. Invite events implied by ``invite`` and ``invite_3pid`` (``m.room.member`` with
``membership: invite`` and ``m.room.third_party_invite``).
The available presets do the following with respect to room state:
@ -60,6 +64,9 @@ paths:
``public_chat`` ``public`` ``shared`` ``forbidden``
======================== ============== ====================== ================ =========
The server will create a ``m.room.create`` event in the room with the
requesting user as the creator, alongside other keys provided in the
``creation_content``.
operationId: createRoom
security:
- accessToken: []
@ -70,14 +77,14 @@ paths:
schema:
type: object
example: {
"preset": "public_chat",
"room_alias_name": "thepub",
"name": "The Grand Duke Pub",
"topic": "All about happy hour",
"creation_content": {
"m.federate": false
}
"preset": "public_chat",
"room_alias_name": "thepub",
"name": "The Grand Duke Pub",
"topic": "All about happy hour",
"creation_content": {
"m.federate": false
}
}
properties:
visibility:
type: string
@ -98,6 +105,9 @@ paths:
created the room. For example, if this was set to "foo" and
sent to the homeserver "example.com" the complete room alias
would be ``#foo:example.com``.
The complete room alias will become the canonical alias for
the room.
name:
type: string
description: |-
@ -149,10 +159,10 @@ paths:
title: CreationContent
type: object
description: |-
Extra keys to be added to the content of the ``m.room.create``.
The server will clobber the following keys: ``creator``, ``room_version``.
Future versions of the specification may allow the server to clobber
other keys.
Extra keys, such as ``m.federate``, to be added to the content
of the `m.room.create`_ event. The server will clobber the following
keys: ``creator``, ``room_version``. Future versions of the specification
may allow the server to clobber other keys.
initial_state:
type: array
description: |-
@ -183,16 +193,25 @@ paths:
description: |-
Convenience parameter for setting various default state events
based on a preset.
If unspecified, the server should use the ``visibility`` to determine
which preset to use. A visbility of ``public`` equates to a preset of
``public_chat`` and ``private`` visibility equates to a preset of
``private_chat``.
is_direct:
type: boolean
description: |-
This flag makes the server set the ``is_direct`` flag on the
``m.room.member`` events sent to the users in ``invite`` and
``invite_3pid``. See `Direct Messaging`_ for more information.
guest_can_join:
type: boolean
power_level_content_override:
title: Power Level Event Content
type: object
description: |-
Allows guests to join the room. See `Guest Access`_ for more information.
The power level content to override in the default power level
event. This object is applied on top of the generated `m.room.power_levels`_
event content prior to it being sent to the room. Defaults to
overriding nothing.
responses:
200:
description: Information about the newly created room.
@ -204,10 +223,11 @@ paths:
type: string
description: |-
The created room's ID.
required: ['room_id']
examples:
application/json: {
"room_id": "!sefiuhWgwghwWgh:example.com"
}
"room_id": "!sefiuhWgwghwWgh:example.com"
}
400:
description: |-
@ -226,6 +246,5 @@ paths:
``M_INVALID_ROOM_STATE``).
schema:
"$ref": "definitions/errors/error.yaml"
tags:
- Room creation

@ -194,7 +194,7 @@ paths:
"user_id": "@alice:example.com",
"device_id": "JLAFKJWSCS",
"algorithms": [
"m.olm.curve25519-aes-sha256",
"m.olm.v1.curve25519-aes-sha256",
"m.megolm.v1.aes-sha"
],
"keys": {
@ -247,7 +247,7 @@ paths:
description: algorithm
example: "signed_curve25519"
example:
"@alice:example.com": { "JLAFKJWSCS": "curve25519" }
"@alice:example.com": { "JLAFKJWSCS": "signed_curve25519" }
required:
- one_time_keys
responses:

@ -0,0 +1,103 @@
# Copyright 2018 New Vector Ltd
#
# 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.
swagger: '2.0'
info:
title: "Matrix Client-Server OpenID API"
version: "1.0.0"
host: localhost:8008
schemes:
- https
- http
basePath: /_matrix/client/%CLIENT_MAJOR_VERSION%
consumes:
- application/json
produces:
- application/json
securityDefinitions:
$ref: definitions/security.yaml
paths:
"/user/{userId}/openid/request_token":
post:
summary: Get an OpenID token object to verify the requester's identity.
description: |-
Gets an OpenID token object that the requester may supply to another
service to verify their identity in Matrix. The generated token is only
valid for exchanging for user information from the federation API for
OpenID.
The access token generated is only valid for the OpenID API. It cannot
be used to request another OpenID access token or call ``/sync``, for
example.
operationId: requestOpenIdToken
security:
- accessToken: []
parameters:
- in: path
type: string
name: userId
description: |-
The user to request and OpenID token for. Should be the user who
is authenticated for the request.
required: true
x-example: "@alice:example.com"
- in: body
name: body
description: An empty object. Reserved for future expansion.
required: true
schema:
type: object
example: {}
responses:
200:
description: |-
OpenID token information. This response is nearly compatible with the
response documented in the `OpenID 1.0 Specification <http://openid.net/specs/openid-connect-core-1_0.html#TokenResponse>`_
with the only difference being the lack of an ``id_token``. Instead,
the Matrix homeserver's name is provided.
examples:
application/json: {
"access_token": "SomeT0kenHere",
"token_type": "Bearer",
"matrix_server_name": "example.com",
"expires_in": 3600,
}
schema:
type: object
properties:
access_token:
type: string
description: |-
An access token the consumer may use to verify the identity of
the person who generated the token. This is given to the federation
API ``GET /openid/userinfo``.
token_type:
type: string
description: The string ``Bearer``.
matrix_server_name:
type: string
description: |-
The homeserver domain the consumer should use when attempting to
verify the user's identity.
expires_in:
type: int
description: |-
The number of seconds before this token expires and a new one must
be generated.
required: ['access_token', 'token_type', 'matrix_server_name', 'expires_in']
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/errors/rate_limited.yaml"
tags:
- OpenID

@ -1,4 +1,5 @@
# Copyright 2016 OpenMarket Ltd
# Copyright 2018 New Vector Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -31,30 +32,30 @@ paths:
get:
summary: Gets the current pushers for the authenticated user
description: |-
Gets all currently active pushers for the authenticated user
Gets all currently active pushers for the authenticated user.
operationId: getPushers
security:
- accessToken: []
responses:
200:
description: The pushers for this user
description: The pushers for this user.
examples:
application/json: {
"pushers": [
{
"pushkey": "Xp/MzCt8/9DcSNE9cuiaoT5Ac55job3TdLSSmtmYl4A=",
"kind": "http",
"app_id": "face.mcapp.appy.prod",
"app_display_name": "Appy McAppface",
"device_display_name": "Alice's Phone",
"profile_tag": "xyz",
"lang": "en-US",
"data": {
"url": "https://example.com/_matrix/push/v1/notify"
}
"pushers": [
{
"pushkey": "Xp/MzCt8/9DcSNE9cuiaoT5Ac55job3TdLSSmtmYl4A=",
"kind": "http",
"app_id": "face.mcapp.appy.prod",
"app_display_name": "Appy McAppface",
"device_display_name": "Alice's Phone",
"profile_tag": "xyz",
"lang": "en-US",
"data": {
"url": "https://example.com/_matrix/push/v1/notify"
}
]
}
}
]
}
schema:
type: object
properties:
@ -70,7 +71,7 @@ paths:
pushkey:
type: string
description: |-
This is a unique identifier for this pusher. See `/set` for
This is a unique identifier for this pusher. See ``/set`` for
more detail.
Max length, 512 bytes.
kind:
@ -115,6 +116,19 @@ paths:
description: |-
Required if ``kind`` is ``http``. The URL to use to send
notifications to.
format:
type: string
description: |-
The format to use when sending notifications to the Push
Gateway.
required:
- pushkey
- app_id
- kind
- app_display_name
- device_display_name
- lang
- data
tags:
- Push notifications
"/pushers/set":
@ -130,23 +144,24 @@ paths:
parameters:
- in: body
name: pusher
description: The pusher information
description: The pusher information.
required: true
schema:
type: object
example: {
"lang": "en",
"kind": "http",
"app_display_name": "Mat Rix",
"device_display_name": "iPhone 9",
"profile_tag": "xxyyzz",
"app_id": "com.example.app.ios",
"pushkey": "APA91bHPRgkF3JUikC4ENAHEeMrd41Zxv3hVZjC9KtT8OvPVGJ-hQMRKRrZuJAEcl7B338qju59zJMjw2DELjzEvxwYv7hH5Ynpc1ODQ0aT4U4OFEeco8ohsN5PjL1iC2dNtk2BAokeMCg2ZXKqpc8FXKmhX94kIxQ",
"data": {
"url": "https://push-gateway.location.here"
},
"append": false
}
"lang": "en",
"kind": "http",
"app_display_name": "Mat Rix",
"device_display_name": "iPhone 9",
"profile_tag": "xxyyzz",
"app_id": "com.example.app.ios",
"pushkey": "APA91bHPRgkF3JUikC4ENAHEeMrd41Zxv3hVZjC9KtT8OvPVGJ-hQMRKRrZuJAEcl7B338qju59zJMjw2DELjzEvxwYv7hH5Ynpc1ODQ0aT4U4OFEeco8ohsN5PjL1iC2dNtk2BAokeMCg2ZXKqpc8FXKmhX94kIxQ",
"data": {
"url": "https://push-gateway.location.here/_matrix/push/v1/notify",
"format": "event_id_only"
},
"append": false
}
properties:
pushkey:
type: string
@ -157,11 +172,15 @@ paths:
for APNS or the Registration ID for GCM. If your notification
client has no such concept, use any unique identifier.
Max length, 512 bytes.
If the ``kind`` is ``"email"``, this is the email address to
send notifications to.
kind:
type: string
description: |-
The kind of pusher to configure. ``"http"`` makes a pusher that
sends HTTP pokes. ``null`` deletes the pusher.
sends HTTP pokes. ``"email"`` makes a pusher that emails the
user with unread notifications. ``null`` deletes the pusher.
app_id:
type: string
description: |-
@ -169,6 +188,8 @@ paths:
It is recommended that this end with the platform, such that
different platform versions get different app identifiers.
Max length, 64 chars.
If the ``kind`` is ``"email"``, this is ``"m.email"``.
app_display_name:
type: string
description: |-
@ -188,7 +209,7 @@ paths:
type: string
description: |-
The preferred language for receiving notifications (e.g. 'en'
or 'en-US')
or 'en-US').
data:
type: object
description: |-
@ -201,7 +222,17 @@ paths:
type: string
description: |-
Required if ``kind`` is ``http``. The URL to use to send
notifications to.
notifications to. MUST be an HTTPS URL with a path of
``/_matrix/push/v1/notify``.
example: "https://push-gateway.location.here/_matrix/push/v1/notify"
format:
type: string
description: |-
The format to send notifications in to Push Gateways if the
``kind`` is ``http``. The details about what fields the
homeserver should send to the push gateway are defined in the
`Push Gateway Specification`_. Currently the only format
available is 'event_id_only'.
append:
type: boolean
description: |-
@ -216,17 +247,17 @@ paths:
200:
description: The pusher was set.
examples:
application/json: {
}
application/json: {}
schema:
type: object # empty json object
type: object
description: An empty object.
400:
description: One or more of the pusher values were invalid.
examples:
application/json: {
"error": "Missing parameters: lang, data",
"errcode": "M_MISSING_PARAM"
}
"error": "Missing parameters: lang, data",
"errcode": "M_MISSING_PARAM"
}
schema:
"$ref": "definitions/errors/error.yaml"
429:

@ -196,11 +196,9 @@ paths:
description: |-
Proxies the identity server API ``validate/email/requestToken``, but
first checks that the given email address is not already associated
with an account on this Home Server. Note that, for consistency,
this API takes JSON objects, though the Identity Server API takes
``x-www-form-urlencoded`` parameters. See the Identity Server API for
with an account on this Home Server. See the Identity Server API for
further information.
operationId: requestTokenToRegister
operationId: requestTokenToRegisterEmail
parameters:
- in: body
name: body
@ -252,6 +250,71 @@ paths:
}
schema:
"$ref": "definitions/errors/error.yaml"
"/register/msisdn/requestToken":
post:
summary: Requests a validation token be sent to the given phone number for the purpose of registering an account
description: |-
Proxies the identity server API ``validate/msisdn/requestToken``, but
first checks that the given phone number is not already associated
with an account on this Home Server. See the Identity Server API for
further information.
operationId: requestTokenToRegisterMSISDN
parameters:
- in: body
name: body
schema:
type: object
properties:
id_server:
type: string
description: The ID server to send the onward request to as a hostname with an appended colon and port number if the port is not the default.
example: "id.matrix.org"
client_secret:
type: string
description: Client-generated secret string used to protect this session.
example: "this_is_my_secret_string"
country:
type: string
description: |-
The two-letter uppercase ISO country code that the number in
``phone_number`` should be parsed as if it were dialled from.
phone_number:
type: string
description: The phone number.
example: "example@example.com"
send_attempt:
type: number
description: Used to distinguish protocol level retries from requests to re-send the SMS message.
example: 1
required: ["client_secret", "country", "phone_number", "send_attempt"]
responses:
200:
description: |-
An SMS message has been sent to the specified phone number.
Note that this may be an SMS message containing the validation token or it may be informing
the user of an error.
examples:
application/json: {}
schema:
type: object
400:
description: |-
Part of the request was invalid. This may include one of the following error codes:
* ``M_THREEPID_IN_USE`` : The phone number is already registered to an account on this server.
However, if the home server has the ability to send SMS message, it is recommended that the server
instead send an SMS message to the user with instructions on how to reset their password.
This prevents malicious parties from being able to determine if a given phone number
has an account on the Home Server in question.
* ``M_SERVER_NOT_TRUSTED`` : The ``id_server`` parameter refers to an ID server
that is not trusted by this Home Server.
examples:
application/json: {
"errcode": "M_THREEPID_IN_USE",
"error": "The specified address is already in use"
}
schema:
"$ref": "definitions/errors/error.yaml"
"/account/password":
post:
summary: "Changes a user's password."
@ -319,10 +382,32 @@ paths:
.. |/register/email/requestToken| replace:: ``/register/email/requestToken``
.. _/register/email/requestToken: #post-matrix-client-%CLIENT_MAJOR_VERSION%-register-email-requesttoken
operationId: requestTokenToResetPassword
operationId: requestTokenToResetPasswordEmail
responses:
200:
description: An email was sent to the given address
"/account/password/msisdn/requestToken":
post:
summary: Requests a validation token be sent to the given phone number for the purpose of resetting a user's password.
description: |-
Proxies the identity server API ``validate/msisdn/requestToken``, but
first checks that the given phone number **is** associated with an account
on this Home Server. This API should be used to request
validation tokens when authenticating for the
`account/password` endpoint. This API's parameters and response are
identical to that of the HS API |/register/msisdn/requestToken|_ except that
`M_THREEPID_NOT_FOUND` may be returned if no account matching the
given email address could be found. The server may instead send an
SMS message to the given address prompting the user to create an account.
`M_THREEPID_IN_USE` may not be returned.
.. |/register/msisdn/requestToken| replace:: ``/register/msisdn/requestToken``
.. _/register/msisdn/requestToken: #post-matrix-client-%CLIENT_MAJOR_VERSION%-register-email-requesttoken
operationId: requestTokenToResetPasswordMSISDN
responses:
200:
description: An SMS message was sent to the given phone number.
"/account/deactivate":
post:
summary: "Deactivate a user's account."

@ -253,6 +253,14 @@ paths:
description: |-
Information on end-to-end device updates, as specified in
|device_lists_sync|_.
device_one_time_keys_count:
title: One-time keys count
type: object
additionalProperties:
type: integer
description: |-
Information on end-to-end encryption keys, as specified
in |device_lists_sync|_.
examples:
application/json: {
"next_batch": "s72595_4483_1934",

@ -0,0 +1,203 @@
# Copyright 2018 New Vector Ltd
#
# 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.
swagger: '2.0'
info:
title: "Matrix Identity Service Phone Number Associations API"
version: "1.0.0"
host: localhost:8090
schemes:
- https
- http
basePath: /_matrix/identity/api/v1
produces:
- application/json
paths:
"/validate/msisdn/requestToken":
post:
summary: Request a token for validating a phone number.
description: |-
Create a session for validating a phone number.
The identity service will send an SMS message containing a token. If
that token is presented to the identity service in the future, it
indicates that that user was able to read the SMS for that phone
number, and so we validate ownership of the phone number.
Note that Home Servers offer APIs that proxy this API, adding
additional behaviour on top, for example,
``/register/msisdn/requestToken`` is designed specifically for use when
registering an account and therefore will inform the user if the phone
number given is already registered on the server.
Note: for backwards compatibility with older versions of this
specification, the parameters may also be specified as
``application/x-form-www-urlencoded`` data. However, this usage is
deprecated.
operationId: msisdnRequestToken
parameters:
- in: body
name: body
schema:
type: object
example: {
"client_secret": "monkeys_are_GREAT",
"country": "GB",
"phone_number": "07700900001",
"send_attempt": 1
}
properties:
client_secret:
type: string
description: A unique string used to identify the validation attempt.
country:
type: string
description: |-
The two-letter uppercase ISO country code that the number in
``phone_number`` should be parsed as if it were dialled from.
phone_number:
type: string
description: The phone number to validate.
send_attempt:
type: integer
description: |-
Optional. If specified, the server will only send an SMS if
the ``send_attempt`` is a number greater than the most recent
one which it has seen (or if it has never seen one), scoped
to that ``country`` + ``phone_number`` + ``client_secret``
triple. This is to avoid repeatedly sending the same SMS in
the case of request retries between the POSTing user and the
identity service. The client should increment this value if
they desire a new SMS (e.g. a reminder) to be sent.
next_link:
type: string
description: |-
Optional. When the validation is completed, the identity
service will redirect the user to this URL.
required: ["client_secret", "country", "phone_number"]
responses:
200:
description:
Session created.
examples:
application/json: {
"sid": "1234"
}
schema:
type: object
properties:
sid:
type: string
description: The session ID.
400:
description: |
An error ocurred. Some possible errors are:
- ``M_INVALID_ADDRESS``: The phone number provided was invalid.
- ``M_SEND_ERROR``: The validation SMS could not be sent.
"/validate/msisdn/submitToken":
post:
summary: Validate ownership of a phone number.
description: |-
Validate ownership of a phone number.
If the three parameters are consistent with a set generated by a
``requestToken`` call, ownership of the phone number is considered to
have been validated. This does not publish any information publicly, or
associate the phone number address with any Matrix user
ID. Specifically, calls to ``/lookup`` will not show a binding.
Note: for backwards compatibility with older versions of this
specification, the parameters may also be specified as
``application/x-form-www-urlencoded`` data. However, this usage is
deprecated.
operationId: msisdnSubmitTokenPost
parameters:
- in: body
name: body
schema:
type: object
example: {
"sid": "1234",
"client_secret": "monkeys_are_GREAT",
"token": "atoken"
}
properties:
sid:
type: string
description: The session ID, generated by the ``requestToken`` call.
client_secret:
type: string
description: The client secret that was supplied to the ``requestToken`` call.
token:
type: string
description: The token generated by the ``requestToken`` call and sent to the user.
required: ["sid", "client_secret", "token"]
responses:
200:
description:
The success of the validation.
examples:
application/json: {
"success": true
}
schema:
type: object
properties:
success:
type: boolean
description: Whether the validation was successful or not.
get:
summary: Validate ownership of a phone number.
description: |-
Validate ownership of a phone number.
If the three parameters are consistent with a set generated by a
``requestToken`` call, ownership of the phone number address is
considered to have been validated. This does not publish any
information publicly, or associate the phone number with any Matrix
user ID. Specifically, calls to ``/lookup`` will not show a binding.
Note that, in contrast with the POST version, this endpoint will be
used by end-users, and so the response should be human-readable.
operationId: msisdnSubmitTokenGet
parameters:
- in: query
type: string
name: sid
required: true
description: The session ID, generated by the ``requestToken`` call.
x-example: 1234
- in: query
type: string
name: client_secret
required: true
description: The client secret that was supplied to the ``requestToken`` call.
x-example: monkeys_are_GREAT
- in: query
type: string
name: token
required: true
description: The token generated by the ``requestToken`` call and sent to the user.
x-example: atoken
responses:
"200":
description: Phone number is validated.
"3xx":
description: |-
Phone number address is validated, and the ``next_link`` parameter
was provided to the ``requestToken`` call. The user must be
redirected to the URL provided by the ``next_link`` parameter.
"4xx":
description:
Validation failed.

@ -1,4 +1,5 @@
# Copyright 2016 OpenMarket Ltd
# Copyright 2018 New Vector Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -19,7 +20,7 @@ host: localhost:8008
schemes:
- https
- http
basePath: /_matrix/push/%CLIENT_MAJOR_VERSION%
basePath: /_matrix/push/v1
consumes:
- application/json
produces:
@ -38,14 +39,14 @@ paths:
Notifications about a particular event will normally cause the user to be
alerted in some way. It is therefore necessary to perform duplicate
suppression for such notifications using the `event_id` field to avoid
suppression for such notifications using the ``event_id`` field to avoid
retries of this HTTP API causing duplicate alerts. The operation of
updating counts of unread notifications should be idempotent and
therefore do not require duplicate suppression.
Notifications are sent to the URL configured when the pusher is
created. This means that the HTTP path may be different depending on the
push gateway.
Notifications are sent to the URL configured when the pusher is created.
This means that the HTTP path may be different depending on the push
gateway.
operationId: notify
parameters:
- in: body
@ -55,36 +56,36 @@ paths:
schema:
type: object
example: {
"notification": {
"id": "$3957tyerfgewrf384",
"room_id": "!slw48wfj34rtnrf:example.com",
"type": "m.room.message",
"sender": "@exampleuser:matrix.org",
"sender_display_name": "Major Tom",
"room_name": "Mission Control",
"room_alias": "#exampleroom:matrix.org",
"prio": "high",
"content": {
"msgtype": "m.text",
"body": "I'm floating in a most peculiar way."
},
"counts": {
"unread" : 2,
"missed_calls": 1
},
"devices": [
{
"app_id": "org.matrix.matrixConsole.ios",
"pushkey": "V2h5IG9uIGVhcnRoIGRpZCB5b3UgZGVjb2RlIHRoaXM/",
"pushkey_ts": 12345678,
"data" : {},
"tweaks": {
"sound": "bing"
}
"notification": {
"id": "$3957tyerfgewrf384",
"room_id": "!slw48wfj34rtnrf:example.com",
"type": "m.room.message",
"sender": "@exampleuser:matrix.org",
"sender_display_name": "Major Tom",
"room_name": "Mission Control",
"room_alias": "#exampleroom:matrix.org",
"prio": "high",
"content": {
"msgtype": "m.text",
"body": "I'm floating in a most peculiar way."
},
"counts": {
"unread" : 2,
"missed_calls": 1
},
"devices": [
{
"app_id": "org.matrix.matrixConsole.ios",
"pushkey": "V2h5IG9uIGVhcnRoIGRpZCB5b3UgZGVjb2RlIHRoaXM/",
"pushkey_ts": 12345678,
"data" : {},
"tweaks": {
"sound": "bing"
}
]
}
}
]
}
}
required: ["notification"]
properties:
notification:
@ -111,14 +112,10 @@ paths:
type: string
description: |-
The type of the event as in the event's ``type`` field.
Required if the notification relates to a specific
Matrix event.
sender:
type: string
description: |-
The sender of the event as in the corresponding event field.
Required if the notification relates to a specific
Matrix event.
sender_display_name:
type: string
description: |-
@ -148,15 +145,16 @@ paths:
type: object
title: EventContent
description: |-
The ``content`` field from the event, if present. If the
event had no content field, this field is omitted.
The ``content`` field from the event, if present. The pusher
may omit this if the event had no content or for any other
reason.
counts:
type: object
title: Counts
description: |-
This is a dictionary of the current number of unacknowledged
communications for the recipient user. Counts whose value is
zero are omitted.
zero should be omitted.
properties:
unread:
type: integer
@ -180,10 +178,10 @@ paths:
app_id:
type: string
description: |-
The app_id given when the pusher was created.
The ``app_id`` given when the pusher was created.
pushkey:
type: string
description: The pushkey given when the pusher was created.
description: The ``pushkey`` given when the pusher was created.
pushkey_ts:
type: integer
description: |-
@ -202,13 +200,14 @@ paths:
description: |-
A dictionary of customisations made to the way this
notification is to be presented. These are added by push rules.
required: ['app_id', 'pushkey']
responses:
200:
description: A list of rejected push keys.
examples:
application/json: {
"rejected": [ "V2h5IG9uIGVhcnRoIGRpZCB5b3UgZGVjb2RlIHRoaXM/" ]
}
"rejected": [ "V2h5IG9uIGVhcnRoIGRpZCB5b3UgZGVjb2RlIHRoaXM/" ]
}
schema:
type: object # empty json object
properties:
@ -222,7 +221,8 @@ paths:
pushkeys and remove the associated pushers. It may not
necessarily be the notification in the request that failed:
it could be that a previous notification to the same pushkey
failed.
failed. May be empty.
items:
type: string
description: A pushkey
description: A pushkey that has been rejected.
required: ['rejected']

@ -24,6 +24,8 @@ consumes:
- application/json
produces:
- application/json
securityDefinitions:
$ref: definitions/security.yaml
paths:
"/backfill/{roomId}":
get:
@ -33,6 +35,8 @@ paths:
Starting from the PDU ID(s) given in the ``v`` argument, the PDUs that preceded it
are retrieved, up to the total number given by the ``limit``.
operationId: backfillRoom
security:
- signedRequest: []
parameters:
- in: path
name: roomId
@ -85,6 +89,8 @@ paths:
walk of the ``prev_events`` for the ``latest_events``, ignoring any events in ``earliest_events``
and stopping at the ``limit``.
operationId: getMissingPreviousEvents
security:
- signedRequest: []
parameters:
- in: path
name: roomId

@ -0,0 +1,71 @@
# Copyright 2018 New Vector Ltd
#
# 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.
type: object
title: m.presence
description: |-
An EDU representing presence updates for users of the sending homeserver.
allOf:
- $ref: ../edu.yaml
- type: object
properties:
edu_type:
type: enum
enum: ['m.presence']
description: The string ``m.presence``
example: "m.presence"
content:
type: object
description: The presence updates and requests.
title: Presence Update
properties:
push:
type: array
description: |-
A list of presence updates that the receiving server is likely
to be interested in.
items:
type: object
title: User Presence Update
properties:
user_id:
type: string
description: The user ID this presence EDU is for.
example: "@john:matrix.org"
presence:
type: enum
enum: ['offline', 'unavailable', 'online']
description: The presence of the user.
example: "online"
status_msg:
type: string
description: An optional description to accompany the presence.
example: "Making cupcakes"
last_active_ago:
type: integer
format: int64
description: |-
The number of milliseconds that have elapsed since the user
last did something.
example: 5000
currently_active:
type: boolean
description: |-
True if the user is likely to be interacting with their
client. This may be indicated by the user having a
``last_active_ago`` within the last few minutes. Defaults
to false.
example: true
required: ['user_id', 'presence', 'last_active_ago']
required: ['push']

@ -0,0 +1,46 @@
# Copyright 2018 New Vector Ltd
#
# 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.
type: object
title: m.presence_accept
description: |-
An EDU representing approval for the observing user to subscribe to the
presence of the the observed user.
allOf:
- $ref: ../edu.yaml
- type: object
properties:
edu_type:
type: enum
enum: ['m.presence_accept']
description: The string ``m.presence_accept``
example: "m.presence_accept"
content:
type: object
description: The invite information.
title: Invite Information
properties:
observed_user:
type: string
description: |-
The user ID that has approved the ``observer_user`` to
subscribe to their presence.
example: "@alice:elsewhere.com"
observer_user:
type: string
description: |-
The user ID that requested to subscribe to the presence of
the ``observed_user``.
example: "@john:matrix.org"
required: ['observer_user', 'observed_user']

@ -0,0 +1,55 @@
# Copyright 2018 New Vector Ltd
#
# 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.
type: object
title: m.presence_deny
description: |-
An EDU representing a declination or revocation for the observing user
to subscribe to the presence of the observed user.
example: {
"origin": "domain.com",
"destination": "elsewhere.org",
"edu_type": "m.presence_deny",
"content": {
"observed_user": "@alice:elsewhere.org",
"observer_user": "@john:domain.com"
}
}
allOf:
- $ref: ../edu.yaml
- type: object
properties:
edu_type:
type: enum
enum: ['m.presence_deny']
description: The string ``m.presence_deny``
example: "m.presence_deny"
content:
type: object
description: The invite information.
title: Invite Information
properties:
observed_user:
type: string
description: |-
The user ID that has declined or revoked the ``observer_user`` from
subscribing to their presence.
example: "@alice:elsewhere.com"
observer_user:
type: string
description: |-
The user ID that requested to subscribe to the presence of
the ``observed_user``.
example: "@john:matrix.org"
required: ['observer_user', 'observed_user']

@ -0,0 +1,45 @@
# Copyright 2018 New Vector Ltd
#
# 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.
type: object
title: m.presence_invite
description: |-
An EDU representing a request to subscribe to a user's presence.
allOf:
- $ref: ../edu.yaml
- type: object
properties:
edu_type:
type: enum
enum: ['m.presence_invite']
description: The string ``m.presence_invite``
example: "m.presence_invite"
content:
type: object
description: The invite information.
title: Invite Information
properties:
observed_user:
type: string
description: |-
The user ID the ``observer_user`` would like to subscribe
to the presence of.
example: "@alice:elsewhere.com"
observer_user:
type: string
description: |-
The user ID that is wishing to subscribe to the presence of
the ``observed_user``.
example: "@john:matrix.org"
required: ['observer_user', 'observed_user']

@ -0,0 +1,82 @@
# Copyright 2018 New Vector Ltd
#
# 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.
type: object
title: m.receipt
description: |-
An EDU representing receipt updates for users of the sending homeserver.
When receiving receipts, the server should only update entries that are
listed in the EDU. Receipts previously received that do not appear in the
EDU should not be removed or otherwise manipulated.
allOf:
- $ref: ../edu.yaml
- type: object
properties:
edu_type:
type: enum
enum: ['m.receipt']
description: The string ``m.receipt``
example: "m.receipt"
content:
type: object
description: |-
Receipts for a particular room. The string key is the room ID for
which the receipts under it belong.
additionalProperties:
type: object
title: Room Receipts
properties:
# We strongly define the receipt type to help spec future ones later
# on. At that point, m.read can become optional (maybe).
"m.read":
type: object
description: Read receipts for users in the room.
title: User Read Receipt
properties:
event_ids:
type: array
description: |-
The extremity event IDs that the user has read up to.
minItems: 1
maxItems: 1
items:
type: string
example: ['$read_this_event:matrix.org']
data:
type: object
description: Metadata for the read receipt.
title: Read Receipt Metadata
properties:
ts:
type: integer
format: int64
description: |-
A POSIX timestamp in milliseconds for when the user read
the event specified in the read receipt.
example: 1533358089009
required: ['ts']
required: ['event_ids', 'data']
required: ['m.read']
example: {
"!some_room:domain.com": {
"m.read": {
"@john:matrix.org": {
"event_ids": ["$read_this_event:matrix.org"],
"data": {
"ts": 1533358089009
}
}
}
}
}

@ -0,0 +1,46 @@
# Copyright 2018 New Vector Ltd
#
# 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.
type: object
title: m.typing
description: A typing notification EDU for a user in a room.
allOf:
- $ref: ../edu.yaml
- type: object
properties:
edu_type:
type: enum
enum: ['m.typing']
description: The string ``m.typing``
example: "m.typing"
content:
type: object
description: The typing notification.
title: Typing Notification
properties:
room_id:
type: string
description: |-
The room where the user's typing status has been updated.
example: "!somewhere:matrix.org"
user_id:
type: string
description: |-
The user ID that has had their typing status changed.
example: "@john:matrix.org"
typing:
type: boolean
description: Whether the user is typing in the room or not.
example: true
required: ['room_id', 'user_id', 'typing']

@ -0,0 +1,19 @@
# Copyright 2018 New Vector Ltd
#
# 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.
signedRequest:
type: apiKey
description: |-
The ``Authorization`` header defined in the `Authentication`_ section.
name: Authorization
in: header

@ -78,7 +78,10 @@ properties:
required: ['sha256']
depth:
type: integer
description: The maximum depth of the ``prev_events``, plus one.
description: |-
The maximum depth of the ``prev_events``, plus one. Must be less than the
maximum value for an integer (2^63 - 1). If the room's depth is already at
the limit, the depth must be set to the limit.
example: 12
auth_events:
type: array

@ -24,6 +24,8 @@ consumes:
- application/json
produces:
- application/json
securityDefinitions:
$ref: definitions/security.yaml
paths:
"/event_auth/{roomId}/{eventId}":
get:
@ -31,6 +33,8 @@ paths:
description: |-
Retrieves the complete auth chain for a given event.
operationId: getEventAuth
security:
- signedRequest: []
parameters:
- in: path
name: roomId
@ -72,6 +76,8 @@ paths:
bottom-up after sorting each chain by depth then by event ID. The differences
are then discovered and returned as the response to this API call.
operationId: compareEventAuth
security:
- signedRequest: []
parameters:
- in: path
name: roomId

@ -22,6 +22,8 @@ schemes:
basePath: /_matrix/federation/v1
produces:
- application/json
securityDefinitions:
$ref: definitions/security.yaml
paths:
"/state/{roomId}":
get:
@ -29,6 +31,8 @@ paths:
description: |-
Retrieves a snapshot of a room's state at a given event.
operationId: getRoomState
security:
- signedRequest: []
parameters:
- in: path
name: roomId
@ -74,6 +78,8 @@ paths:
event IDs. This performs the same function as calling ``/state/{roomId}``,
however this returns just the event IDs rather than the full events.
operationId: getRoomStateIds
security:
- signedRequest: []
parameters:
- in: path
name: roomId
@ -117,6 +123,8 @@ paths:
description: |-
Retrieves a single event.
operationId: getEvent
security:
- signedRequest: []
parameters:
- in: path
name: eventId

@ -24,6 +24,8 @@ consumes:
- application/json
produces:
- application/json
securityDefinitions:
$ref: definitions/security.yaml
paths:
"/invite/{roomId}/{eventId}":
put:
@ -33,6 +35,8 @@ paths:
homeserver and the invited homeserver, it can be sent to all of the servers in the
room by the inviting homeserver.
operationId: sendInvite
security:
- signedRequest: []
parameters:
- in: path
name: roomId

@ -24,6 +24,8 @@ consumes:
- application/json
produces:
- application/json
securityDefinitions:
$ref: definitions/security.yaml
paths:
"/make_join/{roomId}/{userId}":
get:
@ -32,6 +34,8 @@ paths:
Asks the receiving server to return information that the sending
server will need to prepare a join event to get into the room.
operationId: makeJoin
security:
- signedRequest: []
parameters:
- in: path
name: roomId
@ -178,6 +182,8 @@ paths:
Submits a signed join event to the resident server for it
to accept it into the room's graph.
operationId: sendJoin
security:
- signedRequest: []
parameters:
- in: path
name: roomId

@ -24,6 +24,8 @@ consumes:
- application/json
produces:
- application/json
securityDefinitions:
$ref: definitions/security.yaml
paths:
"/make_leave/{roomId}/{userId}":
get:
@ -32,6 +34,8 @@ paths:
Asks the receiving server to return information that the sending
server will need to prepare a leave event to get out of the room.
operationId: makeLeave
security:
- signedRequest: []
parameters:
- in: path
name: roomId
@ -151,6 +155,8 @@ paths:
Submits a signed leave event to the resident server for it
to accept it into the room's graph.
operationId: sendLeave
security:
- signedRequest: []
parameters:
- in: path
name: roomId

@ -0,0 +1,63 @@
# Copyright 2017 Kamax.io
# Copyright 2018 New Vector Ltd
#
# 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.
swagger: '2.0'
info:
title: "Matrix Federation OpenID API"
version: "1.0.0"
host: localhost:8448
schemes:
- https
basePath: /_matrix/federation/v1
produces:
- application/json
paths:
"/openid/userinfo":
get:
summary: Exchange an OpenID token for user information
description: |-
Exchanges an OpenID access token for information about the user
who generated the token. Currently this only exposes the Matrix
User ID of the owner.
operationId: exchangeOpenIdToken
parameters:
- in: path
name: access_token
type: string
description: |-
The OpenID access token to get information about the owner for.
required: true
x-example: SomeT0kenHere
responses:
200:
description: |-
Information about the user who generated the OpenID access token.
schema:
type: object
properties:
sub:
type: string
description: The Matrix User ID who generated the token.
example: "@alice:example.com"
required: ['sub']
401:
description: The token was not recognized or has expired.
schema:
$ref: "../client-server/definitions/errors/error.yaml"
examples:
application/json: {
"errcode": "M_UNKNOWN_TOKEN",
"error": "Access token unknown or expired"
}

@ -22,6 +22,8 @@ schemes:
basePath: /_matrix/federation/v1
produces:
- application/json
securityDefinitions:
$ref: definitions/security.yaml
paths:
"/publicRooms":
get:
@ -31,6 +33,8 @@ paths:
rooms that are listed on another homeserver's directory, just those
listed on the receiving homeserver's directory.
operationId: getPublicRooms
security:
- signedRequest: []
parameters:
- in: query
name: limit

@ -23,6 +23,8 @@ schemes:
basePath: /_matrix/federation/v1
produces:
- application/json
securityDefinitions:
$ref: definitions/security.yaml
paths:
"/query/{queryType}":
get:
@ -32,6 +34,8 @@ paths:
arguments are dependent on which type of query is being made. Known query types
are specified as their own endpoints as an extension to this definition.
operationId: queryInfo
security:
- signedRequest: []
parameters:
- in: path
name: queryType
@ -54,6 +58,8 @@ paths:
Servers may wish to cache the response to this query to avoid requesting the
information too often.
operationId: queryRoomDirectory
security:
- signedRequest: []
parameters:
- in: query
name: room_alias
@ -110,6 +116,9 @@ paths:
Servers may wish to cache the response to this query to avoid requesting the
information too often.
operationId: queryProfile
security:
- signedRequest: []
parameters:
- in: query
name: user_id

@ -24,6 +24,8 @@ consumes:
- application/json
produces:
- application/json
securityDefinitions:
$ref: definitions/security.yaml
paths:
"/exchange_third_party_invite/{roomId}":
put:
@ -34,6 +36,8 @@ paths:
an invite as per the `Inviting to a room`_ section before returning a
response to this request.
operationId: exchangeThirdPartyInvite
security:
- signedRequest: []
parameters:
- in: path
name: roomId

@ -24,6 +24,8 @@ consumes:
- application/json
produces:
- application/json
securityDefinitions:
$ref: definitions/security.yaml
paths:
"/send/{txnId}":
put:
@ -36,6 +38,8 @@ paths:
The sending server must wait and retry for a 200 OK response before sending a
transaction with a different ``txnId`` to the receiving server.
operationId: sendTransaction
security:
- signedRequest: []
parameters:
- in: path
name: txnId

@ -0,0 +1 @@
Clarify ``changed`` field behaviour in device tracking process

@ -0,0 +1,7 @@
End-to-end encryption for group chats:
- Olm and Megolm messaging algorithms.
- ``m.room.encrypted``, ``m.room.encryption``, ``m.room_key`` events.
- Device verification process.
- ``device_one_time_keys_count`` sync parameter.
- ``device_lists:left`` sync parameter.

@ -0,0 +1 @@
Document and improve client interaction with pushers.

@ -0,0 +1 @@
``POST /account/3pid/msisdn/requestToken``, ``POST /register/msisdn/requestToken``, and ``POST /account/password/msisdn/requestToken``

@ -0,0 +1 @@
Clarify how access tokens are meant to be supplied to the homeserver.

@ -0,0 +1 @@
Document additional parameters on the ``/createRoom`` API.

@ -0,0 +1 @@
Guests can now call /context and /event to fetch events

@ -0,0 +1,14 @@
{
"content": {
"algorithm": "m.megolm.v1.aes-sha2",
"ciphertext": "AwgAEnACgAkLmt6qF84IK++J7UDH2Za1YVchHyprqTqsg...",
"device_id": "RJYKSTBOIE",
"sender_key": "IlRMeOPX2e0MurIyfWEucYBRVOEEUMrOHqn/8mLqMjA",
"session_id": "X3lUlvLELLYxeTx4yOVu6UDpasGEVO0Jbu+QFnm0cKQ"
},
"event_id": "$WLGTSEFSEF:localhost",
"room_id": "!Cuyf34gef24t:localhost",
"origin_server_ts": 1476648761524,
"sender": "@example:localhost",
"type": "m.room.encrypted"
}

@ -0,0 +1,14 @@
{
"type": "m.room.encrypted",
"sender": "@example:localhost",
"content": {
"algorithm": "m.olm.v1.curve25519-aes-sha2",
"sender_key": "Szl29ksW/L8yZGWAX+8dY1XyFi+i5wm+DRhTGkbMiwU",
"ciphertext": {
"7qZcfnBmbEGzxxaWfBjElJuvn7BZx+lSz/SvFrDF/z8": {
"type": 0,
"body": "AwogGJJzMhf/S3GQFXAOrCZ3iKyGU5ZScVtjI0KypTYrW..."
}
}
}
}

@ -0,0 +1,13 @@
{
"content": {
"algorithm": "m.megolm.v1.aes-sha2",
"rotation_period_ms": 604800000,
"rotation_period_msgs": 100
},
"event_id": "$WLGTSEFJJKJ:localhost",
"origin_server_ts": 1476648761524,
"sender": "@example:localhost",
"room_id": "!Cuyf34gef24t:localhost",
"state_key": "",
"type": "m.room.encryption"
}

@ -0,0 +1,9 @@
{
"content": {
"algorithm": "m.megolm.v1.aes-sha2",
"room_id": "!Cuyf34gef24t:localhost",
"session_id": "X3lUlvLELLYxeTx4yOVu6UDpasGEVO0Jbu+QFnm0cKQ",
"session_key": "AgAAAADxKHa9uFxcXzwYoNueL5Xqi69IkD4sni8LlfJL7qNBEY..."
},
"type": "m.room_key"
}

@ -0,0 +1,61 @@
---
allOf:
- $ref: core-event-schema/event.yaml
description: |-
This event type is used when sending encrypted events. It can be used either
within a room (in which case it will have all of the `Room Event fields`_), or
as a `to-device`_ event.
properties:
content:
properties:
algorithm:
type: string
enum:
- m.olm.curve25519-aes-sha256
- m.megolm.v1.aes-sha
description: |-
The encryption algorithm used to encrypt this event. The
value of this field determines which other properties will be
present.
ciphertext:
oneOf:
- type: string
- type: object
additionalProperties:
type: object
title: CiphertextInfo
properties:
body:
type: string
description: The encrypted payload.
type:
type: integer
description: The Olm message type.
description: |-
The encrypted content of the event. Either the encrypted payload
itself, in the case of a Megolm event, or a map from the recipient
Curve25519 identity key to ciphertext information, in the case of an
Olm event. For more details, see `Messaging Algorithms`_.
sender_key:
type: string
description: The Curve25519 key of the sender.
device_id:
type: string
description: The ID of the sending device. Required with Megolm.
session_id:
type: string
description: |-
The ID of the session used to encrypt the message. Required with
Megolm.
required:
- algorithm
- sender_key
- ciphertext
type: object
type:
enum:
- m.room.encrypted
type: string
type: object

@ -0,0 +1,36 @@
---
allOf:
- $ref: core-event-schema/state_event.yaml
description: Defines how messages sent in this room should be encrypted.
properties:
content:
properties:
algorithm:
type: string
enum:
- "m.megolm.v1.aes-sha2"
description: |-
The encryption algorithm to be used to encrypt messages sent in this
room.
rotation_period_ms:
type: integer
description: |-
How long the session should be used before changing it. ``604800000``
(a week) is the recommended default.
rotation_period_msgs:
type: integer
description: |-
How many messages should be sent before changing the session. ``100`` is the
recommended default.
required:
- algorithm
type: object
state_key:
description: A zero-length string.
pattern: '^$'
type: string
type:
enum:
- m.room.encryption
type: string
type: object

@ -0,0 +1,35 @@
---
allOf:
- $ref: core-event-schema/event.yaml
description: |-
This event type is used to exchange keys for end-to-end encryption. Typically
it is encrypted as an ``m.room.encrypted`` event, then sent as a `to-device`_ event.
properties:
content:
properties:
algorithm:
type: string
enum: ["m.megolm.v1.aes-sha2"]
description: |-
The encryption algorithm the key in this event is to be used with.
room_id:
type: string
description: The room where the key is used.
session_id:
type: string
description: The ID of the session that the key is for.
session_key:
type: string
description: The key to be exchanged.
required:
- algorithm
- room_id
- session_id
- session_key
type: object
type:
enum:
- m.room_key
type: string
type: object

@ -32,6 +32,12 @@ complete specification to be merged correctly. These characters are:
If you find yourself using ``^`` or beyond, you should rethink your document
layout if possible.
Correct capitalisation for long section names
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Headings should start with a capital letter, and use lower-case otherwise.
TODOs
-----

@ -1,6 +1,6 @@
{% import 'tables.tmpl' as tables -%}
``{{definition.title}}`` Schema
``{{definition.title}}`` schema
{{(11 + definition.title | length) * title_kind}}
{% if 'description' in definition %}

@ -1,4 +1,5 @@
.. Copyright 2016 OpenMarket Ltd
.. Copyright 2018 New Vector Ltd
..
.. Licensed under the Apache License, Version 2.0 (the "License");
.. you may not use this file except in compliance with the License.
@ -39,7 +40,7 @@ This version of the specification is generated from
Application Services
--------------------
Application services are passive and can only observe events from a given
homeserver. They can inject events into rooms they are participating in.
homeserver (HS). They can inject events into rooms they are participating in.
They cannot prevent events from being sent, nor can they modify the content of
the event being sent. In order to observe events from a homeserver, the
homeserver needs to be configured to pass certain types of traffic to the
@ -68,7 +69,13 @@ Registration
Application services register "namespaces" of user IDs, room aliases and room IDs.
These namespaces are represented as regular expressions. An application service
is said to be "interested" in a given event if one of the IDs in the event match
the regular expression provided by the application service. An application
the regular expression provided by the application service, such as the room having
an alias or ID in the relevant namespaces. Similarly, the application service is
said to be interested in a given event if one of the application service's namespaced
users is the target of the event, or is a joined member of the room where the event
occurred.
An application
service can also state whether they should be the only ones who
can manage a specified namespace. This is referred to as an "exclusive"
namespace. An exclusive namespace prevents humans and other application
@ -83,7 +90,7 @@ regular expressions and look like:
users:
- exclusive: true
regex: @irc.freenode.net_.*
regex: @_irc.freenode.net_.*
The registration is represented by a series of key-value pairs, which this
@ -105,12 +112,17 @@ traffic to the AS is:
aliases: [] # Namespaces of room aliases which should be delegated to the AS
rooms: [] # Namespaces of room ids which should be delegated to the AS
Exclusive user and alias namespaces should begin with an underscore after the
sigil to avoid collisions with other users on the homeserver. Application
services should additionally attempt to identify the service they represent
in the reserved namespace. For example, ``@_irc_.*`` would be a good namespace
to register for an application service which deals with IRC.
.. WARNING::
If the homeserver in question has multiple application services, each
``as_token`` and ``id`` MUST be unique per application service as these are
used to identify the application service. The homeserver MUST enforce this.
Homeserver -> Application Service API
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -163,6 +175,10 @@ this request (e.g. to join a room alias).
the application service about information about the entity such as room ID to
room alias mappings.
{{query_user_as_http_api}}
{{query_room_as_http_api}}
HTTP APIs
+++++++++
@ -185,29 +201,34 @@ homeserver.
Identity assertion
++++++++++++++++++
The client-server API infers the user ID from the ``access_token`` provided in
every request. It would be an annoying amount of book-keeping to maintain tokens
for every virtual user. It would be preferable if the application service could
use the CS API with its own ``as_token`` instead, and specify the virtual user
they wish to be acting on behalf of. For real users, this would require
additional permissions granting the AS permission to masquerade as a matrix user.
every request. To avoid the application service from having to keep track of each
user's access token, the application service should identify itself to the Client-Server
API by providing its ``as_token`` for the ``access_token`` alongside the user the
application service would like to masquerade as.
Inputs:
- Application service token (``access_token``)
- Application service token (``as_token``)
- User ID in the AS namespace to act as.
Notes:
- This will apply on all aspects of the CS API, except for Account Management.
- This applies to all aspects of the Client-Server API, except for Account Management.
- The ``as_token`` is inserted into ``access_token`` which is usually where the
client token is. This is done on purpose to allow application services to
reuse client SDKs.
client token is, such as via the query string or ``Authorization`` header. This
is done on purpose to allow application services to reuse client SDKs.
- The ``access_token`` should be supplied through the ``Authorization`` header where
possible to prevent the token appearing in HTTP request logs by accident.
::
The application service may specify the virtual user to act as through use of a
``user_id`` query string parameter on the request. The user specified in the query
string must be covered by one of the application service's ``user`` namespaces. If
the parameter is missing, the homeserver is to assume the application service intends
to act as the user implied by the ``sender_localpart`` property of the registration.
An example request would be::
/path?access_token=$token&user_id=$userid
GET /_matrix/client/%CLIENT_MAJOR_VERSION%/account/whoami?user_id=@_irc_user:example.org
Authorization: Bearer YourApplicationServiceTokenHere
Query Parameters:
access_token: The application service token
user_id: The desired user ID to act as.
Timestamp massaging
+++++++++++++++++++
@ -217,17 +238,17 @@ need to be able to adjust the ``origin_server_ts`` value to do this.
Inputs:
- Application service token (``as_token``)
- Desired timestamp
- Desired timestamp (in milliseconds since the unix epoch)
Notes:
- This will only apply when sending events.
::
/path?access_token=$token&ts=$timestamp
PUT /_matrix/client/r0/rooms/!somewhere:domain.com/send/m.room.message/txnId?ts=1534535223283
Authorization: Bearer YourApplicationServiceTokenHere
Query Parameters added to the send event APIs only:
access_token: The application service token
ts: The desired timestamp
Content: The event to send, as per the Client-Server API.
Server admin style permissions
++++++++++++++++++++++++++++++
@ -250,12 +271,13 @@ including the AS token on a ``/register`` request, along with a login type of
::
/register?access_token=$as_token
POST /_matrix/client/%CLIENT_MAJOR_VERSION%/register
Authorization: Bearer YourApplicationServiceTokenHere
Content:
{
type: "m.login.application_service",
username: "<desired user localpart in AS namespace>"
username: "_irc_example"
}
Application services which attempt to create users or aliases *outside* of
@ -264,78 +286,19 @@ normal users who attempt to create users or aliases *inside* an application
service-defined namespace will receive the same ``M_EXCLUSIVE`` error code,
but only if the application service has defined the namespace as ``exclusive``.
ID conventions
~~~~~~~~~~~~~~
.. TODO-spec
- Giving HSes the freedom to namespace still feels like the Right Thing here.
- Exposing a public API provides the consistency which was the main complaint
against namespacing.
- This may have knock-on effects for the AS registration API. E.g. why don't
we let ASes specify the *URI* regex they want?
This concerns the well-defined conventions for mapping 3P network IDs to matrix
IDs, which we expect clients to be able to do by themselves.
User IDs
++++++++
Matrix users may wish to directly contact a virtual user, e.g. to send an email.
The URI format is a well-structured way to represent a number of different ID
types, including:
- MSISDNs (``tel``)
- Email addresses (``mailto``)
- IRC nicks (``irc`` - https://tools.ietf.org/html/draft-butcher-irc-url-04)
- XMPP (XEP-0032)
- SIP URIs (RFC 3261)
As a result, virtual user IDs SHOULD relate to their URI counterpart. This
mapping from URI to user ID can be expressed in a number of ways:
Using ``/sync`` and ``/events``
+++++++++++++++++++++++++++++++
- Expose a C-S API on the HS which takes URIs and responds with user IDs.
- Munge the URI with the user ID.
Application services wishing to use ``/sync`` or ``/events`` from the Client-Server
API MUST do so with a virtual user (provide a ``user_id`` via the query string). It
is expected that the application service use the transactions pushed to it to
handle events rather than syncing with the user implied by ``sender_localpart``.
Exposing an API would allow HSes to internally map user IDs however they like,
at the cost of an extra round trip (of which the response can be cached).
Munging the URI would allow clients to apply the mapping locally, but would force
user X on service Y to always map to the same munged user ID. Considering the
exposed API could just be applying this munging, there is more flexibility if
an API is exposed.
::
GET /_matrix/app/%CLIENT_MAJOR_VERSION%/user?uri=$url_encoded_uri
Returns 200 OK:
{
user_id: <complete user ID on local HS>
}
Room Aliases
++++++++++++
We may want to expose some 3P network rooms so Matrix users can join them directly,
e.g. IRC rooms. We don't want to expose every 3P network room though, e.g.
``mailto``, ``tel``. Rooms which are publicly accessible (e.g. IRC rooms) can be
exposed as an alias by the application service. Private rooms
(e.g. sending an email to someone) should not
be exposed in this way, but should instead operate using normal invite/join semantics.
Therefore, the ID conventions discussed below are only valid for public rooms which
expose room aliases.
Matrix users may wish to join XMPP rooms (e.g. using XEP-0045) or IRC rooms. In both
cases, these rooms can be expressed as URIs. For consistency, these "room" URIs
SHOULD be mapped in the same way as "user" URIs.
::
Event fields
~~~~~~~~~~~~
GET /_matrix/app/%CLIENT_MAJOR_VERSION%/alias?uri=$url_encoded_uri
.. TODO-TravisR: Fix this section to be a general "3rd party networks" section
Returns 200 OK:
{
alias: <complete room alias on local HS>
}
Event fields
++++++++++++
We recommend that any events that originated from a remote network should
include an ``external_url`` field in their content to provide a way for Matrix
clients to link into the 'native' client from which the event originated.

@ -198,10 +198,6 @@ previously obtained credentials in the form of an ``access_token`` query
parameter or through an Authorization Header of ``Bearer $access_token``.
An access token is typically obtained via the `Login`_ or `Registration`_ processes.
When credentials are required but missing or invalid, the HTTP call will
return with a status of 401 and the error code, ``M_MISSING_TOKEN`` or
``M_UNKNOWN_TOKEN`` respectively.
.. NOTE::
This specification does not mandate a particular format for the access
@ -209,6 +205,24 @@ return with a status of 401 and the error code, ``M_MISSING_TOKEN`` or
to choose an appropriate format. Server implementors may like to investigate
`macaroons <macaroon_>`_.
Using access tokens
~~~~~~~~~~~~~~~~~~~
Access tokens may be provided in two ways, both of which the homeserver MUST
support:
1. Via a query string parameter, ``access_token=TheTokenHere``.
#. Via a request header, ``Authorization: Bearer TheTokenHere``.
Clients are encouraged to use the ``Authorization`` header where possible
to prevent the access token being leaked in access/HTTP logs. The query
string should only be used in cases where the ``Authorization`` header is
inaccessible for the client.
When credentials are required but missing or invalid, the HTTP call will
return with a status of 401 and the error code, ``M_MISSING_TOKEN`` or
``M_UNKNOWN_TOKEN`` respectively.
Relationship between access tokens and devices
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

@ -119,6 +119,11 @@ Email associations
{{email_associations_is_http_api}}
Phone number associations
~~~~~~~~~~~~~~~~~~~~~~~~~
{{phone_associations_is_http_api}}
General
~~~~~~~

@ -21,12 +21,6 @@ Matrix optionally supports end-to-end encryption, allowing rooms to be created
whose conversation contents is not decryptable or interceptable on any of the
participating homeservers.
.. WARNING::
End to end encryption is being worked on and will be coming soon. This
section is incomplete. You can read more about what's underway at
http://matrix.org/speculator/spec/drafts%2Fe2e/client_server/unstable.html#end-to-end-encryption.
Key Distribution
----------------
Encryption and Authentication in Matrix is based around public-key
@ -159,7 +153,7 @@ It is therefore expected that each client will maintain a list of devices for a
number of users (in practice, typically each user with whom we share an
encrypted room). Furthermore, it is likely that this list will need to be
persisted between invocations of the client application (to preserve device
verification data and to alert Alice if Bob suddently gets a new
verification data and to alert Alice if Bob suddenly gets a new
device).
Alice's client can maintain a list of Bob's devices via the following
@ -176,9 +170,10 @@ process:
flag.
#. During its normal processing of responses to |/sync|_, Alice's client
inspects the |device_lists|_ field. If it is tracking the device lists of
any of the listed users, then it marks the device lists for those users
outdated, and initiates another request to |/keys/query|_ for them.
inspects the ``changed`` property of the |device_lists|_ field. If it is
tracking the device lists of any of the listed users, then it marks the
device lists for those users outdated, and initiates another request to
|/keys/query|_ for them.
#. Periodically, Alice's client stores the ``next_batch`` field of the result
from |/sync|_ in persistent storage. If Alice later restarts her client, it
@ -214,6 +209,18 @@ process:
that the first request's results are ignored (possibly by cancelling the
request).
.. Note::
When Bob and Alice share a room, with Bob tracking Alice's devices, she may leave
the room and then add a new device. Bob will not be notified of this change,
as he doesn't share a room anymore with Alice. When they start sharing a
room again, Bob has an out-of-date list of Alice's devices. In order to address
this issue, Bob's homeserver will add Alice's user ID to the ``changed`` property of
the ``device_lists`` field, thus Bob will update his list of Alice's devices as part
of his normal processing. Note that Bob can also be notified when he stops sharing
any room with Alice by inspecting the ``left`` property of the ``device_lists``
field, and as a result should remove her from its list of tracked users.
.. |device_lists| replace:: ``device_lists``
.. _`device_lists`: `device_lists_sync`_
@ -228,10 +235,238 @@ A homeserver should rate-limit the number of one-time keys that a given user or
remote server can claim. A homeserver should discard the public part of a one
time key once it has given that key to another user.
Device verification
-------------------
Before Alice sends Bob encrypted data, or trusts data received from him, she
may want to verify that she is actually communicating with him, rather than a
man-in-the-middle. This verification process requires an out-of-band channel:
there is no way to do it within Matrix without trusting the administrators of
the homeservers.
In Matrix, the basic process for device verification is for Alice to verify
that the public Ed25519 signing key she received via ``/keys/query`` for Bob's
device corresponds to the private key in use by Bob's device. For now, it is
recommended that clients provide mechanisms by which the user can see:
1. The public part of their device's Ed25519 signing key, encoded using
`unpadded Base64`_.
2. The list of devices in use for each user in a room, along with the public
Ed25519 signing key for each device, again encoded using unpadded Base64.
Alice can then meet Bob in person, or contact him via some other trusted
medium, and ask him to read out the Ed25519 key shown on his device. She
compares this with the value shown for his device on her client.
Device verification may reach one of several conclusions. For example:
* Alice may "accept" the device. This means that she is satisfied that the
device belongs to Bob. She can then encrypt sensitive material for that
device, and knows that messages received were sent from that device.
* Alice may "reject" the device. She will do this if she knows or suspects
that Bob does not control that device (or equivalently, does not trust
Bob). She will not send sensitive material to that device, and cannot trust
messages apparently received from it.
* Alice may choose to skip the device verification process. She is not able
to verify that the device actually belongs to Bob, but has no reason to
suspect otherwise. The encryption protocol continues to protect against
passive eavesdroppers.
.. NOTE::
Once the signing key has been verified, it is then up to the encryption
protocol to verify that a given message was sent from a device holding that
Ed25519 private key, or to encrypt a message so that it may only be
decrypted by such a device. For the Olm protocol, this is documented at
https://matrix.org/git/olm/about/docs/signing.rst.
Messaging Algorithms
--------------------
Messaging Algorithm Names
~~~~~~~~~~~~~~~~~~~~~~~~~
Messaging algorithm names use the extensible naming scheme used throughout this
specification. Algorithm names that start with ``m.`` are reserved for
algorithms defined by this specification. Implementations wanting to experiment
with new algorithms must be uniquely globally namespaced following Java's package
naming conventions.
Algorithm names should be short and meaningful, and should list the primitives
used by the algorithm so that it is easier to see if the algorithm is using a
broken primitive.
A name of ``m.olm.v1`` is too short: it gives no information about the primitives
in use, and is difficult to extend for different primitives. However a name of
``m.olm.v1.ecdh-curve25519-hdkfsha256.hmacsha256.hkdfsha256-aes256-cbc-hmac64sha256``
is too long despite giving a more precise description of the algorithm: it adds
to the data transfer overhead and sacrifices clarity for human readers without
adding any useful extra information.
``m.olm.v1.curve25519-aes-sha2``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The name ``m.olm.v1.curve25519-aes-sha2`` corresponds to version 1 of the Olm
ratchet, as defined by the `Olm specification`_. This uses:
* Curve25519 for the initial key agreement.
* HKDF-SHA-256 for ratchet key derivation.
* Curve25519 for the root key ratchet.
* HMAC-SHA-256 for the chain key ratchet.
* HKDF-SHA-256, AES-256 in CBC mode, and 8 byte truncated HMAC-SHA-256 for authenticated encryption.
Devices that support Olm must include "m.olm.v1.curve25519-aes-sha2" in their
list of supported messaging algorithms, must list a Curve25519 device key, and
must publish Curve25519 one-time keys.
An event encrypted using Olm has the following format:
.. code:: json
{
"type": "m.room.encrypted",
"content": {
"algorithm": "m.olm.v1.curve25519-aes-sha2",
"sender_key": "<sender_curve25519_key>",
"ciphertext": {
"<device_curve25519_key>": {
"type": 0,
"body": "<encrypted_payload_base_64>"
}
}
}
}
``ciphertext`` is a mapping from device Curve25519 key to an encrypted payload
for that device. ``body`` is a Base64-encoded Olm message body. ``type`` is an
integer indicating the type of the message body: 0 for the initial pre-key
message, 1 for ordinary messages.
Olm sessions will generate messages with a type of 0 until they receive a
message. Once a session has decrypted a message it will produce messages with
a type of 1.
When a client receives a message with a type of 0 it must first check if it
already has a matching session. If it does then it will use that session to
try to decrypt the message. If there is no existing session then the client
must create a new session and use the new session to decrypt the message. A
client must not persist a session or remove one-time keys used by a session
until it has successfully decrypted a message using that session.
Messages with type 1 can only be decrypted with an existing session. If there
is no matching session, the client must treat this as an invalid message.
The plaintext payload is of the form:
.. code:: json
{
"type": "<type of the plaintext event>",
"content": "<content for the plaintext event>",
"sender": "<sender_user_id>",
"recipient": "<recipient_user_id>",
"recipient_keys": {
"ed25519": "<our_ed25519_key>"
},
"keys": {
"ed25519": "<sender_ed25519_key>"
}
}
The type and content of the plaintext message event are given in the payload.
Other properties are included in order to prevent an attacker from publishing
someone else's curve25519 keys as their own and subsequently claiming to have
sent messages which they didn't.
``sender`` must correspond to the user who sent the event, ``recipient`` to
the local user, and ``recipient_keys`` to the local ed25519 key.
Clients must confirm that the ``sender_key`` and the ``ed25519`` field value
under the ``keys`` property match the keys returned by |/keys/query|_ for
the given user, and must also verify the signature of the payload. Without
this check, a client cannot be sure that the sender device owns the private
part of the ed25519 key it claims to have in the Olm payload.
This is crucial when the ed25519 key corresponds to a verified device.
``m.megolm.v1.aes-sha2``
~~~~~~~~~~~~~~~~~~~~~~~~
The name ``m.megolm.v1.aes-sha2`` corresponds to version 1 of the Megolm
ratchet, as defined by the `Megolm specification`_. This uses:
* HMAC-SHA-256 for the hash ratchet.
* HKDF-SHA-256, AES-256 in CBC mode, and 8 byte truncated HMAC-SHA-256 for authenticated encryption.
* Ed25519 for message authenticity.
Devices that support Megolm must support Olm, and include "m.megolm.v1.aes-sha2" in
their list of supported messaging algorithms.
An event encrypted using Megolm has the following format:
.. code:: json
{
"type": "m.room.encrypted",
"content": {
"algorithm": "m.megolm.v1.aes-sha2",
"sender_key": "<sender_curve25519_key>",
"device_id": "<sender_device_id>",
"session_id": "<outbound_group_session_id>",
"ciphertext": "<encypted_payload_base_64>"
}
}
The encrypted payload can contain any message event. The plaintext is of the form:
.. code:: json
{
"type": "<event_type>",
"content": "<event_content>",
"room_id": "<the room_id>"
}
We include the room ID in the payload, because otherwise the homeserver would
be able to change the room a message was sent in.
Clients must guard against replay attacks by keeping track of the ratchet indices
of Megolm sessions. They should reject messages with a ratchet index that they
have already decrypted. Care should be taken in order to avoid false positives, as a
client may decrypt the same event twice as part of its normal processing.
As with Olm events, clients must confirm that the ``sender_key`` belongs to the user
who sent the message. The same reasoning applies, but the sender ed25519 key has to be
inferred from the ``keys.ed25519`` property of the event which established the Megolm
session.
In order to enable end-to-end encryption in a room, clients can send a
``m.room.encryption`` state event specifying ``m.megolm.v1.aes-sha2`` as its
``algorithm`` property.
When creating a Megolm session in a room, clients must share the corresponding session
key using Olm with the intended recipients, so that they can decrypt future messages
encrypted using this session. A ``m.room_key`` event is used to do this. Clients
must also handle ``m.room_key`` events sent by other devices in order to decrypt their
messages.
Protocol definitions
--------------------
Events
~~~~~~
{{m_room_encryption_event}}
{{m_room_encrypted_event}}
{{m_room_key_event}}
Key management API
~~~~~~~~~~~~~~~~~~
{{keys_cs_http_api}}
@ -249,6 +484,9 @@ specified). The client is expected to use |/keys/query|_ or |/keys/changes|_
for the equivalent functionality after an initial sync, as documented in
`Tracking the device list for a user`_.
It also adds a ``one_time_keys_count`` property. Note the spelling difference
with the ``one_time_key_counts`` property in the |/keys/upload|_ response.
.. todo: generate this from a swagger definition?
.. device_lists: { changed: ["@user:server", ... ]},
@ -258,6 +496,9 @@ Parameter Type Description
============ =========== =====================================================
device_lists DeviceLists Optional. Information on e2e device updates. Note:
only present on an incremental sync.
|device_otk| {string: Optional. For each key algorithm, the number of
integer} unclaimed one-time keys currently held on the server
for this device.
============ =========== =====================================================
``DeviceLists``
@ -265,10 +506,20 @@ device_lists DeviceLists Optional. Information on e2e device updates. Note:
========= ========= =============================================
Parameter Type Description
========= ========= =============================================
changed [string] List of users who have updated their device identity keys
since the previous sync response.
changed [string] List of users who have updated their device identity keys,
or who now share an encrypted room with the client since
the previous sync response.
left [string] List of users with whom we do not share any encrypted rooms
anymore since the previous sync response.
========= ========= =============================================
.. NOTE::
For optimal performance, Alice should be added to ``changed`` in Bob's sync only
when she adds a new device, or when Alice and Bob now share a room but didn't
share any room previously. However, for the sake of simpler logic, a server
may add Alice to ``changed`` when Alice and Bob share a new room, even if they
previously already shared a room.
Example response:
@ -281,17 +532,27 @@ Example response:
"changed": [
"@alice:example.com",
],
"left": [
"@bob:example.com",
],
},
"device_one_time_keys_count": {
"curve25519": 10,
"signed_curve25519": 20
}
}
.. References
.. _ed25519: http://ed25519.cr.yp.to/
.. _curve25519: https://cr.yp.to/ecdh.html
.. _`Olm specification`: http://matrix.org/docs/spec/olm.html
.. _`Megolm specification`: http://matrix.org/docs/spec/megolm.html
.. _`Signing JSON`: ../appendices.html#signing-json
.. |m.olm.v1.curve25519-aes-sha2| replace:: ``m.olm.v1.curve25519-aes-sha2``
.. |device_otk| replace:: device_one_time_keys_count
.. |/keys/upload| replace:: ``/keys/upload``
.. _/keys/upload: #post-matrix-client-%CLIENT_MAJOR_VERSION%-keys-upload

@ -50,6 +50,8 @@ The following API endpoints are allowed to be accessed by guest accounts for
retrieving events:
* `GET /rooms/:room_id/state <#get-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-state>`_
* `GET /rooms/:room_id/context/:event_id <#get-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-context-eventid>`_
* `GET /rooms/:room_id/event/:event_id <#get-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-event-eventid>`_
* `GET /rooms/:room_id/state/:event_type/:state_key <#get-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-state-eventtype-statekey>`_
* `GET /rooms/:room_id/messages <#get-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-messages>`_
* `GET /rooms/:room_id/initialSync <#get-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-initialsync>`_

@ -0,0 +1,24 @@
.. Copyright 2018 New Vector Ltd.
..
.. 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.
OpenID
======
.. _module:openid:
This module allows users to verify their identity with a third party service. The
third party service does need to be matrix-aware in that it will need to know to
resolve matrix homeservers to exchange the user's token for identity information.
{{openid_cs_http_api}}

@ -622,3 +622,5 @@ shouldn't be sent in the push itself where possible. Instead, Push Gateways
should send a "sync" command to instruct the client to get new events from the
homeserver directly.
.. _`Push Gateway Specification`: ../push_gateway/unstable.html

@ -67,4 +67,9 @@ This describes the format used by "HTTP" pushers to send notifications of
events to Push Gateways. If the endpoint returns an HTTP error code, the
homeserver SHOULD retry for a reasonable amount of time using exponential backoff.
When pushing notifications for events, the hoemserver is expected to include all of
the event-related fields in the ``/notify`` request. When the homeserver is performing
a push where the ``format`` is ``"event_id_only"``, only the ``event_id``, ``room_id``,
``counts``, and ``devices`` are required to be populated.
{{push_notifier_push_http_api}}

@ -606,7 +606,7 @@ the events it is missing.
{{backfill_ss_http_api}}
Retrieving events
----------------
-----------------
In some circumstances, a homeserver may be missing a particular event or information
about the room which cannot be easily determined from backfilling. These APIs provide
@ -812,68 +812,58 @@ should be retrieved for.
{{public_rooms_ss_http_api}}
Typing Notifications
--------------------
When a server's users send typing notifications, those notifications need to
be sent to other servers in the room so their users are aware of the same
state. Receiving servers should verify that the user is in the room, and is
a user belonging to the sending server.
{{definition_ss_event_schemas_m_typing}}
Presence
--------
The server API for presence is based entirely on exchange of the following
EDUs. There are no PDUs or Federation Queries involved.
Performing a presence update and poll subscription request::
EDU type: m.presence
Content keys:
push: (optional): list of push operations.
Each should be an object with the following keys:
user_id: string containing a User ID
presence: "offline"|"unavailable"|"online"|"free_for_chat"
status_msg: (optional) string of free-form text
last_active_ago: milliseconds since the last activity by the user
Servers should only send presence updates for users that the receiving server
would be interested in. This can include the receiving server sharing a room
with a given user, or a user on the receiving server has added one of the
sending server's users to their presence list.
poll: (optional): list of strings giving User IDs
Clients may define lists of users that they are interested in via "Presence
Lists" through the `Client-Server API`_. When users are added to a presence
list, a ``m.presence_invite`` EDU is sent to them. The user may then accept
or deny their involvement in the list by sending either an ``m.presence_accept``
or ``m.presence_deny`` EDU back.
unpoll: (optional): list of strings giving User IDs
The presence of this combined message is two-fold: it informs the recipient
server of the current status of one or more users on the sending server (by the
``push`` key), and it maintains the list of users on the recipient server that
the sending server is interested in receiving updates for, by adding (by the
``poll`` key) or removing them (by the ``unpoll`` key). The ``poll`` and
``unpoll`` lists apply *changes* to the implied list of users; any existing IDs
that the server sent as ``poll`` operations in a previous message are not
removed until explicitly requested by a later ``unpoll``.
On receipt of a message containing a non-empty ``poll`` list, the receiving
server should immediately send the sending server a presence update EDU of its
own, containing in a ``push`` list the current state of every user that was in
the original EDU's ``poll`` list.
Sending a presence invite::
.. TODO-doc
- Explain the timing-based round-trip reduction mechanism for presence
messages
- Explain the zero-byte presence inference logic
See also: docs/client-server/model/presence
EDU type: m.presence_invite
{{definition_ss_event_schemas_m_presence}}
Content keys:
observed_user: string giving the User ID of the user whose presence is
requested (i.e. the recipient of the invite)
observer_user: string giving the User ID of the user who is requesting to
observe the presence (i.e. the sender of the invite)
{{definition_ss_event_schemas_m_presence_invite}}
Accepting a presence invite::
{{definition_ss_event_schemas_m_presence_accept}}
EDU type: m.presence_accept
{{definition_ss_event_schemas_m_presence_deny}}
Content keys - as for m.presence_invite
Rejecting a presence invite::
Receipts
--------
EDU type: m.presence_deny
Receipts are EDUs used to communicate a marker for a given event. Currently the
only kind of receipt supported is a "read receipt", or where in the event graph
the user has read up to.
Content keys - as for m.presence_invite
Read receipts for events events that a user sent do not need to be sent. It is
implied that by sending the event the user has read up to the event.
.. TODO-doc
- Explain the timing-based round-trip reduction mechanism for presence
messages
- Explain the zero-byte presence inference logic
See also: docs/client-server/model/presence
{{definition_ss_event_schemas_m_receipt}}
Querying for information
------------------------
@ -888,6 +878,18 @@ that can be made.
{{query_ss_http_api}}
OpenID
------
Third party services can exchange an access token previously generated by the
`Client-Server API` for information about a user. This can help verify that a
user is who they say they are without granting full access to the user's account.
Access tokens generated by the OpenID API are only good for the OpenID API and
nothing else.
{{openid_ss_http_api}}
Send-to-device messaging
------------------------

@ -66,6 +66,7 @@ groups: # reusable blobs of files when prefixed with 'group:'
- modules/stickers.rst
- modules/report_content.rst
- modules/third_party_networks.rst
- modules/openid.rst
title_styles: ["=", "-", "~", "+", "^", "`", "@", ":"]

Loading…
Cancel
Save