Merge branch 'master' into mass_redactions

pull/2244/head
Tulir Asokan 5 years ago
commit b2ce6f87bc

@ -97,7 +97,7 @@ jobs:
command: DOCS_URL="${CIRCLE_BUILD_URL}/artifacts/${CIRCLE_NODE_INDEX}/${CIRCLE_WORKING_DIRECTORY/#\~/$HOME}/api/client-server/index.html"; echo $DOCS_URL
build-dev-scripts:
docker:
- image: golang:1.8
- image: golang:1.10
steps:
- checkout
- run:

@ -138,4 +138,4 @@ Issue tracking
Issues with the Matrix specification are tracked in `GitHub
<https://github.com/matrix-org/matrix-doc/issues>`_.
See `meta/labels.rst <meta/labels.rst>`_ for notes on what the labels mean.
See `meta/github-labels.rst <meta/github-labels.rst>`_ for notes on what the labels mean.

@ -30,6 +30,7 @@ paths:
description: |-
Determines if a given 3pid has been validated by a user.
operationId: getValidated3pid
deprecated: true
parameters:
- in: query
type: string
@ -104,6 +105,7 @@ paths:
``application/x-form-www-urlencoded`` data. However, this usage is
deprecated.
operationId: bind
deprecated: true
parameters:
- in: body
name: body
@ -221,6 +223,7 @@ paths:
through to the client requesting an unbind through a homeserver, if the
homeserver is acting on behalf of a client.
operationId: unbind
deprecated: true
parameters:
- in: body
name: body

@ -0,0 +1,18 @@
# Copyright 2019 The Matrix.org Foundation C.I.C.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
accessToken:
type: apiKey
description: The access_token returned by a call to ``/register``.
name: access_token
in: query

@ -46,6 +46,7 @@ paths:
``application/x-form-www-urlencoded`` data. However, this usage is
deprecated.
operationId: emailRequestToken
deprecated: true
parameters:
- in: body
name: body
@ -92,6 +93,7 @@ paths:
``application/x-form-www-urlencoded`` data. However, this usage is
deprecated.
operationId: emailSubmitTokenPost
deprecated: true
parameters:
- in: body
name: body
@ -142,6 +144,7 @@ paths:
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: emailSubmitTokenGet
deprecated: true
parameters:
- in: query
type: string

@ -33,6 +33,7 @@ paths:
The identity server will look up ``token`` which was stored in a call
to ``store-invite``, and fetch the sender of the invite.
operationId: blindlySignStuff
deprecated: true
parameters:
- in: body
name: body

@ -32,6 +32,7 @@ paths:
summary: Look up the Matrix user ID for a 3pid.
description: Look up the Matrix user ID for a 3pid.
operationId: lookupUser
deprecated: true
parameters:
- in: query
type: string
@ -101,6 +102,7 @@ paths:
summary: Lookup Matrix user IDs for a list of 3pids.
description: Lookup Matrix user IDs for a list of 3pids.
operationId: lookupUsers
deprecated: true
parameters:
- in: body
name: body

@ -46,6 +46,7 @@ paths:
``application/x-form-www-urlencoded`` data. However, this usage is
deprecated.
operationId: msisdnRequestToken
deprecated: true
parameters:
- in: body
name: body
@ -94,6 +95,7 @@ paths:
``application/x-form-www-urlencoded`` data. However, this usage is
deprecated.
operationId: msisdnSubmitTokenPost
deprecated: true
parameters:
- in: body
name: body
@ -144,6 +146,7 @@ paths:
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
deprecated: true
parameters:
- in: query
type: string

@ -36,6 +36,7 @@ paths:
This is primarly used for auto-discovery and health check purposes
by entities acting as a client for the identity server.
operationId: ping
deprecated: true
responses:
200:
description: An identity server is ready to serve requests.

@ -30,6 +30,7 @@ paths:
description: |-
Get the public key for the passed key ID.
operationId: getPubKey
deprecated: true
parameters:
- in: path
type: string
@ -72,6 +73,7 @@ paths:
Check whether a long-term public key is valid. The response should always
be the same, provided the key exists.
operationId: isPubKeyValid
deprecated: true
parameters:
- in: query
type: string
@ -101,6 +103,7 @@ paths:
description: |-
Check whether a short-term public key is valid.
operationId: isEphemeralPubKeyValid
deprecated: true
parameters:
- in: query
type: string

@ -55,6 +55,7 @@ paths:
server's ability. Identity servers may use these variables when notifying
the ``address`` of the pending invite for display purposes.
operationId: storeInvite
deprecated: true
parameters:
- in: body
name: body

@ -0,0 +1,308 @@
# Copyright 2018 New Vector Ltd
# Copyright 2019 The Matrix.org Foundation C.I.C.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
swagger: '2.0'
info:
title: "Matrix Identity Service Establishing Associations API"
version: "2.0.0"
host: localhost:8090
schemes:
- https
basePath: /_matrix/identity/v2
consumes:
- application/json
produces:
- application/json
securityDefinitions:
$ref: definitions/security.yaml
paths:
"/3pid/getValidated3pid":
get:
summary: Check whether ownership of a 3pid was validated.
description: |-
Determines if a given 3pid has been validated by a user.
operationId: getValidated3pidV2
security:
- accessToken: []
parameters:
- in: query
type: string
name: sid
description: The Session ID generated by the ``requestToken`` call.
required: true
x-example: 1234
- in: query
type: string
name: client_secret
description: The client secret passed to the ``requestToken`` call.
required: true
x-example: monkeys_are_GREAT
responses:
200:
description: Validation information for the session.
examples:
application/json: {
"medium": "email",
"validated_at": 1457622739026,
"address": "louise@bobs.burgers"
}
schema:
type: object
properties:
medium:
type: string
description: The medium type of the 3pid.
address:
type: string
description: The address of the 3pid being looked up.
validated_at:
type: integer
description: |-
Timestamp, in milliseconds, indicating the time that the 3pid
was validated.
required: ['medium', 'address', 'validated_at']
400:
description: |-
The session has not been validated.
If the session has not been validated, then ``errcode`` will be
``M_SESSION_NOT_VALIDATED``. If the session has timed out, then
``errcode`` will be ``M_SESSION_EXPIRED``.
examples:
application/json: {
"errcode": "M_SESSION_NOT_VALIDATED",
"error": "This validation session has not yet been completed"
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
404:
description: The Session ID or client secret were not found.
examples:
application/json: {
"errcode": "M_NO_VALID_SESSION",
"error": "No valid session was found matching that sid and client secret"
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
"/3pid/bind":
post:
summary: Publish an association between a session and a Matrix user ID.
description: |-
Publish an association between a session and a Matrix user ID.
Future calls to ``/lookup`` for any of the session\'s 3pids will return
this association.
Note: for backwards compatibility with previous drafts of this
specification, the parameters may also be specified as
``application/x-form-www-urlencoded`` data. However, this usage is
deprecated.
operationId: bindV2
security:
- accessToken: []
parameters:
- in: body
name: body
schema:
type: object
example: {
"sid": "1234",
"client_secret": "monkeys_are_GREAT",
"mxid": "@ears:matrix.org"
}
properties:
sid:
type: string
description: The Session ID generated by the ``requestToken`` call.
client_secret:
type: string
description: The client secret passed to the ``requestToken`` call.
mxid:
type: string
description: The Matrix user ID to associate with the 3pids.
required: ["sid", "client_secret", "mxid"]
responses:
200:
description: The association was published.
examples:
application/json: {
"address": "louise@bobs.burgers",
"medium": "email",
"mxid": "@ears:matrix.org",
"not_before": 1428825849161,
"not_after": 4582425849161,
"ts": 1428825849161,
"signatures": {
"matrix.org": {
"ed25519:0": "ENiU2YORYUJgE6WBMitU0mppbQjidDLanAusj8XS2nVRHPu+0t42OKA/r6zV6i2MzUbNQ3c3MiLScJuSsOiVDQ"
}
}
}
schema:
type: object
properties:
address:
type: string
description: The 3pid address of the user being looked up.
medium:
type: string
description: The medium type of the 3pid.
mxid:
type: string
description: The Matrix user ID associated with the 3pid.
not_before:
type: integer
description: A unix timestamp before which the association is not known to be valid.
not_after:
type: integer
description: A unix timestamp after which the association is not known to be valid.
ts:
type: integer
description: The unix timestamp at which the association was verified.
signatures:
type: object
description: |-
The signatures of the verifying identity servers which show that the
association should be trusted, if you trust the verifying identity
services.
$ref: "../../schemas/server-signatures.yaml"
required:
- address
- medium
- mxid
- not_before
- not_after
- ts
- signatures
400:
description: |-
The association was not published.
If the session has not been validated, then ``errcode`` will be
``M_SESSION_NOT_VALIDATED``. If the session has timed out, then
``errcode`` will be ``M_SESSION_EXPIRED``.
examples:
application/json: {
"errcode": "M_SESSION_NOT_VALIDATED",
"error": "This validation session has not yet been completed"
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
404:
description: The Session ID or client secret were not found
examples:
application/json: {
"errcode": "M_NO_VALID_SESSION",
"error": "No valid session was found matching that sid and client secret"
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
"/3pid/unbind":
post:
summary: Remove an association between a session and a Matrix user ID.
description: |-
Remove an association between a session and a Matrix user ID.
Future calls to ``/lookup`` for any of the session's 3pids will not
return the removed association.
The identity server should authenticate the request in one of two
ways:
1. The request is signed by the homeserver which controls the ``user_id``.
2. The request includes the ``sid`` and ``client_secret`` parameters,
as per ``/3pid/bind``, which proves ownership of the 3PID.
If this endpoint returns a JSON Matrix error, that error should be passed
through to the client requesting an unbind through a homeserver, if the
homeserver is acting on behalf of a client.
operationId: unbindV2
security:
- accessToken: []
parameters:
- in: body
name: body
schema:
type: object
example: {
"sid": "1234",
"client_secret": "monkeys_are_GREAT",
"mxid": "@ears:example.org",
"threepid": {
"medium": "email",
"address": "monkeys_have_ears@example.org"
}
}
properties:
sid:
type: string
description: The Session ID generated by the ``requestToken`` call.
client_secret:
type: string
description: The client secret passed to the ``requestToken`` call.
mxid:
type: string
description: The Matrix user ID to remove from the 3pids.
threepid:
type: object
title: 3PID
description: |-
The 3PID to remove. Must match the 3PID used to generate the session
if using ``sid`` and ``client_secret`` to authenticate this request.
properties:
medium:
type: string
description: |-
A medium from the `3PID Types`_ Appendix, matching the medium
of the identifier to unbind.
address:
type: string
description: The 3PID address to remove.
required: ['medium', 'address']
required: ["threepid", "mxid"]
responses:
200:
description: The association was successfully removed.
examples:
application/json: {}
schema:
type: object
400:
description: |-
If the response body is not a JSON Matrix error, the identity server
does not support unbinds. If a JSON Matrix error is in the response
body, the requesting party should respect the error.
404:
description: |-
If the response body is not a JSON Matrix error, the identity server
does not support unbinds. If a JSON Matrix error is in the response
body, the requesting party should respect the error.
403:
description: |-
The credentials supplied to authenticate the request were invalid.
This may also be returned if the identity server does not support
the chosen authentication method (such as blocking homeservers from
unbinding identifiers).
examples:
application/json: {
"errcode": "M_FORBIDDEN",
"error": "Invalid homeserver signature"
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
501:
description: |-
If the response body is not a JSON Matrix error, the identity server
does not support unbinds. If a JSON Matrix error is in the response
body, the requesting party should respect the error.

@ -0,0 +1,183 @@
# Copyright 2018 New Vector Ltd
# Copyright 2019 The Matrix.org Foundation C.I.C.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
swagger: '2.0'
info:
title: "Matrix Identity Service Email Associations API"
version: "2.0.0"
host: localhost:8090
schemes:
- https
basePath: /_matrix/identity/v2
consumes:
- application/json
produces:
- application/json
securityDefinitions:
$ref: definitions/security.yaml
paths:
"/validate/email/requestToken":
post:
summary: Request a token for validating an email address.
description: |-
Create a session for validating an email address.
The identity server will send an email containing a token. If that
token is presented to the identity server in the future, it indicates
that that user was able to read the email for that email address, and
so we validate ownership of the email address.
Note that homeservers offer APIs that proxy this API, adding
additional behaviour on top, for example,
``/register/email/requestToken`` is designed specifically for use when
registering an account and therefore will inform the user if the email
address given is already registered on the server.
Note: for backwards compatibility with previous drafts of this
specification, the parameters may also be specified as
``application/x-form-www-urlencoded`` data. However, this usage is
deprecated.
operationId: emailRequestTokenV2
security:
- accessToken: []
parameters:
- in: body
name: body
schema:
$ref: "definitions/request_email_validation.yaml"
responses:
200:
description: Session created.
schema:
$ref: "definitions/sid.yaml"
400:
description: |
An error ocurred. Some possible errors are:
- ``M_INVALID_EMAIL``: The email address provided was invalid.
- ``M_EMAIL_SEND_ERROR``: The validation email could not be sent.
examples:
application/json: {
"errcode": "M_INVALID_EMAIL",
"error": "The email address is not valid"
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
"/validate/email/submitToken":
post:
summary: Validate ownership of an email address.
description: |-
Validate ownership of an email address.
If the three parameters are consistent with a set generated by a
``requestToken`` call, ownership of the email address is considered to
have been validated. This does not publish any information publicly, or
associate the email address with any Matrix user ID. Specifically,
calls to ``/lookup`` will not show a binding.
The identity server is free to match the token case-insensitively, or
carry out other mapping operations such as unicode
normalisation. Whether to do so is an implementation detail for the
identity server. Clients must always pass on the token without
modification.
Note: for backwards compatibility with previous drafts of this
specification, the parameters may also be specified as
``application/x-form-www-urlencoded`` data. However, this usage is
deprecated.
operationId: emailSubmitTokenPostV2
security:
- accessToken: []
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 emailed 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.
required: ['success']
get:
summary: Validate ownership of an email address.
description: |-
Validate ownership of an email address.
If the three parameters are consistent with a set generated by a
``requestToken`` call, ownership of the email address is considered to
have been validated. This does not publish any information publicly, or
associate the email address 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: emailSubmitTokenGetV2
security:
- accessToken: []
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 emailed to the user.
x-example: atoken
responses:
"200":
description: Email address is validated.
"3xx":
description: |-
Email 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.

@ -0,0 +1,101 @@
# Copyright 2018 New Vector Ltd
# Copyright 2019 The Matrix.org Foundation C.I.C.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
swagger: '2.0'
info:
title: "Matrix Identity Service Ephemeral Invitation Signing API"
version: "2.0.0"
host: localhost:8090
schemes:
- https
basePath: /_matrix/identity/v2
consumes:
- application/json
produces:
- application/json
securityDefinitions:
$ref: definitions/security.yaml
paths:
"/sign-ed25519":
post:
summary: Sign invitation details
description: |-
Sign invitation details.
The identity server will look up ``token`` which was stored in a call
to ``store-invite``, and fetch the sender of the invite.
operationId: blindlySignStuffV2
security:
- accessToken: []
parameters:
- in: body
name: body
schema:
type: object
example: {
"mxid": "@foo:bar.com",
"token": "sometoken",
"private_key": "base64encodedkey"
}
properties:
mxid:
type: string
description: The Matrix user ID of the user accepting the invitation.
token:
type: string
description: The token from the call to ``store-invite``.
private_key:
type: string
description: The private key, encoded as `Unpadded base64`_.
required: ["mxid", "token", "private_key"]
responses:
200:
description: The signed JSON of the mxid, sender, and token.
schema:
type: object
properties:
mxid:
type: string
description: The Matrix user ID of the user accepting the invitation.
sender:
type: string
description: The Matrix user ID of the user who sent the invitation.
signatures:
type: object
description: The signature of the mxid, sender, and token.
$ref: "../../schemas/server-signatures.yaml"
token:
type: string
description: The token for the invitation.
required: ['mxid', 'sender', 'signatures', 'token']
examples:
application/json: {
"mxid": "@foo:bar.com",
"sender": "@baz:bar.com",
"signatures": {
"my.id.server": {
"ed25519:0": "def987"
}
},
"token": "abc123"
}
404:
description: The token was not found.
examples:
application/json: {
"errcode": "M_UNRECOGNIZED",
"error": "Didn't recognize token"
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"

@ -0,0 +1,185 @@
# Copyright 2018 New Vector Ltd
# Copyright 2019 The Matrix.org Foundation C.I.C.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
swagger: '2.0'
info:
title: "Matrix Identity Service Phone Number Associations API"
version: "2.0.0"
host: localhost:8090
schemes:
- https
basePath: /_matrix/identity/v2
consumes:
- application/json
produces:
- application/json
securityDefinitions:
$ref: definitions/security.yaml
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 server will send an SMS message containing a token. If
that token is presented to the identity server 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 homeservers 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 previous drafts of this
specification, the parameters may also be specified as
``application/x-form-www-urlencoded`` data. However, this usage is
deprecated.
operationId: msisdnRequestTokenV2
security:
- accessToken: []
parameters:
- in: body
name: body
schema:
$ref: "definitions/request_msisdn_validation.yaml"
responses:
200:
description: Session created.
schema:
$ref: "definitions/sid.yaml"
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.
- ``M_DESTINATION_REJECTED``: The identity server cannot deliver an
SMS to the provided country or region.
examples:
application/json: {
"errcode": "M_INVALID_ADDRESS",
"error": "The phone number is not valid"
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
"/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.
The identity server is free to match the token case-insensitively, or
carry out other mapping operations such as unicode
normalisation. Whether to do so is an implementation detail for the
identity server. Clients must always pass on the token without
modification.
Note: for backwards compatibility with previous drafts of this
specification, the parameters may also be specified as
``application/x-form-www-urlencoded`` data. However, this usage is
deprecated.
operationId: msisdnSubmitTokenPostV2
security:
- accessToken: []
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.
required: ['success']
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: msisdnSubmitTokenGetV2
security:
- accessToken: []
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.

@ -0,0 +1,46 @@
# Copyright 2018 Kamax Sàrl
# Copyright 2018 New Vector Ltd
# Copyright 2019 The Matrix.org Foundation C.I.C.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
swagger: "2.0"
info:
title: "Matrix Identity Service Ping API"
version: "2.0.0"
host: localhost:8090
schemes:
- https
basePath: /_matrix/identity
produces:
- application/json
paths:
"/v2":
get:
summary: Checks that an identity server is available at this API endpoint.
description: |-
Checks that an identity server is available at this API endpoint.
To discover that an identity server is available at a specific URL,
this endpoint can be queried and will return an empty object.
This is primarly used for auto-discovery and health check purposes
by entities acting as a client for the identity server.
operationId: pingV2
responses:
200:
description: An identity server is ready to serve requests.
examples:
application/json: {}
schema:
type: object

@ -0,0 +1,127 @@
# Copyright 2016 OpenMarket Ltd
# Copyright 2019 The Matrix.org Foundation C.I.C.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
swagger: '2.0'
info:
title: "Matrix Identity Service Public Key API"
version: "2.0.0"
host: localhost:8090
schemes:
- https
basePath: /_matrix/identity/v2
consumes:
- application/json
produces:
- application/json
paths:
"/pubkey/{keyId}":
get:
summary: Get a public key.
description: |-
Get the public key for the passed key ID.
operationId: getPubKeyV2
parameters:
- in: path
type: string
name: keyId
required: true
description: |-
The ID of the key. This should take the form algorithm:identifier
where algorithm identifies the signing algorithm, and the identifier
is an opaque string.
x-example: "ed25519:0"
responses:
200:
description:
The public key exists.
examples:
application/json: {
"public_key": "VXuGitF39UH5iRfvbIknlvlAVKgD1BsLDMvBf0pmp7c"
}
schema:
type: object
properties:
public_key:
type: string
description: Unpadded Base64 encoded public key.
required: ['public_key']
404:
description:
The public key was not found.
examples:
application/json: {
"errcode": "M_NOT_FOUND",
"error": "The public key was not found"
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
"/pubkey/isvalid":
get:
summary: Check whether a long-term public key is valid.
description: |-
Check whether a long-term public key is valid. The response should always
be the same, provided the key exists.
operationId: isPubKeyValidV2
parameters:
- in: query
type: string
name: public_key
required: true
description: |-
The unpadded base64-encoded public key to check.
x-example: "VXuGitF39UH5iRfvbIknlvlAVKgD1BsLDMvBf0pmp7c"
responses:
200:
description:
The validity of the public key.
examples:
application/json: {
"valid": true
}
schema:
type: object
properties:
valid:
type: boolean
description: Whether the public key is recognised and is currently valid.
required: ['valid']
"/pubkey/ephemeral/isvalid":
get:
summary: Check whether a short-term public key is valid.
description: |-
Check whether a short-term public key is valid.
operationId: isEphemeralPubKeyValidV2
parameters:
- in: query
type: string
name: public_key
required: true
description: |-
The unpadded base64-encoded public key to check.
x-example: "VXuGitF39UH5iRfvbIknlvlAVKgD1BsLDMvBf0pmp7c"
responses:
200:
description:
The validity of the public key.
examples:
application/json: {
"valid": true
}
schema:
type: object
properties:
valid:
type: boolean
description: Whether the public key is recognised and is currently valid.
required: ['valid']

@ -0,0 +1,165 @@
# Copyright 2018 New Vector Ltd
# Copyright 2019 The Matrix.org Foundation C.I.C.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
swagger: '2.0'
info:
title: "Matrix Identity Service Store Invitations API"
version: "2.0.0"
host: localhost:8090
schemes:
- https
basePath: /_matrix/identity/v2
consumes:
- application/json
produces:
- application/json
securityDefinitions:
$ref: definitions/security.yaml
paths:
"/store-invite":
post:
summary: Store pending invitations to a user's 3pid.
description: |-
Store pending invitations to a user's 3pid.
In addition to the request parameters specified below, an arbitrary
number of other parameters may also be specified. These may be used in
the invite message generation described below.
The service will generate a random token and an ephemeral key used for
accepting the invite.
The service also generates a ``display_name`` for the inviter, which is
a redacted version of ``address`` which does not leak the full contents
of the ``address``.
The service records persistently all of the above information.
It also generates an email containing all of this data, sent to the
``address`` parameter, notifying them of the invitation.
Also, the generated ephemeral public key will be listed as valid on
requests to ``/_matrix/identity/v2/pubkey/ephemeral/isvalid``.
Currently, invites may only be issued for 3pids of the ``email`` medium.
Optional fields in the request should be populated to the best of the
server's ability. Identity servers may use these variables when notifying
the ``address`` of the pending invite for display purposes.
operationId: storeInviteV2
security:
- accessToken: []
parameters:
- in: body
name: body
schema:
type: object
properties:
medium:
type: string
description: The literal string ``email``.
example: "email"
address:
type: string
description: The email address of the invited user.
example: "foo@example.com"
room_id:
type: string
description: The Matrix room ID to which the user is invited
example: "!something:example.org"
sender:
type: string
description: The Matrix user ID of the inviting user
example: "@bob:example.com"
room_alias:
type: string
description: |-
The Matrix room alias for the room to which the user is
invited. This should be retrieved from the ``m.room.canonical_alias``
state event.
example: "#somewhere:exmaple.org"
room_avatar_url:
type: string
description: |-
The Content URI for the room to which the user is invited. This should
be retrieved from the ``m.room.avatar`` state event.
example: "mxc://example.org/s0meM3dia"
room_join_rules:
type: string
description: |-
The ``join_rule`` for the room to which the user is invited. This should
be retrieved from the ``m.room.join_rules`` state event.
example: "public"
room_name:
type: string
description: |-
The name of the room to which the user is invited. This should be retrieved
from the ``m.room.name`` state event.
example: "Bob's Emporium of Messages"
sender_display_name:
type: string
description: The display name of the user ID initiating the invite.
example: "Bob Smith"
sender_avatar_url:
type: string
description: The Content URI for the avatar of the user ID initiating the invite.
example: "mxc://example.org/an0th3rM3dia"
required: ["medium", "address", "room_id", "sender"]
responses:
200:
description: The invitation was stored.
schema:
type: object
properties:
token:
type: string
description: |
The generated token. Must be a string consisting of the
characters ``[0-9a-zA-Z.=_-]``. Its length must not exceed
255 characters and it must not be empty.
public_keys:
type: array
description: |
A list of [server's long-term public key, generated ephemeral
public key].
items:
type: string
display_name:
type: string
description: The generated (redacted) display_name.
required: ['token', 'public_keys', 'display_name']
example:
application/json: {
"token": "sometoken",
"public_keys": [
"serverpublickey",
"ephemeralpublickey"
],
"display_name": "f...@b..."
}
400:
description: |
An error has occured.
If the 3pid is already bound to a Matrix user ID, the error code
will be ``M_THREEPID_IN_USE``. If the medium is unsupported, the
error code will be ``M_UNRECOGNIZED``.
examples:
application/json: {
"errcode": "M_THREEPID_IN_USE",
"error": "Binding already known",
"mxid": "@alice:example.com"
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"

@ -0,0 +1 @@
Fix the ``m.room_key_request`` ``action`` value, setting it from ``cancel_request`` to ``request_cancellation``.

@ -1,6 +1,6 @@
{
"content": {
"action": "cancel_request",
"action": "request_cancellation",
"requesting_device_id": "RJYKSTBOIE",
"request_id": "1495474790150.19"
},

@ -38,7 +38,7 @@ properties:
action:
enum:
- request
- cancel_request
- request_cancellation
type: string
requesting_device_id:
description: ID of the device requesting the key.

@ -0,0 +1,91 @@
The following labels are used to help categorize issues:
`spec-omission <https://github.com/matrix-org/matrix-doc/labels/spec-omission>`_
--------------------------------------------------------------------------------
Things which have been implemented but not currently specified. These may range
from entire API endpoints, to particular options or return parameters.
Issues with this label will have been implemented in `Synapse
<https://github.com/matrix-org/synapse>`_. Normally there will be a design
document in Google Docs or similar which describes the feature.
Examples:
* `Spec PUT /directory/list <https://github.com/matrix-org/matrix-doc/issues/417>`_
* `Unspec'd server_name request param for /join/{roomIdOrAlias}
<https://github.com/matrix-org/matrix-doc/issues/904>`_
`clarification <https://github.com/matrix-org/matrix-doc/labels/clarification>`_
--------------------------------------------------------------------------------
An area where the spec could do with being more explicit.
Examples:
* `Spec the implicit limit on /syncs
<https://github.com/matrix-org/matrix-doc/issues/708>`_
* `Clarify the meaning of the currently_active flags in presence events
<https://github.com/matrix-org/matrix-doc/issues/686>`_
`spec-bug <https://github.com/matrix-org/matrix-doc/labels/spec-bug>`_
----------------------------------------------------------------------
Something which is in the spec, but is wrong.
Note: this is *not* for things that are badly designed or don't work well
(for which see 'improvement' or 'feature') - it is for places where the
spec doesn't match reality.
Examples:
* `swagger is wrong for directory PUT
<https://github.com/matrix-org/matrix-doc/issues/933>`_
* `receipts section still refers to initialSync
<https://github.com/matrix-org/matrix-doc/issues/695>`_
`improvement <https://github.com/matrix-org/matrix-doc/labels/improvement>`_
----------------------------------------------------------------------------
A suggestion for a relatively simple improvement to the protocol.
Examples:
* `We need a 'remove 3PID' API so that users can remove mappings
<https://github.com/matrix-org/matrix-doc/issues/620>`_
* `We should mandate that /publicRooms requires an access_token
<https://github.com/matrix-org/matrix-doc/issues/612>`_
`feature <https://github.com/matrix-org/matrix-doc/labels/feature>`_
--------------------------------------------------------------------
A suggestion for a significant extension to the matrix protocol which
needs considerable consideration before implementation.
Examples:
* `Peer-to-peer Matrix <https://github.com/matrix-org/matrix-doc/issues/710>`_
* `Specify a means for clients to "edit" previous messages
<https://github.com/matrix-org/matrix-doc/issues/682>`_
`wart <https://github.com/matrix-org/matrix-doc/labels/wart>`_
--------------------------------------------------------------
A point where the protocol is inconsistent or inelegant, but which isn't really
causing anybody any problems right now. Might be nice to consider fixing one
day.
`question <https://github.com/matrix-org/matrix-doc/labels/question>`_
----------------------------------------------------------------------
A thought or idea about the protocol which we aren't really sure whether to
pursue or not.
Examples:
* `Should we prepend anti-eval code to our json responses?
<https://github.com/matrix-org/matrix-doc/issues/908>`_

@ -0,0 +1,189 @@
# MSC1957: Integration manager discovery
**Note**: this proposal is part of a larger "Integrations API" which has not yet been defined.
See [MSC1956](https://github.com/matrix-org/matrix-doc/pull/1956) for details.
**Note**: this proposal makes use of the existing Widget API proposed by
[MSC1236](https://github.com/matrix-org/matrix-doc/issues/1236).
Users should have the freedom to choose which integration manager they want to use in their client, while
also accepting suggestions from their homeserver and client. Clients need to know where to find the different
integration managers and how to contact them.
## Proposal
A single logged in user may be influenced by zero or more integration managers at any given time. Managers
are sourced from the client's own configuration, homeserver discovery information, and the user's personal
account data in the form of widgets. Clients should support users using more than one integration manager
at a given time, although the rules for how this can be handled are defined later in this proposal.
#### Client-configured integration managers
This is left as an implementation detail. In the case of Riot, this is likely to be part of the existing
`config.json` options, although likely modified to support multiple managers instead of one.
#### Homeserver-configured integration managers
The integration managers suggested by a homeserver are done through the existing
[.well-known](https://matrix.org/docs/spec/client_server/r0.4.0.html#get-well-known-matrix-client) discovery
mechanism. The added optional fields, which should not affect a client's ability to log a user in, are:
```json
{
"m.integrations": {
"managers": [
{
"api_url": "https://integrations.example.org",
"ui_url": "https://integrations.example.org/ui"
},
{
"api_url": "https://bots.example.org"
}
]
}
}
```
As shown, the homeserver is able to suggest multiple integration managers through this method. Each manager
must have an `api_url` which must be an `http` or `https` URL. The `ui_url` is optional and if not provided
is the same as the `api_url`. Like the `api_url`, the `ui_url` must be `http` or `https` if supplied.
The `ui_url` is ultimately treated the same as a widget, except that the `data` object from the widget is not
present and must not be templated here. Variables like `$matrix_display_name` are able to function, however.
Integration managers should never use the `$matrix_user_id` as authoritative and instead seek other ways to
determine the user ID. This is covered by other proposals.
The `api_url` is the URL clients will use when *not* embedding the integration manager, and instead showing
its own purpose-built interface.
Clients should query the `.well-known` information for the homeserver periodically to update the integration
manager settings for that homeserver. The client is not expected to validate or use any other information
contained in the response. Current recommendations are to query the configuration when the client starts up
and every 8 hours after that. Clients can additionally refresh the configuration whenever they feel is
necessary (such as every time the user opens the integration manager).
#### User-configured integration managers
Users can specify integration managers in the form of account widgets. The `type` is to be `m.integration_manager`
and the content would look something similar to:
```json
{
"url": "https://integrations.example.org/ui?displayName=$matrix_display_name",
"data": {
"api_url": "https://integrations.example.org"
}
}
```
The `api_url` in the `data` object is required and has the same meaning as the homeserver-defined `api_url`.
The `url` of the widget is analogous to the `ui_url` from the homeserver configuration above, however normal
widget rules apply here.
The user is able to have multiple integration managers through use of multiple widgets.
The query string shown in the example is to demonstrate that integration managers are widgets and can
make use of the template options provided to widgets.
#### Display order of integration managers
Clients which have support for integration managers should display at least 1 manager, but should
display multiple via something like tabs. Clients must prefer to display the user's configured
integration managers over any defaults, and if only displaying one manager must pick the first
manager after sorting the `state_key`s of the applicable widgets in lexicographical order. Clients
can additionally display default managers if they so wish, and should preserve the order defined in
the various defaults. If the user has no configured integration managers, the client must prefer
to display one or more of the managers suggested by the homeserver over the managers recommended
by the client.
The client can optionally support a way to entirely disable integration manager support, even if the
user and homeserver have managers defined.
The rationale for having the client prefer to use the user's integration managers first is so that
the user can tailor their experience within Matrix if desired. Similarly, a homeserver may wish to
subject all of their users to the same common integration manager as would be common in some organizations.
The client's own preference is a last ditch effort to have an integration manager available to the
user so they don't get left out.
#### Displaying integration managers
Clients simply open the `ui_url` (or equivalent) in an `iframe` or similar. In the current ecosystem,
integration managers would receive a `scalar_token` to identify the user - this is no longer the case
and instead integration managers must seek other avenues for determining the user ID. Other proposals
cover how to do this in the context of the integrations API.
Integration managers shown in this way must be treated like widgets, regardless of source. In practice
this means exposing the Widget API to the manager and applying necessary scoping to keep the manager
as an account widget rather than a room widget.
#### Discovering a manager by only the domain name
Clients may wish to ask users for a single canonical domain name so they can find the manager to add
to the user's account transparently. This differs from the .well-known discovery which allows homeservers
to recommend their own integration manager: the homeserver is not recommending a default here. The
user has instead opted to pick an integration manager (identified only by domain name) and the client
is expected to resolve that to a set of URLs it can use for the manager.
Similar to the .well-known discovery done by servers (and clients during login), clients which have an
integrations domain (eg: "example.org") make a regular HTTPS request to
`https://example.org/.well-known/matrix/integrations` which returns an object which looks like the
following:
```json
{
"m.integrations_widget": {
"url": "https://integrations.example.org/ui?displayName=$matrix_display_name",
"data": {
"api_url": "https://integrations.example.org"
}
}
}
```
The response should be parsed as JSON. If the endpoint returns an error or is missing the `m.integrations_widget`
property, the client should assume there is no integrations manager running on that domain. The
`m.integrations_widget` is an object which has the exact same format as the account widget for
an integration manager, described above. The client should wrap the object verbatim into the appropriate
account data location.
Because the .well-known file would be accessed by web browsers, among other platforms, the server
should be using appropriate CORS headers for the request. The recommended headers are the same as those
which are already recommended for homeserver discovery in the Client-Server API.
*Note*: this could reuse the client-server mechanic for discovery and just omit the homeserver information
however that conflates many concerns together on the one endpoint. A new endpoint is instead proposed
to keep the concerns isolated.
The query string shown in the example is to demonstrate that integration managers are widgets and can
make use of the template options provided to widgets.
## Tradeoffs
We could limit the user (and by extension, the homeserver and client) to exactly 1 integration manager
and not worry about tabs or other concepts, however this restricts a user's access to integrations.
In a scenario where the user wants to use widgets from Service A and bots from Service B, they'd
end up switching accounts or clients to gain access to either service, or potentially just give up
and walk away from the problem. Instead of having the user switch between clients, we might as well
support this use case, even if it is moderately rare.
We could also define the integration managers in a custom account data event rather than defining them
as a widget. Doing so just adds clutter to the account data and risks duplicating code in clients as
using widgets gets us URL templating for free (see the section earlier on in this proposal about account
widgets for more information: "User-configured integration managers").
## Future extensions
Some things which may be desirable in the future are:
* Avatars for the different managers
* Human-readable names for the different managers
* Supporting `ui_url`s targeting specific clients for a more consistent design
## Security considerations
When displaying integration managers, clients should not trust that the input is sanitary. Per the
proposal above, an integration manager is only permitted to be served from HTTP(S) URIs. A given
integration manager can still have malicious intent however, and clients should ensure any sandboxing
on the manager is appropriate such that it can communicate with the client, but cannot perform
unauthorized actions. Other URI schemes are just as dangerous and could potentially be allowed by
this proposal - use cases are less defined and desirable for schemes like `file://` and are excluded
by this proposal. They can be added in a future proposal if a use case arises.

@ -0,0 +1,73 @@
# MSC1961: Integration manager authentication
A set of common APIs needs to be defined for clients to be able to interact with an integration
manager. This proposal covers the authentication portion of that API.
**Note**: this proposal is part of a larger "Integrations API" which has not yet been defined.
See [MSC1956](https://github.com/matrix-org/matrix-doc/pull/1956) for details.
## Proposal
All specified APIs (except `/register`) will take an `Authorization` header with a `Bearer` token returned
from a call to `/register`. This token is used to authorize the request and to identify who is making the
request. The token may also be specified as the `access_token` query string parameter, similar to the
Client-Server API.
#### POST `/_matrix/integrations/v1/account/register`
Exchanges an OpenID object for a token which can be used to authorize future requests to the manager.
Request body is an OpenID object as returned by `/_matrix/client/r0/user/:userId/openid/request_token`.
Response is:
```json
{
"token": "OpaqueString"
}
```
The token should consist of URL-safe base64 characters. Integration managers should be careful to validate
the OpenID object by ensuring the `/_matrix/federation/v1/openid/userinfo` response has a `sub` which belongs
to the `matrix_server_name` provided in the original OpenID object.
Applications which register for a token are responsible for tracking which integration manager they are for.
This can usually be done by tracking the hostname of the integration manager and matching a token with it.
#### GET `/_matrix/integrations/v1/account`
Gets information about the token's owner, such as the user ID for which it belongs.
Besides a token, no other information is required for the request.
Response is:
```json
{
"user_id": "@alice:example.org"
}
```
The `user_id` is the user ID which was represented in the OpenID object provided to `/register`. Integration
managers may be interested in also supplying information about the user's credit balance for paid integrations
here. Preferably, custom information is stored under a namespaced key like so:
```json
{
"user_id": "@alice:example.org",
"org.example.paid.integrations": {
"credit": 20000
}
}
```
#### POST `/_matrix/integrations/v1/account/logout`
Logs the token out, rendering it useless for future requests.
Request body is an empty object. Response body is also an empty object if successful.
## Security considerations
Clients should be sure to call `/logout` where possible when the user is logging out or no longer needs access
to a given manager. Clients should additionally be cautious about which managers they register for tokens with,
as some integration managers may be untrusted.

@ -0,0 +1,335 @@
# MSC2140: Terms of Service API for Identity Servers and Integration Managers
[MSC1692](https://github.com/matrix-org/matrix-doc/issues/1692) introduces a
method for homeservers to require that users read and agree to certain
documents before being permitted to use the service. This proposal introduces a
corresponding method that can be used with Identity Servers and Integration
Managers.
Requirements for this proposal are:
* ISes and IMs should be able to give multiple documents a user must agree to
abide by
* Each document shoud be versioned
* ISes and IMs must, for each request that they handle, know that the user
making the request has agreed to their data being used. This need not be
absolute proof (we will always have to trust that the client actually
showed the document to the user) but it must be reasonably demonstrable that
the user has given informed consent for the client to use that service.
* ISes and IMs must be able to prevent users from using the service if they
have not provided agreement.
* A user should only have to agree to each version of each document once for
their Matrix ID, ie. having agreed to a set of terms in one client, they
should not have to agree to them again when using a different client.
* Documents should be de-duplicated between services. If two or more services
are hosted by the same organisation, the organisation should have the
option to give their users a single document that encompasses both services
(bearing in mind that the user must be able to opt-out of components of a
service whilst still being able to use the service without that component).
Identity Servers do not currently require any kind of user login to access the
service and so are unable to track what users have agreed to what terms in the
way that Homeservers do.
## Proposal
Throuhgout this proposal, $prefix will be used to refer to the prefix of the
API in question, ie. `/_matrix/identity/v2` for the IS API and
`/_matrix/integrations/v1` for the IM API.
Note the removal of the `/api` prefix and migration to v2 in the IS API
following convention from
[MSC2134](https://github.com/matrix-org/matrix-doc/issues/2134).
This proposal introduces:
* A v2 API prefix, with authentication, for the Identity Service
* The `$prefix/terms` endpoint
* The `m.accepted_terms` section in account data
* `POST /_matrix/client/r0/account/3pid/unbind` endpoints on the client/server
API
This proposal removes:
* The `bind_email` and `bind_msisdn` on the Homeserver `/register` endpoint
This proposal relies on both Integration Managers and Identity Servers being
able to identify users by their MXID and store the fact that a given MXID has
indicated that they accept the terms given. Integration Managers already
identify users in this way by authenticating them using the OpenID endpoint on
the Homeserver. This proposal introduces the same mechanism to Identity Servers
and adds authentication across the Identity Service API.
### IS API Authentication
All current endpoints within `/_matrix/identity/api/v1/` will be duplicated
into `/_matrix/identity/v2`, noting that MSC2134 changes the behaviour of
lookups. Authentication is still expected on MSC2134's proposed endpoints.
Support for `application/x-form-www-urlencoded` parameters in requests will
be dropped from all endpoints.
Any request to any endpoint within `/_matrix/identity/v2`, with the exception
of:
* `/_matrix/identity/v2`
* `/_matrix/identity/v2/pubkey/*`
* The new `$prefix/account/register` endpoint
* The new `GET /_matrix/identity/v2/terms`
* `$prefix/account/logout`
...may return an error with `M_UNAUTHORIZED` errcode with HTTP status code 401.
This indicates that the user must authenticate with OpenID and supply a valid
`access_token`.
Clients authenticate either via an `Authorization` header with a `Bearer` token
or an `access_token` query parameter.
The existing endpoints under `/_matrix/identity/api/v1/` continue to be
unauthenticated but will be deprecated. ISes may support the old v1 API for as
long as they wish. Once ISes remove support for the old APIs, those endpoints
must return HTTP Status 404. Clients must update to use the v2 API as soon as
possible.
OpenID authentication in the IS API will work the same as in the Integration Manager
API, as specified in [MSC1961](https://github.com/matrix-org/matrix-doc/issues/1961).
When clients supply an identity server to the Homeserver in order for the
Homeserver to make calls to the IS on its behalf, it must also supply its
access token for the Identity Server alongside in the `id_access_token` key of
the same JSON object. That is, in the main request object for `requestToken`
and `/_matrix/client/r0/rooms/{roomId}/invite` requests and in the
`threepidCreds` object when supplying 3PID credentials (eg. in the
`m.email.identity` UI auth stage). The server must also relay
`M_TERMS_NOT_SIGNED` errors back to the client. Exceptions to this are any
requests where the only IS operation the Homeserver may perform is unbinding,
ie. `/_matrix/client/r0/account/deactivate` and
`/_matrix/client/r0/account/3pid/delete`, in which case the unbind will be
authenticated by a signed request from the Homeserver.
### HS Register API
The `bind_email` and `bind_msisdn` options to `/_matrix/client/r0/register` in
the client/server API will be removed. Due to the fact that
`/_matrix/identity/v2/3pid/bind` requires authentication, it will no longer be
possible for the Homeserver to bind 3PIDs as part of the registration process.
### IS Register API
The following new APIs will be introduced to support OpenID auth as per
[MSC1961](https://github.com/matrix-org/matrix-doc/issues/1961):
* `/_matrix/identity/v2/account/register`
* `/_matrix/identity/v2/account`
* `/_matrix/identity/v2/account/logout`
Note again the removal of the `/api` prefix and migration to v2 following
convention from
[MSC2134](https://github.com/matrix-org/matrix-doc/issues/2134).
### Terms API
New API endpoints will be introduced:
#### `GET $prefix/terms`:
This returns a set of documents that the user must agree to abide by in order
to use the service. Its response is similar to the structure used in the
`m.terms` UI auth flow of the Client/Server API:
```json
{
"policies": {
"terms_of_service": {
"version": "2.0",
"en": {
"name": "Terms of Service",
"url": "https://example.org/somewhere/terms-2.0-en.html"
},
"fr": {
"name": "Conditions d'utilisation",
"url": "https://example.org/somewhere/terms-2.0-fr.html"
}
},
"privacy_policy": {
"version": "1.2",
"en": {
"name": "Privacy Policy",
"url": "https://example.org/somewhere/privacy-1.2-en.html"
},
"fr": {
"name": "Politique de confidentialité",
"url": "https://example.org/somewhere/privacy-1.2-fr.html"
}
}
}
}
```
Each document (ie. key/value pair in the 'policies' object) MUST be
uniquely identified by its URL. It is therefore strongly recommended
that the URL contains the version number of the document. The name
and version keys, however, are used only to provide a human-readable
description of the document to the user.
This endpoint does *not* require authentication.
#### `POST $prefix/terms`:
Requests to this endpoint have a single key, `user_accepts` whose value is
a list of URLs (given by the `url` field in the GET response) of documents that
the user has agreed to:
```json
{
"user_accepts": ["https://example.org/somewhere/terms-2.0-en.html"]
}
```
This endpoint requires authentication.
The clients MUST include the correct URL for the language of the document that
was presented to the user and they agreed to. Servers should accept agreement
of any one language of each document as sufficient, regardless of what language
a client is operating in: users should not have to re-consent to documents if
they change their client to a different language.
The server responds with an empty JSON object. The server must not assume that
the client will agree to all documents in a single request.
### Accepted Terms Account Data
This proposal also defines the `m.accepted_terms` section in User Account
Data in the client/server API that clients SHOULD use to track what sets of
terms the user has consented to. This has an array of URLs under the 'accepted'
key to which the user has agreed to.
An `m.accepted_terms` section therefore resembles the following:
```json
{
"accepted": [
"https://example.org/somewhere/terms-1.2-en.html",
"https://example.org/somewhere/privacy-1.2-en.html"
]
}
```
Whenever a client submits a `POST $prefix/terms` request to an IS or IM or
completes an `m.terms` flow on the HS (or as soon as possible afterwards, ie.
after registration is complete), it SHOULD update this account data section
adding any the URLs of any additional documents that the user agreed to to this
list.
### Terms Acceptance in the API
Before any requests are made to an Identity Server or Integration Manager,
the client must use the `GET $prefix/terms` endpoint to fetch the set of
documents that the user must agree to in order to use the service.
It then cross-references this set of documents against the `m.accepted_terms`
account data and presents to the user any documents that they have not already
agreed to, along with UI for them to indicate their agreement. If there are no
such documents (ie. if the `policies` dict is empty or the user has already
agreed to all documents) the client proceeds to perform the OpenID
registration. If there are new terms documents, the client prompts the user for
agreement, then once the user has indicated their agreement, it adds these URLs
to `m.accepted_terms` account data and then proceeds with OpenID
authentication, getting a token from the Homeserver and submitting this to the
service using the `register` endpoint.
Having done this, if the user agreed to any new documents, it performs a `POST
$prefix/terms` request to signal to the server the set of documents that the
user has agreed to.
Any request to any endpoint in the IM API, and the `/_matrix/identity/v2/`
namespace of the IS API, with the exception of `/_matrix/identity/v2` itself,
may return:
* `M_UNAUTHORIZED` errcode with HTTP status code 401. This indicates that
the user must authenticate with OpenID and supply a valid `access_token`.
* `M_TERMS_NOT_SIGNED` errcode with HTTP status code 403. This indicates
that the user must agree to (new) terms in order to use or continue to
use the service.
The `/_matrix/identity/v2/3pid/unbind` endpoint must not return either of these
errors if the request has a valid signature from a Homeserver, and is being authenticated as such.
In summary, the process for using a service that has not previously been used
in the current login session is:
* `GET $prefix/terms`
* Compare result with `m.accepted_terms` account data, get set of documents
pending agreement.
* If non-empty, show this set of documents to the user and wait for the user
to indicate their agreement.
* Add the newly agreed documents to `m.accepted_terms`.
* On success, or if there were no documents pending agreement, get an OpenID
token from the Homeserver and submit this token to the `register` endpoint.
Store the resulting access token.
* If the set of documents pending agreement was non-empty, Perform a
`POST $prefix/terms` request to the service with these documents.
### `POST /_matrix/client/r0/account/3pid/unbind`
A client uses this client/server API endpoint to request that the Homeserver
removes the given 3PID from the given Identity Server, or all Identity Servers.
Takes the same parameters as
`POST /_matrix/client/r0/account/3pid/delete`, ie. `id_server`, `medium`,
`address` and the newly added `is_token`.
Returns the same as `POST /_matrix/client/r0/account/3pid/delete`.
Clients may add IS bindings for 3PIDs that already exist on the user's
Homeserver account by using the `POST /_matrix/client/r0/account/3pid`
to re-add the 3PID.
## Tradeoffs
The Identity Service API previously did not require authentication, and OpenID
is reasonably complex, adding a significant burden to both clients and servers.
A custom HTTP header was also considered that could be added to assert that the
client agrees to a particular set of terms. We decided against this in favour
of re-using existing primitives that already exist in the Matrix ecosystem.
Custom HTTP headers are not used anywhere else within Matrix. This also gives a
very simple and natural way for ISes to enforce that users may only bind 3PIDs
to their own MXIDs.
This introduces a different way of accepting terms from the client/server API
which uses User-Interactive Authentication. In the client/server API, the use
of UI auth allows terms acceptance to be integrated into the registration flow
in a simple and backwards-compatible way. Another option here would be to use
UI Auth on the register endpoint. This would also not allow users to register
before accepting the terms. However, this would then make the OpenID
registration process different and non-standard.
The `m.accepted_terms` section contains only URLs of the documents that
have been agreed to. This loses information like the name and version of
the document, but:
* It would be up to the clients to copy this information correctly into
account data.
* Having just the URLs makes it much easier for clients to make a list
of URLs and find documents not already agreed to.
## Potential issues
This change deprecates all v1 endpoints and so will require clients to update
to continue working.
## Security considerations
Requiring authentication on the IS API means it will no longer be possible to
use it anonymously.
It is assumed that once servers publish a given version of a document at a
given URL, the contents of that URL will not change. This could be mitigated by
identifying documents based on a hash of their contents rather than their URLs.
Agreement to terms in the client/server API makes this assumption, so this
proposal aims to be consistent.
## Conclusion
This proposal adds an error response to all endpoints on the API and a custom
HTTP header on all requests that is used to signal agreement to a set of terms
and conditions. The use of the header is only necessary if the server has no
other means of tracking acceptance of terms per-user. The IS API is not
authenticated so ISes will have no choice but to use the header. The IM API is
authenticated so IMs may either use the header or store acceptance per-user.
A separate endpoint is specified with a GET request for retrieving the set
of terms required and a POST to indicate that the user consents to those
terms.

@ -0,0 +1,71 @@
# MSC2230: Store Identity Server in Account Data
The URL of the Identity Server to use is currently specified at registration and
login time and then used for the lifetime of a login session. If users wish to
specify a custom one, they must do so each time they log in on every client.
Once they have chosen an Identity Server to advertise their 3PIDs on, it would
be normal that they would wish to continue using this Identity Server for all
Identity requests in their account accross all clients. This proposal aims to
make this easier.
## Proposal
The base URL of the Identity Server is to be stored in user account data. It
shall be stored in the same format as in a .well-known file under the event type
`m.identity_server` and shall comprise a single key, `base_url` which is the
base URL of the ID Server to use (that is, the part before `/_matrix`, including
`https://`).
Upon registration or login, a client SHOULD refrain from performing any requests
to the Identity Server until the account data has been fetched from the server.
Once it has the account data, it SHOULD check for the presence of the
`m.identity_server` key. If present, the `base_url` in this key SHOULD be used
as the Identity Server base URL for the duration of the login session. If this
key is not present, the client SHOULD use whatever value it would have used prior
to this MSC. It should not update the account data in this situation.
Client SHOULD listen for changes in the `m.identity_server` account data value
and update the URL that they use for ID Server requests accordingly.
Clients can offer a way for users to change the ID server being used. If they
do, the client MUST update the value of `m.identity_server` accordingly.
The `m.identity_server` may be present with a `base_url` of `null`. In this case,
clients MUST treat this as no ID Server URL being set and not perform ID
Server requests, disabling any functionality that requires such requests.
Conversely, if a user wishes to disable ID Server functionality, the client
shall action this by setting the `base_url` of the `m.identity_server`
account data entry to `null`.
### Transition Period
Clients will continue to use whatever IS URLs they currently use until the
user sets one explicitly, at which point it will be written to account data
and all clients will start using this value.
## Tradeoffs
There are a number of ways to transition to this new scheme. Clients could
populate the account data with their current ID Server URL as soon as
possible, and immediately use any new value seen on account data. This
would a much faster migration but any users with clients using different
ID Servers would suddenly find all their clients using the ID Server of
whichever client they updated first.
## Potential issues
Users will no longer be able to have different clients configured with
different ID Servers.
## Security considerations
An attacker would be able to force all a user clients to use a given ID Server
if they gained control of any of a user's logins.
## Conclusion
This makes the ID server an account setting which means it persists between
logins. The intention would be to phase out clients ever asking for an ID
Server URL at registration or login: this will be much easier for users to
understand whilst still retaining the flexibilty for those who want it.

@ -1,11 +1,15 @@
{% import 'tables.tmpl' as tables -%}
``{{endpoint.method}} {{endpoint.path}}``
{{(5 + (endpoint.path | length) + (endpoint.method | length)) * title_kind}}
{% if "deprecated" in endpoint and endpoint.deprecated -%}
Deprecated: ``{{endpoint.method}} {{endpoint.path}}``
{{(17 + (endpoint.path | length) + (endpoint.method | length)) * title_kind}}
.. WARNING::
This API is deprecated and will be removed from a future release.
{% else %}
``{{endpoint.method}} {{endpoint.path}}``
{{(5 + (endpoint.path | length) + (endpoint.method | length)) * title_kind}}
{% endif -%}
{{endpoint.desc}}

@ -57,6 +57,8 @@ The following other versions are also available, in reverse chronological order:
General principles
------------------
.. TODO: TravisR - Define auth for IS v2 API in a future PR
The purpose of an identity server is to validate, store, and answer questions
about the identities of users. In particular, it stores associations of the form
"identifier X represents the same user as identifier Y", where identities may
@ -176,6 +178,8 @@ Status check
{{ping_is_http_api}}
{{v2_ping_is_http_api}}
Key management
--------------
@ -195,11 +199,15 @@ service's long-term keys.
{{pubkey_is_http_api}}
{{v2_pubkey_is_http_api}}
Association lookup
------------------
{{lookup_is_http_api}}
.. TODO: TravisR - Add v2 lookup API in future PR
Establishing associations
-------------------------
@ -243,16 +251,22 @@ Email associations
{{email_associations_is_http_api}}
{{v2_email_associations_is_http_api}}
Phone number associations
~~~~~~~~~~~~~~~~~~~~~~~~~
{{phone_associations_is_http_api}}
{{v2_phone_associations_is_http_api}}
General
~~~~~~~
{{associations_is_http_api}}
{{v2_associations_is_http_api}}
Invitation storage
------------------
@ -267,6 +281,8 @@ long-term private key for the identity server.
{{store_invite_is_http_api}}
{{v2_store_invite_is_http_api}}
Ephemeral invitation signing
----------------------------
@ -277,6 +293,8 @@ this isn't possible.
{{invitation_signing_is_http_api}}
{{v2_invitation_signing_is_http_api}}
.. _`Unpadded Base64`: ../appendices.html#unpadded-base64
.. _`3PID Types`: ../appendices.html#pid-types
.. _`Signing JSON`: ../appendices.html#signing-json

@ -756,8 +756,8 @@ sending `m.room_key_request`_ to-device messages to other devices with
device, it can forward the keys to the first device by sending an encrypted
`m.forwarded_room_key`_ to-device message. The first device should then send an
`m.room_key_request`_ to-device message with ``action`` set to
``cancel_request`` to the other devices that it had originally sent the key
request to; a device that receives a ``cancel_request`` should disregard any
``request_cancellation`` to the other devices that it had originally sent the key
request to; a device that receives a ``request_cancellation`` should disregard any
previously-received ``request`` message with the same ``request_id`` and
``requesting_device_id``.

@ -79,7 +79,7 @@ their proposed changes to the Matrix protocol:
* Pragmatism rather than perfection
* Proof rather than conjecture
Please see [MSC1779](https://github.com/matrix-org/matrix-doc/blob/matthew/msc1779/proposals/1779-open-governance.md)
Please see `MSC1779 <https://github.com/matrix-org/matrix-doc/blob/matthew/msc1779/proposals/1779-open-governance.md>`_
for full details of the project's Guiding Principles.
Technical notes

Loading…
Cancel
Save