diff --git a/.gitignore b/.gitignore index 800be2fa..9cc27b85 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ *.swp _rendered.rst /.vscode/ +/.idea/ diff --git a/README.rst b/README.rst index ace8ebdd..01ea8e72 100644 --- a/README.rst +++ b/README.rst @@ -66,12 +66,14 @@ The above will write the rendered version of the specification to Windows users ~~~~~~~~~~~~~ +The ``source`` program does not exist on Windows, so instead run one of the +``activate`` files in ``.\env\Scripts\`` to activate the virtual environment. If you're on Windows Vista or higher, be sure that the "Symbolic Links" option was selected when installing Git prior to cloning this repository. If you're still seeing errors about files not being found it is likely because the symlink at ``api/client-server/definitions/event-schemas`` looks like a -file. To correct the problem, open an Administrative/Elevated shell in your +file. To correct the problem, open an Administrative/Elevated Command Prompt in your cloned matrix-doc directory and run the following:: cd api\client-server\definitions diff --git a/api/client-server/keys.yaml b/api/client-server/keys.yaml index 69e39def..e172ea8a 100644 --- a/api/client-server/keys.yaml +++ b/api/client-server/keys.yaml @@ -101,7 +101,7 @@ paths: responses: 200: description: - The provided keys were sucessfully uploaded. + The provided keys were successfully uploaded. schema: type: object properties: diff --git a/api/client-server/redaction.yaml b/api/client-server/redaction.yaml index 58141049..907b1d16 100644 --- a/api/client-server/redaction.yaml +++ b/api/client-server/redaction.yaml @@ -37,7 +37,7 @@ paths: This cannot be undone. Users may redact their own events, and any user with a power level - greater than or equal to the `redact` power level of the room may + greater than or equal to the ``redact`` power level of the room may redact events there. operationId: redactEvent security: diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index 8114299e..50ce4a96 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -328,8 +328,8 @@ paths: The homeserver may change the flows available depending on whether a valid access token is provided. The homeserver SHOULD NOT revoke the - access token provided in the request, however all other access tokens - for the user should be revoked if the request succeeds. + access token provided in the request. Whether other access tokens for + the user are revoked depends on the request parameters. security: - accessToken: [] operationId: changePassword @@ -343,6 +343,12 @@ paths: type: string description: The new password for the account. example: "ihatebananas" + logout_devices: + type: boolean + description: |- + Whether the other access tokens, and their associated devices, for the user should be + revoked if the request succeeds. Defaults to true. + example: true auth: description: |- Additional authentication information for the user-interactive authentication API. diff --git a/api/client-server/room_send.yaml b/api/client-server/room_send.yaml index 6963f76c..fc8f3339 100644 --- a/api/client-server/room_send.yaml +++ b/api/client-server/room_send.yaml @@ -85,5 +85,7 @@ paths: type: string description: |- A unique identifier for the event. + required: + - event_id tags: - Room participation diff --git a/api/client-server/room_state.yaml b/api/client-server/room_state.yaml index 62168f26..640e2009 100644 --- a/api/client-server/room_state.yaml +++ b/api/client-server/room_state.yaml @@ -92,6 +92,8 @@ paths: type: string description: |- A unique identifier for the event. + required: + - event_id 403: description: |- The sender doesn't have permission to send the event into the room. diff --git a/api/client-server/room_upgrades.yaml b/api/client-server/room_upgrades.yaml index 55ee14dc..3aaaadcb 100644 --- a/api/client-server/room_upgrades.yaml +++ b/api/client-server/room_upgrades.yaml @@ -90,4 +90,4 @@ paths: schema: "$ref": "definitions/errors/error.yaml" tags: - - Room ugprades + - Room upgrades diff --git a/api/server-server/backfill.yaml b/api/server-server/backfill.yaml index 2ed6298c..d53de6c0 100644 --- a/api/server-server/backfill.yaml +++ b/api/server-server/backfill.yaml @@ -63,6 +63,14 @@ paths: description: |- A transaction containing the PDUs that preceded the given event(s), including the given event(s), up to the given limit. + + .. Note:: + Though the PDU definitions require that ``prev_events`` and ``auth_events`` be limited + in number, the response of backfill MUST NOT be validated on these specific restrictions. + + Due to historical reasons, it is possible that events which were previously accepted + would now be rejected by these limitations. The events should be rejected per usual by + the ``/send``, ``/get_missing_events``, and remaining endpoints. schema: $ref: "definitions/unlimited_pdu_transaction.yaml" "/get_missing_events/{roomId}": diff --git a/api/server-server/definitions/keys.yaml b/api/server-server/definitions/keys.yaml index 8bc6c563..1e025a52 100644 --- a/api/server-server/definitions/keys.yaml +++ b/api/server-server/definitions/keys.yaml @@ -20,7 +20,6 @@ properties: server_name: type: string description: DNS name of the homeserver. - required: true example: "example.org" verify_keys: type: object @@ -31,7 +30,6 @@ properties: algorithm and ``abc123`` being the version in the example below). Together, this forms the Key ID. The version must have characters matching the regular expression ``[a-zA-Z0-9_]``. - required: true additionalProperties: type: object title: Verify Key @@ -44,8 +42,8 @@ properties: key: type: string description: The `Unpadded Base64`_ encoded key. - required: true example: "VGhpcyBzaG91bGQgYmUgYSByZWFsIGVkMjU1MTkgcGF5bG9hZA" + required: ["key"] old_verify_keys: type: object description: |- @@ -69,13 +67,12 @@ properties: type: integer format: int64 description: POSIX timestamp in milliseconds for when this key expired. - required: true example: 1532645052628 key: type: string description: The `Unpadded Base64`_ encoded key. - required: true example: "VGhpcyBzaG91bGQgYmUgeW91ciBvbGQga2V5J3MgZWQyNTUxOSBwYXlsb2FkLg" + required: ["expired_ts", "key"] signatures: type: object description: Digital signatures for this object signed using the ``verify_keys``. @@ -103,3 +100,4 @@ properties: publishes a key which is valid for a significant amount of time without a way for the homeserver owner to revoke it. example: 1052262000000 +required: ["server_name", "verify_keys"] diff --git a/api/server-server/definitions/pdu_v3.yaml b/api/server-server/definitions/pdu_v3.yaml index 38105098..3e69d941 100644 --- a/api/server-server/definitions/pdu_v3.yaml +++ b/api/server-server/definitions/pdu_v3.yaml @@ -32,6 +32,10 @@ allOf: description: |- Event IDs for the authorization events that would allow this event to be in the room. + + Must contain less than or equal to 10 events. Note that if the relevant + auth event selection rules are used, this restriction should never be + encountered. example: ["$base64EncodedHash", "$AnotherEvent"] prev_events: type: array @@ -41,6 +45,8 @@ allOf: description: |- Event IDs for the most recent events in the room that the homeserver was aware of when it made this event. + + Must contain less than or equal to 20 events. example: ["$base64EncodedHash", "$AnotherEvent"] hashes: type: object diff --git a/api/server-server/definitions/pdu_v4.yaml b/api/server-server/definitions/pdu_v4.yaml index a045e657..d22956c6 100644 --- a/api/server-server/definitions/pdu_v4.yaml +++ b/api/server-server/definitions/pdu_v4.yaml @@ -32,6 +32,10 @@ allOf: description: |- Event IDs for the authorization events that would allow this event to be in the room. + + Must contain less than or equal to 10 events. Note that if the relevant + auth event selection rules are used, this restriction should never be + encountered. example: ["$URLsafe-base64EncodedHash", "$Another_Event"] prev_events: type: array @@ -41,6 +45,8 @@ allOf: description: |- Event IDs for the most recent events in the room that the homeserver was aware of when it made this event. + + Must contain less than or equal to 20 events. example: ["$URLsafe-base64EncodedHash", "$Another_Event"] required: - auth_events diff --git a/api/server-server/definitions/unsigned_pdu_base.yaml b/api/server-server/definitions/unsigned_pdu_base.yaml index 283e4fed..f1485b55 100644 --- a/api/server-server/definitions/unsigned_pdu_base.yaml +++ b/api/server-server/definitions/unsigned_pdu_base.yaml @@ -53,6 +53,8 @@ properties: description: |- Event IDs and reference hashes for the most recent events in the room that the homeserver was aware of when it made this event. + + Must contain less than or equal to 20 events. items: type: array maxItems: 2 @@ -84,6 +86,10 @@ properties: description: |- Event IDs and reference hashes for the authorization events that would allow this event to be in the room. + + Must contain less than or equal to 10 events. Note that if the relevant + auth event selection rules are used, this restriction should never be + encountered. items: type: array maxItems: 2 diff --git a/api/server-server/event_auth.yaml b/api/server-server/event_auth.yaml index 0db0d401..8f545e1d 100644 --- a/api/server-server/event_auth.yaml +++ b/api/server-server/event_auth.yaml @@ -72,137 +72,3 @@ paths: example: $ref: "examples/minimal_pdu.json" required: ['auth_chain'] - "/query_auth/{roomId}/{eventId}": - post: - summary: Compare auth chains with the receiving server - description: |- - Compares the auth chain provided with what the receiving server has for the - room ID and event ID combination. - - The auth difference can be calculated in two parts, where the "remote auth" - is the auth chain provided by the sending server and the "local auth" is the - auth chain the receiving server has. With those lists, the algorithm works - 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 - type: string - description: The room ID to compare the auth chain in. - required: true - x-example: "!abc123:matrix.org" - - in: path - name: eventId - type: string - description: The event ID to compare the auth chain of. - required: true - x-example: "$helloworld:example.org" - - in: body - name: body - schema: - type: object - properties: - auth_chain: - type: array - description: |- - The auth chain (the "remote auth"). Note that events have a different - format depending on the room version - check the `room version specification`_ - for precise event formats. - items: - type: object - title: PDU - description: |- - The `PDUs <#pdus>`_ contained in the auth chain. The event format - varies depending on the room version - check the `room version specification`_ - for precise event formats. - properties: [] - example: - $ref: "examples/minimal_pdu.json" - missing: - type: array - description: |- - A list of event IDs that the sender thinks the receiver is missing. - items: - type: string - example: [] - rejects: - type: object - description: |- - The set of events that the sending server has rejected from the provided - auth chain. - - The ``string`` key is the event ID that was rejected. - additionalProperties: - type: object - title: Rejection Reason - properties: - reason: - type: enum - enum: ['auth_error', 'replaced', 'not_ancestor'] - description: |- - The reason for the event being rejected. - required: ['reason'] - example: { - "$some_event:example.org": { - "reason": "auth_error" - } - } - required: ['auth_chain'] - responses: - 200: - description: The auth chain differences, as determined by the receiver. - schema: - type: object - properties: - auth_chain: - type: array - description: |- - The auth chain the receiver has, and used to determine the auth - chain differences (the "local auth"). Note that events have a different - format depending on the room version - check the `room version specification`_ - for precise event formats. - items: - type: object - title: PDU - description: |- - The `PDUs <#pdus>`_ contained in the auth chain. The event format - varies depending on the room version - check the `room version specification`_ - for precise event formats. - properties: [] - example: - $ref: "examples/minimal_pdu.json" - missing: - type: array - description: |- - The list of event IDs that the receiver believes it is missing, - after comparing the "remote auth" and "local auth" chains. - items: - type: string - example: ["$a_missing_event:example.org"] - rejects: - type: object - description: |- - The set of events that the receiving server has rejected from the - auth chain, not including events that the sending server is missing - as determined from the difference algorithm. - - The ``string`` key is the event ID that was rejected. - additionalProperties: - type: object - title: Rejection Reason - properties: - reason: - type: enum - enum: ['auth_error', 'replaced', 'not_ancestor'] - description: |- - The reason for the event being rejected. - required: ['reason'] - example: { - "$some_event:example.org": { - "reason": "auth_error" - } - } - required: ['auth_chain', 'missing', 'rejects'] diff --git a/changelogs/README.md b/changelogs/README.md index a5fb1fb7..5a5b6271 100644 --- a/changelogs/README.md +++ b/changelogs/README.md @@ -2,14 +2,14 @@ # Changelogs -[Towncrier](https://github.com/hawkowl/towncrier) is used to manage the changelog and +[Towncrier](https://github.com/hawkowl/towncrier) is used to manage the changelog and keep it up to date. Because of this, updating a changelog is really easy. ## How to update a changelog when releasing an API 1. Ensure you're in your Python 3 virtual environment 2. `cd` your way to the API you're releasing (eg: `cd changelogs/client_server`) -3. Run `towncrier --version "r0.4.0" --name "client-server" --yes` substituting the +3. Run `towncrier --version "r0.4.0" --name "client-server" --yes` substituting the variables as approprite. Note that `--name` is required although the value is ignored. 4. Commit the changes and finish the release process. @@ -26,27 +26,32 @@ For this example, we're going to pretend that the `server_server` API doesn't ex directory = "newsfragments" issue_format = "`#{issue} `_" title_format = "{version}" - + [[tool.towncrier.type]] directory = "breaking" name = "Breaking Changes" showcontent = true - + [[tool.towncrier.type]] directory = "deprecation" name = "Deprecations" showcontent = true - + [[tool.towncrier.type]] directory = "new" name = "New Endpoints" showcontent = true - + + [[tool.towncrier.type]] + directory = "removal" + name = "Removed Endpoints" + showcontent = true + [[tool.towncrier.type]] directory = "feature" name = "Backwards Compatible Changes" showcontent = true - + [[tool.towncrier.type]] directory = "clarification" name = "Spec Clarifications" diff --git a/changelogs/application_service/pyproject.toml b/changelogs/application_service/pyproject.toml index 44d430e8..278def78 100644 --- a/changelogs/application_service/pyproject.toml +++ b/changelogs/application_service/pyproject.toml @@ -3,27 +3,32 @@ directory = "newsfragments" issue_format = "`#{issue} `_" title_format = "{version}" - + [[tool.towncrier.type]] directory = "breaking" name = "Breaking Changes" showcontent = true - + [[tool.towncrier.type]] directory = "deprecation" name = "Deprecations" showcontent = true - + [[tool.towncrier.type]] directory = "new" name = "New Endpoints" showcontent = true - + + [[tool.towncrier.type]] + directory = "removal" + name = "Removed Endpoints" + showcontent = true + [[tool.towncrier.type]] directory = "feature" name = "Backwards Compatible Changes" showcontent = true - + [[tool.towncrier.type]] directory = "clarification" name = "Spec Clarifications" diff --git a/changelogs/client_server.rst b/changelogs/client_server.rst index a5173fd0..bc12da5c 100644 --- a/changelogs/client_server.rst +++ b/changelogs/client_server.rst @@ -74,7 +74,7 @@ Backwards Compatible Changes - Support optional features by having clients query for capabilities. (`#1829 `_, `#1879 `_) - Add ``M_RESOURCE_LIMIT_EXCEEDED`` as an error code for when homeservers exceed limits imposed on them. (`#1874 `_) - Emit ``M_UNSUPPORTED_ROOM_VERSION`` error codes where applicable on ``/createRoom`` and ``/invite`` APIs. (`#1908 `_) -- Add a ``.m.rule.tombstone`` default push rule for room ugprade notifications. (`#2020 `_) +- Add a ``.m.rule.tombstone`` default push rule for room upgrade notifications. (`#2020 `_) - Add support for sending server notices to clients. (`#2026 `_) - Add MSISDN (phone number) support to User-Interactive Authentication. (`#2030 `_) - Add the option to lazy-load room members for increased client performance. (`#2035 `_) diff --git a/changelogs/client_server/2245.clarification b/changelogs/client_server/newsfragments/2245.clarification similarity index 100% rename from changelogs/client_server/2245.clarification rename to changelogs/client_server/newsfragments/2245.clarification diff --git a/changelogs/client_server/newsfragments/2415.clarification b/changelogs/client_server/newsfragments/2415.clarification index d1a7dbfe..902a9c3f 100644 --- a/changelogs/client_server/newsfragments/2415.clarification +++ b/changelogs/client_server/newsfragments/2415.clarification @@ -1 +1 @@ -Fix misspelling of _deprecated_. \ No newline at end of file +Fix various spelling errors throughout the specification. diff --git a/changelogs/client_server/newsfragments/2434.feature b/changelogs/client_server/newsfragments/2434.feature new file mode 100644 index 00000000..2b8f36f5 --- /dev/null +++ b/changelogs/client_server/newsfragments/2434.feature @@ -0,0 +1 @@ +Added data structures for defining moderation policies in rooms per `MSC2313 `_. diff --git a/changelogs/client_server/newsfragments/2453.clarification b/changelogs/client_server/newsfragments/2453.clarification new file mode 100644 index 00000000..902a9c3f --- /dev/null +++ b/changelogs/client_server/newsfragments/2453.clarification @@ -0,0 +1 @@ +Fix various spelling errors throughout the specification. diff --git a/changelogs/client_server/newsfragments/2492.clarification b/changelogs/client_server/newsfragments/2492.clarification new file mode 100644 index 00000000..88c478ec --- /dev/null +++ b/changelogs/client_server/newsfragments/2492.clarification @@ -0,0 +1 @@ +Clarify the IV data type for encrypted files. diff --git a/changelogs/client_server/newsfragments/2519.clarification b/changelogs/client_server/newsfragments/2519.clarification new file mode 100644 index 00000000..4b32da1e --- /dev/null +++ b/changelogs/client_server/newsfragments/2519.clarification @@ -0,0 +1 @@ +Fix the ``.m.rule.contains_user_name`` default push rule to set the highlight tweak. diff --git a/changelogs/client_server/newsfragments/2523.feature b/changelogs/client_server/newsfragments/2523.feature new file mode 100644 index 00000000..e45d1c2f --- /dev/null +++ b/changelogs/client_server/newsfragments/2523.feature @@ -0,0 +1 @@ +Optionally invalidate other access tokens during password modification per `MSC2457 `_. diff --git a/changelogs/client_server/newsfragments/2524.clarification b/changelogs/client_server/newsfragments/2524.clarification new file mode 100644 index 00000000..902a9c3f --- /dev/null +++ b/changelogs/client_server/newsfragments/2524.clarification @@ -0,0 +1 @@ +Fix various spelling errors throughout the specification. diff --git a/changelogs/client_server/newsfragments/2525.clarification b/changelogs/client_server/newsfragments/2525.clarification new file mode 100644 index 00000000..df1fc538 --- /dev/null +++ b/changelogs/client_server/newsfragments/2525.clarification @@ -0,0 +1 @@ +Clarify that an ``event_id`` is returned when sending events. diff --git a/changelogs/client_server/newsfragments/2532.feature b/changelogs/client_server/newsfragments/2532.feature new file mode 100644 index 00000000..cf74a289 --- /dev/null +++ b/changelogs/client_server/newsfragments/2532.feature @@ -0,0 +1 @@ +Add User-Interactive Authentication for SSO-backed homeserver per `MSC2454 `_. diff --git a/changelogs/client_server/pyproject.toml b/changelogs/client_server/pyproject.toml index 8fa3f6b5..eb9e7b4e 100644 --- a/changelogs/client_server/pyproject.toml +++ b/changelogs/client_server/pyproject.toml @@ -3,27 +3,32 @@ directory = "newsfragments" issue_format = "`#{issue} `_" title_format = "{version}" - + [[tool.towncrier.type]] directory = "breaking" name = "Breaking Changes" showcontent = true - + [[tool.towncrier.type]] directory = "deprecation" name = "Deprecations" showcontent = true - + [[tool.towncrier.type]] directory = "new" name = "New Endpoints" showcontent = true - + + [[tool.towncrier.type]] + directory = "removal" + name = "Removed Endpoints" + showcontent = true + [[tool.towncrier.type]] directory = "feature" name = "Backwards Compatible Changes" showcontent = true - + [[tool.towncrier.type]] directory = "clarification" name = "Spec Clarifications" diff --git a/changelogs/identity_service/pyproject.toml b/changelogs/identity_service/pyproject.toml index a7fe582d..2e50b9df 100644 --- a/changelogs/identity_service/pyproject.toml +++ b/changelogs/identity_service/pyproject.toml @@ -19,6 +19,11 @@ name = "New Endpoints" showcontent = true + [[tool.towncrier.type]] + directory = "removal" + name = "Removed Endpoints" + showcontent = true + [[tool.towncrier.type]] directory = "feature" name = "Backwards Compatible Changes" diff --git a/changelogs/push_gateway/pyproject.toml b/changelogs/push_gateway/pyproject.toml index dad1bc04..9f2595c9 100644 --- a/changelogs/push_gateway/pyproject.toml +++ b/changelogs/push_gateway/pyproject.toml @@ -3,27 +3,32 @@ directory = "newsfragments" issue_format = "`#{issue} `_" title_format = "{version}" - + [[tool.towncrier.type]] directory = "breaking" name = "Breaking Changes" showcontent = true - + [[tool.towncrier.type]] directory = "deprecation" name = "Deprecations" showcontent = true - + [[tool.towncrier.type]] directory = "new" name = "New Endpoints" showcontent = true - + + [[tool.towncrier.type]] + directory = "removal" + name = "Removed Endpoints" + showcontent = true + [[tool.towncrier.type]] directory = "feature" name = "Backwards Compatible Changes" showcontent = true - + [[tool.towncrier.type]] directory = "clarification" name = "Spec Clarifications" diff --git a/changelogs/server_server/newsfragments/2470.removal b/changelogs/server_server/newsfragments/2470.removal new file mode 100644 index 00000000..51cdadd4 --- /dev/null +++ b/changelogs/server_server/newsfragments/2470.removal @@ -0,0 +1 @@ +Remove the unused ``query_auth`` API per `MSC2451 `_. diff --git a/changelogs/server_server/newsfragments/2510.clarification b/changelogs/server_server/newsfragments/2510.clarification new file mode 100644 index 00000000..9c96c5a5 --- /dev/null +++ b/changelogs/server_server/newsfragments/2510.clarification @@ -0,0 +1 @@ +Fix typo in Request Authentication python example. diff --git a/changelogs/server_server/newsfragments/2527.clarification b/changelogs/server_server/newsfragments/2527.clarification new file mode 100644 index 00000000..329d5da2 --- /dev/null +++ b/changelogs/server_server/newsfragments/2527.clarification @@ -0,0 +1 @@ +Clarify which fields are required on the key server endpoints. diff --git a/changelogs/server_server/newsfragments/2538.clarification b/changelogs/server_server/newsfragments/2538.clarification new file mode 100644 index 00000000..4b709a8d --- /dev/null +++ b/changelogs/server_server/newsfragments/2538.clarification @@ -0,0 +1 @@ +Clarify the limits of ``prev_events`` and ``auth_events`` for PDUs. diff --git a/changelogs/server_server/pyproject.toml b/changelogs/server_server/pyproject.toml index 98478527..6a9dca1d 100644 --- a/changelogs/server_server/pyproject.toml +++ b/changelogs/server_server/pyproject.toml @@ -3,27 +3,32 @@ directory = "newsfragments" issue_format = "`#{issue} `_" title_format = "{version}" - + [[tool.towncrier.type]] directory = "breaking" name = "Breaking Changes" showcontent = true - + [[tool.towncrier.type]] directory = "deprecation" name = "Deprecations" showcontent = true - + [[tool.towncrier.type]] directory = "new" name = "New Endpoints" showcontent = true - + + [[tool.towncrier.type]] + directory = "removal" + name = "Removed Endpoints" + showcontent = true + [[tool.towncrier.type]] directory = "feature" name = "Backwards Compatible Changes" showcontent = true - + [[tool.towncrier.type]] directory = "clarification" name = "Spec Clarifications" diff --git a/event-schemas/examples/m.policy.rule.room b/event-schemas/examples/m.policy.rule.room new file mode 100644 index 00000000..5a532cb5 --- /dev/null +++ b/event-schemas/examples/m.policy.rule.room @@ -0,0 +1,10 @@ +{ + "$ref": "core/state_event.json", + "type": "m.policy.rule.room", + "state_key": "rule:#*:example.org", + "content": { + "entity": "#*:example.org", + "recommendation": "m.ban", + "reason": "undesirable content" + } +} diff --git a/event-schemas/examples/m.policy.rule.server b/event-schemas/examples/m.policy.rule.server new file mode 100644 index 00000000..3d740a28 --- /dev/null +++ b/event-schemas/examples/m.policy.rule.server @@ -0,0 +1,10 @@ +{ + "$ref": "core/state_event.json", + "type": "m.policy.rule.server", + "state_key": "rule:*.example.org", + "content": { + "entity": "*.example.org", + "recommendation": "m.ban", + "reason": "undesirable engagement" + } +} diff --git a/event-schemas/examples/m.policy.rule.user b/event-schemas/examples/m.policy.rule.user new file mode 100644 index 00000000..eb3832da --- /dev/null +++ b/event-schemas/examples/m.policy.rule.user @@ -0,0 +1,10 @@ +{ + "$ref": "core/state_event.json", + "type": "m.policy.rule.user", + "state_key": "rule:@alice*:example.org", + "content": { + "entity": "@alice*:example.org", + "recommendation": "m.ban", + "reason": "undesirable behaviour" + } +} diff --git a/event-schemas/moderation_policy_rule.yaml b/event-schemas/moderation_policy_rule.yaml new file mode 100644 index 00000000..34ad4d9a --- /dev/null +++ b/event-schemas/moderation_policy_rule.yaml @@ -0,0 +1,30 @@ +# Copyright 2020 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. +properties: + entity: + description: |- + The entity affected by this rule. Glob characters ``*`` and ``?`` can be used + to match zero or more and one or more characters respectively. + type: string + recommendation: + description: The suggested action to take. Currently only ``m.ban`` is specified. + type: string + reason: + description: The human-readable description for the ``recommendation``. + type: string +type: object +required: + - entity + - recommendation + - reason diff --git a/event-schemas/schema/m.policy.rule.room b/event-schemas/schema/m.policy.rule.room new file mode 100644 index 00000000..ff81543e --- /dev/null +++ b/event-schemas/schema/m.policy.rule.room @@ -0,0 +1,15 @@ +--- +allOf: + - $ref: core-event-schema/state_event.yaml +description: A moderation policy rule which affects room IDs and room aliases. +properties: + content: + $ref: "../moderation_policy_rule.yaml" + state_key: + description: An arbitrary string decided upon by the sender. + type: string + type: + enum: + - m.policy.rule.room + type: string +type: object diff --git a/event-schemas/schema/m.policy.rule.server b/event-schemas/schema/m.policy.rule.server new file mode 100644 index 00000000..ca37e8ff --- /dev/null +++ b/event-schemas/schema/m.policy.rule.server @@ -0,0 +1,15 @@ +--- +allOf: + - $ref: core-event-schema/state_event.yaml +description: A moderation policy rule which affects servers. +properties: + content: + $ref: "../moderation_policy_rule.yaml" + state_key: + description: An arbitrary string decided upon by the sender. + type: string + type: + enum: + - m.policy.rule.server + type: string +type: object diff --git a/event-schemas/schema/m.policy.rule.user b/event-schemas/schema/m.policy.rule.user new file mode 100644 index 00000000..4fa65ad8 --- /dev/null +++ b/event-schemas/schema/m.policy.rule.user @@ -0,0 +1,15 @@ +--- +allOf: + - $ref: core-event-schema/state_event.yaml +description: A moderation policy rule which affects users. +properties: + content: + $ref: "../moderation_policy_rule.yaml" + state_key: + description: An arbitrary string decided upon by the sender. + type: string + type: + enum: + - m.policy.rule.user + type: string +type: object diff --git a/proposals/1756-cross-signing.md b/proposals/1756-cross-signing.md index 4b5904bc..de08422a 100644 --- a/proposals/1756-cross-signing.md +++ b/proposals/1756-cross-signing.md @@ -216,7 +216,7 @@ response: } ``` -Similarly, the federation endpoints `POST /user/keys/query` and `POST +Similarly, the federation endpoints `POST /user/keys/query` and `GET /user/devices/{userId}` will include the master and self-signing keys. (It will not include the user-signing key because it is not intended to be visible to other users.) @@ -463,7 +463,7 @@ response: } ``` -Similarly, the federation endpoints `GET /user/keys/query` and `POST +Similarly, the federation endpoints `POST /user/keys/query` and `GET /user/devices/{userId}` will include the new signatures for her own devices or master key, but not signatures made by her user-signing key. diff --git a/proposals/1946-secure_server-side_storage.md b/proposals/1946-secure_server-side_storage.md index fd907e53..3f386d5e 100644 --- a/proposals/1946-secure_server-side_storage.md +++ b/proposals/1946-secure_server-side_storage.md @@ -66,7 +66,7 @@ corresponds to the public key. Encrypted data is stored in the user's account_data using the event type defined by the feature that uses the data. For example, decryption keys for -key backups could be stored under the type `m.megolm_backup.v1.recovery_key`, +key backups could be stored under the type `m.megolm_backup.v1`, or the self-signing key for cross-signing could be stored under the type `m.cross_signing.self_signing`. diff --git a/proposals/2422-allow-color-attribute-on-font-tag.md b/proposals/2422-allow-color-attribute-on-font-tag.md new file mode 100644 index 00000000..4e6a9ced --- /dev/null +++ b/proposals/2422-allow-color-attribute-on-font-tag.md @@ -0,0 +1,39 @@ +# MSC2422: Allow `color` as attribute for `` in messages + +Currently the spec recommends that you to use `data-mx-color` instead of the standard +`color` html attribute for the `` tag. This is probably done to make it +consistent with ``, where you may not want to allow a generic style tag for. + +On the other hand the /rainbow command on almost every client just uses the +`color` attribute of the `` tag. While some clients support +`data-mx-color` (i.e. Riot Web), most clients don't. Most clients support +rendering `color` however. + +It would probably be for the best to allow or even prefer `color` on the +`` tag. + +## Proposal + +Add the `color` attribute to the allowed attributes of `` in section +13.2.1.7. No changes to the allowable values from the HTML spec are made here. + +## Potential issues + +- We now have a redundant attribute in the spec. While it matches what the + clients currently do, it may be better to fix each client instead. +- Clients may not sanitize the color attribute and will let other color values + through, increasing compatibility issues again. +- Clients may never support the data-mx-* attributes now. +- Old messages could loose their color +- This proposal doesn't touch span at all, maybe it should? + +## Alternatives + +- fix the clients + -> This currently seems not feasible. Multiple clients started using color first (i.e. RiotX, Gomuks) and if it isn't spelled out explicitly in the spec, this will probably continue. +- remove the `data-mx-color` and `data-mx-bg-color` attributes entirely, leaving us just with `color` for `` + -> This would break old messages and can be done independently of this proposal at a later date, if it is deemed useful. +- Add a section to tell the clients to prefer `color` over `mx-data-color` + -> I don't really know, why mx-data-* was chosen, but I assume there was a reason, so I don't want to change that. +- Spec an entirely different format for messages (that would probably not make this proposal obsolete) + -> This wouldn't fix the issue, where some client may choose to remove the color tag, since it is discouraged in the spec. Migration would probably also take a while, so this proposal is a quick solution, that doesn't prevent other solutions at a later date. diff --git a/proposals/2432-revised-alias-publishing.md b/proposals/2432-revised-alias-publishing.md new file mode 100644 index 00000000..4c2f010f --- /dev/null +++ b/proposals/2432-revised-alias-publishing.md @@ -0,0 +1,247 @@ +# MSC2432: Updated semantics for publishing room aliases + +This MSC offers an alternative to [MSC2260](https://github.com/matrix-org/matrix-doc/issues/2260). + +## Background + +The [`m.room.aliases`](https://matrix.org/docs/spec/client_server/r0.6.0#m-room-aliases) +state event exists to list the available aliases for a given room. This serves +two purposes: + + * It allows existing members of the room to discover alternative aliases, + which may be useful for them to pass this knowledge on to others trying to + join. + + * Secondarily, it helps to educate users about how Matrix works by + illustrating multiple aliases per room and giving a perception of the size + of the network. + +However, it has problems: + + * Any user in the entire ecosystem can create aliases for rooms, which are + then unilaterally added to `m.room.aliases`, and room admins are unable to + remove them. This is an abuse + vector (https://github.com/matrix-org/matrix-doc/issues/625). + + * For various reasons, the `m.room.aliases` event tends to get out of sync + with the actual aliases (https://github.com/matrix-org/matrix-doc/issues/2262). + +## Proposal + +We propose that that room moderators should be able to manually curate a list +of "official" aliases for their room, instead of matrix servers automatically +publishing lists of all room aliases into the room state. No particular +guarantees are offered that this alias list is entirely accurate: it becomes +room moderators' responsibility to keep it so. + +Meanwhile, the aliases that map to a given room on a given server become +the ultimate responsibility of the administrators of that server. We give them +tools to inspect the alias list and clean it up when necessary, in addition to +the current tools which allow restriction of who can create aliases in the +first place. + +A detailed list of proposed modifications to the Matrix spec follows: + + * `m.room.aliases` loses any special meaning within the spec. In particular: + + * Clients should no longer format it specially in room timelines. + + * Clients and servers should no longer consider `m.room.aliases` when + [calculating the display name for a + room](https://matrix.org/docs/spec/client_server/r0.6.0#calculating-the-display-name-for-a-room). + + (Note: servers follow the room display-name algorithm when calculating + room names for certain types of push notification.) + + * A future room version will remove the special [authorization +rules](https://matrix.org/docs/spec/rooms/v1#authorization-rules) and +[redaction rules](https://matrix.org/docs/spec/client_server/r0.6.0#redactions). + + * [`m.room.canonical_alias`](https://matrix.org/docs/spec/client_server/r0.6.0#m-room-canonical-alias) + is extended to include a new `alt_aliases` property. This, if present, + should be a list of alternative aliases for the room. An example event might + look like: + + ```json + { + "content": { + "alias": "#somewhere:localhost", + "alt_aliases": [ + "#somewhere:overthere.com", + "#somewhereelse:example.com" + ] + }, + "room_id": "!jEsUZKDJdhlrceRyVU:example.org", + "state_key": "", + "type": "m.room.canonical_alias" + } + ``` + + It is valid for `alt_aliases` to be non-empty even if `alias` is absent or + empty. This means that no alias has been picked out as the 'main' alias. + + (Note: although the spec currently claims that `alias` is mandatory, Synapse + generates `m.room.canonical_alias` events with no `alias` property when the + main alias is deleted. This change would legitimise that behaviour.) + + (For clarity: it is not proposed that the `alt_aliases` be considered when + calculating the displayname for a room.) + + * [`PUT /_matrix/client/r0/rooms/{roomId}/state/{eventType}/{stateKey}`](https://matrix.org/docs/spec/client_server/r0.6.0#put-matrix-client-r0-rooms-roomid-state-eventtype-statekey) + is extended to recommend that servers validate any *new* aliases added to + `m.room.canonical_alias` by checking that it is a valid alias according to + the [syntax](https://matrix.org/docs/spec/appendices#room-aliases), and by + looking up the alias and and that it corresponds to the expected room ID. + + (Note: Synapse currently implements this check on the main alias, though + this is unspecced.) + + The following error codes are specified: + + * HTTP 400, with `errcode: M_INVALID_PARAMETER` if an attempt is made to add + an entry which is not a well-formed alias (examples: too long, doesn't + start with `#`, doesn't contain a `:`). + + * HTTP 400, with `errcode: M_BAD_ALIAS` if an added alias does not point at + the given room (either because the alias doesn't exist, because it can't + be resolved due to an unreachable server, or because the alias points at a + different room). + + * Currently, [`PUT /_matrix/client/r0/directory/room/{roomAlias}`](https://matrix.org/docs/spec/client_server/r0.6.0#put-matrix-client-r0-directory-room-roomalias) + attempts to send updated `m.room.aliases` events on the caller's + behalf. (This is implemented in Synapse but does not appear to be explicitly + specced.) This functionality should be removed. + + * Currently, [`DELETE /_matrix/client/r0/directory/room/{roomAlias}`](https://matrix.org/docs/spec/client_server/r0.6.0#delete-matrix-client-r0-directory-room-roomalias), + attempts to send updated `m.room.aliases` and/or `m.room.canonical_alias` + events on the caller's behalf, removing any aliases which have been + deleted. (Again, this is implemented in Synapse but does not appear to be + explicitly specced.) The `m.room.aliases` functionality should be removed, + and the `m.room.canonical_alias` functionality should be extended to cover + `alt_aliases`. + + The behaviour if the calling user has permission to delete the alias but + does not have permission to send `m.room.canonical_alias` events in the room + (for example, by virtue of being a "server administrator", or by being the + user that created the alias) is implementation-defined. It is *recommended* + that in this case, the alias is deleted anyway, and a successful response is + returned to the client. + + * A new api endpoint, `GET /_matrix/client/r0/rooms/{roomId}/aliases` is + added, which returns the list of aliases currently defined on the local + server for the given room. The response looks like: + + ```json + { + "aliases": [ + "#somewhere:example.com", + "#somewhereelse:example.com", + "#special_alias:example.com" + ] + } + ``` + + This API can be called by any current member of the room (calls from other + users result in `M_FORBIDDEN`). For rooms with `history_visibility` set to + `world_readable`, it can also be called by users outside the room. + + Servers might also choose to allow access to other users such as server + administrators. + +Various APIs are currently subject to implementation-defined access +restrictions. No change to the specification is introduced in this regard +(implementations will continue to be free to impose their own +restrictions). Nevertheless as part of this MSC it is useful to consider some +proposed changes to Synapse's implementation: + + * No change: `PUT /_matrix/client/r0/directory/room/{roomAlias}`: Synapse + only allows access to current members of the room, and also exposes some + configuration options which allow restriction of which users are allowed to + create aliases in general. + + * `DELETE /_matrix/client/r0/directory/room/{roomAlias}`: in this case, + currently Synapse restricts its use to the user that created the alias, and + server admins. + + It is proposed to extend this to local users who have a power-level + sufficient to send an `m.room.canonical_alias` event in the room that the + alias currently points to. + + * [`PUT /_matrix/client/r0/directory/list/room/{roomId}`](https://matrix.org/docs/spec/client_server/r0.6.0#put-matrix-client-r0-directory-list-room-roomid) + and the corresponding unspecced `DELETE` api (both of which set the + visibility of a room in the public directory): currently Synapse restricts + their use to server admins and local users who have a PL sufficient to send + an `m.room.aliases` event in the room (ignoring the special auth + rules). This will be changed to check against the PL required to send an + `m.room.canonical_alias` event. + +It is envisaged that Matrix clients will then change their "Room Settings" user +interface to display the aliases from `m.room.canonical_alias` instead of those +in `m.room.aliases`, as well as giving moderators the ability to update that +list. Clients might also wish to use the new `GET +/_matrix/client/r0/rooms/{roomId}/aliases` endpoint to obtain and display the +currently-available local aliases, though given that this list may be subject +to abuse, it should probably not be shown by default. + +### Future work + +This work isn't considered part of this MSC, but rather a potential extension +for the future. + + * It may be useful to be able to query remote servers for their alias + list. This could be done by extending `GET + /_matrix/client/r0/rooms/{roomId}/aliases` to take a `server_name` + parameter, and defining an API in the server_server spec which will expose + the requested information, subject to the calling homeserver having at least + one user with a right to see it. + + * Similarly, room moderators may wish to be able to delete aliases on a remote + server for their room. We could envisage a federation API which allows such + a request to be made, subject to the calling homeserver having at least one + moderator in the room. + +## Potential issues + +The biggest problem with this proposal is that existing clients, which rely on +`m.room.aliases` in one way or another, will lose functionality. In particular, +they may not know about aliases that exist, or they may look at outdated +`m.room.aliases` events that list aliases that no longer exist. However, since +`m.room.aliases` is best-effort anyway, these are both problems that exist to +some extent today. + +## Alternatives + +We considered continuing to use `m.room.aliases` to advertise room aliases +instead of `m.room.canonical_alias`, but the significant changes in semantics +made that seem inappropriate. + +We also considered using separate state events for each advertised alias, +rather than listing them all in one event. This might increase the number of +aliases which can be advertised, and help to reduce races when editing the +list. However, the 64KB limit of an event still allows room for hundreds of +aliases of any sane length, and we don't expect the list to be changing +frequently enough for races to be a practical concern. Ultimately the added +complexity seemed redundant. + +A previous suggestion was +[MSC2260](https://github.com/matrix-org/matrix-doc/issues/2260), which proposed +keeping `m.room.aliases` largely as-is, but giving room moderators tools to +control who can send them via room power-levels. We dismissed it for the +reasons set out at +https://github.com/matrix-org/matrix-doc/pull/2260#issuecomment-584207073. + +## Security considerations + +None currently identified. + +## Unstable prefix + +While this feature is in development, the following names will be in use: + +| Proposed final name | Name while in development | +| --- | --- | +| `GET /_matrix/client/r0/rooms/{roomId}/aliases` | `GET /_matrix/client/unstable/org.matrix.msc2432/rooms/{roomId}/aliases` | + +Servers will indicate support for the new endpoint via a non-empty value for feature flag +`org.matrix.msc2432` in `unstable_features` in the response to `GET +/_matrix/client/versions`. diff --git a/proposals/2451-remove-query_auth-federation-endpoint.md b/proposals/2451-remove-query_auth-federation-endpoint.md new file mode 100644 index 00000000..b2d8bc9f --- /dev/null +++ b/proposals/2451-remove-query_auth-federation-endpoint.md @@ -0,0 +1,56 @@ +# MSC2451: Remove the `query_auth` federation endpoint + +This API was added without sufficient thought nor testing. The endpoint isn't +used in any known implementations, and we do not believe it to be necessary +for federation to work. The only known implementation (in Synapse) was not fully +fleshed out and is broken. + +For background, the idea behind this endpoint was that two homeservers would be +able to share state events with the hope of filling in missing state from one +of homeservers allowing state resolution to complete. This was to protect +against a joining server not providing the full (or providing stale) state. + +In addition to the ideas above not coming to fruition, it is unclear whether the +current design of this endpoint would be sufficient. If this state negotiation +feature is needed in the future it should be redesigned from scratch via the MSC +proposal process. + +## Proposal + +Remove the following endpoint: + +* [POST `/_matrix/federation/v1/query_auth/{roomId}/{eventId}`](https://matrix.org/docs/spec/server_server/r0.1.3#post-matrix-federation-v1-query-auth-roomid-eventid) + +## Potential issues + +Removing this endpoint impacts backwards compatibility, in practice removing +this endpoint should have minimal impact as it was an unused error path in +Synapse. The federation client code to call this endpoint was removed in Synapse +v1.5.0rc1. + +There is no evidence of other homeserver implementations having implemented this +endpoint. + +### History + +This endpoint (and the federation client code) to call it was initially +added in Synapse v0.7.0 (see [#43](https://github.com/matrix-org/synapse/pull/43)). +The federation client code was heavily modified for v1.0.0rc1 (see +[#5227](https://github.com/matrix-org/synapse/pull/5227/)), + +The federation client code to call this endpoint was removed in v1.5.0rc1 of +Synapse (see [#6214](https://github.com/matrix-org/synapse/pull/6214). After +that point this endpoint is not called). + +During removal it was noted that the code to call this endpoint was already +unreachable. It seems that this code was never reachable and was meant for an +error situation which was never built out (see `git log -S NOT_ANCESTOR`, the +error condition is never assigned). + +## Alternatives + +The endpoint could be deprecated and removed in a future version of the specification. + +## Security considerations + +None. diff --git a/proposals/2454-ui-interactive-auth-for-sso.md b/proposals/2454-ui-interactive-auth-for-sso.md new file mode 100644 index 00000000..18112c5f --- /dev/null +++ b/proposals/2454-ui-interactive-auth-for-sso.md @@ -0,0 +1,230 @@ +# User-Interactive Authentication for SSO-backed homeserver + +Certain endpoints, such as `DELETE /_matrix/client/r0/devices/{deviceId}` and +`POST /_matrix/client/r0/account/3pid/add`, require the user to reconfirm their +identity, as a guard against a leaked access token being used to take over an +entire account. + +On a normal homeserver, this is done by prompting the user to enter their +password. However, on a homeserver where users authenticate via a single-sign-on +system, the user doesn't have a password registered with the homeserver. Instead +we need to delegate that check to the SSO system. + +At the protocol level, this means adding support for SSO to the +[user-interactive authentication API](https://matrix.org/docs/spec/client_server/r0.6.0#user-interactive-authentication-api). + +In theory, once SSO is added as a possible flow for authentication, any clients +that already implement the [fallback process for unknown authentication types](https://matrix.org/docs/spec/client_server/r0.6.0#fallback) +will work fine without modification. It is unknown whether this is widely +supported among clients. + +## Proposal + +An [additional authentication type](https://matrix.org/docs/spec/client_server/r0.6.0#authentication-types) +of `m.login.sso` is added to the user-interactive authentication specification. + +There are no additional parameters as part of this authentication type. As per +the user-interactive authentication specification, the only parameter included in +the `auth` dictionary should be the session ID from the homeserver, e.g.: + +```json +{ + "auth": { + "session": "" + } +} +``` + +### Detailed fallback authentication flow: + +The following is a re-iteration of the [fallback authentication flow](https://matrix.org/docs/spec/client_server/r0.6.0#fallback), +but with details filled in for the proposed new authentication type. + +When choosing this authentication flow, the following should occur: + +1. If the client wants to complete authentication using SSO, it opens a browser + window for `/_matrix/client/r0/auth/m.login.sso/fallback/web?session=<...>` + with session set to the UI-Auth session id (from the "auth" dict). + + The homeserver returns a page which asks for the user's confirmation before + proceeding. See the security considerations section below for why this is + necessary. For example, the page could say words to the effect of: + + > A client is trying to remove a device/add an email address/take over your + > account. To confirm this action, **re-authenticate with single sign-on**. + > If you did not expect this, your account may be compromised! +2. The link, once the user clicks on it, goes to the SSO provider's page. +3. The SSO provider validates the user, and redirects the browser back to the + homeserver. +4. The homeserver validates the response from the SSO provider, updates the + user-interactive auth session to show that the SSO has completed, and + [serves the fallback auth completion page as specced](https://matrix.org/docs/spec/client_server/r0.6.0#fallback). +5. The client resubmits its original request, with its original session id, + which now should complete. + +Note that the post-SSO URL on the homeserver is left up to the homeserver +implementation rather than forming part of the specification, choices might be +limited by the chosen SSO implementation, for example: + +* SAML2 servers typically only support one URL per service provider, so in + practice it will need to be the same as that already used for the login flow + (for synapse, it's `/_matrix/saml2/authn_response`) - and the server needs to + be able to figure out if it's doing SSO for a login attempt or an SSO + attempt. +* CAS doesn't have the same restriction. + +### Example flow: + +A more complete example is provided below in which a user attempts to delete +a device and is pushed into the user interactive authentication process with +SSO being the only possible flow. + +0. Client submits the request, which the server says requires SSO: + + ``` + POST /_matrix/client/r0/delete_devices HTTP/1.1 + Content-Type: application/json + Authorization: Bearer xyzzy + + { + "devices": ["FSVVTZRRAA"] + } + + HTTP/1.1 401 Unauthorized + Content-Type: application/json + + { + "flows": [ + { + "stages": [ + "m.login.sso" + ] + } + ], + "params": {}, + "session": "dTKfsLHSAJeAhqfxUsvrIVJd" + } + ``` + +1. Client opens a browser window for the fallback endpoint: + + ``` + GET /_matrix/client/r0/auth/m.login.sso/fallback/web + ?session=dTKfsLHSAJeAhqfxUsvrIVJd HTTP/1.1 + + HTTP/1.1 200 OK + + + A client is trying to remove a device from your account. To confirm this + action, re-authenticate with single sign-on. + If you did not expect this, your account may be compromised! + + ``` + +2. The user clicks the confirmation link which goes to the SSO provider's site: + + ``` + GET https://sso_provider/validate?SAMLRequest= HTTP/1.1 + + + ``` + +3. The SSO provider validates the user and ends up redirecting the browser back + to the homeserver. The example below shows a 302 for simplicity, this might + vary based on SSO implementation. + + ``` + HTTP/1.1 302 Moved + Location: https://homeserver/_matrix/saml2/authn_response? + SAMLResponse= + ``` + +4. The browser sends the SSO response to the homeserver, which validates it and + shows the fallback auth completion page: + + ``` + GET /_matrix/saml2/authn_response?SAMLResponse= + + + HTTP/1.1 200 OK + + + +

Thank you.

+

You may now close this window and return to the application.

+ ``` + +5. The client closes the browser popup if it is still open, and resubmits its + original request, which now succeeds: + + ``` + POST /_matrix/client/r0/delete_devices HTTP/1.1 + Content-Type: application/json + Authorization: Bearer xyzzy + + { + "auth": { + "session": "dTKfsLHSAJeAhqfxUsvrIVJd" + } + } + + HTTP/1.1 200 OK + Content-Type: application/json + + {} + ``` + +## Alternatives + +An alternative client flow where the fallback auth ends up redirecting to a +given URI, instead of doing JavaScript `postMessage` foo could be considered. +This is probably an orthogonal change to the fallback auth though. + +## Security considerations + +### Why we need user to confirm before the SSO flow + +Recall that the thing we are trying to guard against here is a single leaked +access-token being used to take over an entire account. So let's assume the +attacker has got hold of an access token for your account. What happens if the +confirmation step is skipped? + +The attacker, who has your access token, starts a UI Authentication session to +add their email address to your account. + +They then sends you a link "hey, check out this cool video!"; the link leads (via +an innocent-looking URL shortener or some other phishing technique) to +`/_matrix/client/r0/auth/m.login.sso/fallback/web?session=<...>`, with the ID of +the session that he just created. + +Since there is no confirmation step, the server redirects directly to the SSO +provider. + +It's common for SSO providers to redirect straight back to the app if you've +recently authenticated with them; even in the best case, the SSO provider shows +an innocent message along the lines of "Confirm that you want to sign in to +\". + +After redirecting back to the homeserver, the SSO is completed and the +attacker's session is validated. They are now able to make their malicious +change to your account. + +This problem can be mitigated by clearly telling the user what is about to happen. + +### Reusing User Interactive Authentication sessions + +The security of this relies on User Interactive Authentication sessions only +being used for the same request as they were initiated for. This security is not +only a concern for the proposed SSO authentication type. It is not believed +that this is currently enforced in implementations. + +## Unstable prefix + +A vendor prefix of `org.matrix.login.sso` is proposed (instead of `m.login.sso`) +until this is part of the specification. diff --git a/proposals/2457-password-modification-invalidating-devices.md b/proposals/2457-password-modification-invalidating-devices.md new file mode 100644 index 00000000..ccde2ac6 --- /dev/null +++ b/proposals/2457-password-modification-invalidating-devices.md @@ -0,0 +1,56 @@ +# Invalidating devices during password modification + +There are multiple use cases for why a user might want to modify their password: + +* Adopting a password manager (to use a unique password or more secure password). +* Password rotation. +* Re-secure a compromised account. +* ... probably tons of others ... + +These can be summarized into two groups: + +1. "My account has been compromised and I need to re-secure it." +2. "I just want to change my password." + +The [current Matrix specification](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-account-password) +does not provide a way to differentiate between these use cases. It currently +specifies behavior that fits well into the first use-case above: that the +sessions except the current session should be revoked. + +It is reasonable for a client to want to specify this behavior to offer two +different workflows: + +1. Modify a password and log all other devices out (for use when an account has + been compromised). +2. Modify a password and do not touch any session data (for use in a + non-malicious situations). + +Alternately a client may default to whichever workflow is best for their users. + +## Proposal + +An optional field is added to the JSON body of the [password reset endpoint](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-account-password) +called `logout_devices`. This is a boolean flag (defaulting to `true`) that +signals to whether other devices and sessions should be invalidated after +modifying the password. + +## Potential issues + +The specification states: + +> The homeserver SHOULD NOT revoke the access token provided in the request, +> however all other access tokens for the user should be revoked if the request +> succeeds. + +Defaulting `logout_devices` to `true` should be backwards compatible. + +## Alternatives + +A new endpoint could be provided in a future version of the specification that +supports an additional field (as described above). + +## Security considerations + +By defaulting to invalidating devices and sessions the security considerations +of this endpoint should remain intact. A client will need to be modified to +choose to keep other devices active. diff --git a/scripts/proposals.py b/scripts/proposals.py index 27cc6cfb..faa10a83 100755 --- a/scripts/proposals.py +++ b/scripts/proposals.py @@ -38,7 +38,10 @@ def getpage(url): pagecount = 1 for link in resp.links.values(): if link['rel'] == 'last': - pagecount = int(re.search('page=(.+?)', link['url']).group(1)) + # we extract the pagecount from the `page` param of the last url + # in the response, eg + # 'https://api.github.com/repositories/24998719/issues?state=all&labels=proposal&page=10' + pagecount = int(re.search('page=(\d+)', link['url']).group(1)) val = resp.json() if not isinstance(val, list): diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index eb32d3b4..fce879a2 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -643,6 +643,7 @@ This specification defines the following auth types: - ``m.login.password`` - ``m.login.recaptcha`` - ``m.login.oauth2`` + - ``m.login.sso`` - ``m.login.email.identity`` - ``m.login.msisdn`` - ``m.login.token`` @@ -782,6 +783,38 @@ the auth code. Homeservers can choose any path for the ``redirect URI``. Once the OAuth flow has completed, the client retries the request with the session only, as above. +Single Sign-On +<<<<<<<<<<<<<< +:Type: + ``m.login.sso`` +:Description: + Authentication is supported by authorising with an external single sign-on + provider. + +A client wanting to complete authentication using SSO should use the +`Fallback`_ authentication flow by opening a browser window for +``/_matrix/client/r0/auth/m.login.sso/fallback/web?session=<...>`` with the +session parameter set to the session ID provided by the server. + +The homeserver should return a page which asks for the user's confirmation +before proceeding. For example, the page could say words to the effect of: + + A client is trying to remove a device/add an email address/take over your + account. To confirm this action, re-authenticate with single sign-on. If you + did not expect this, your account may be compromised! + +Once the user has confirmed they should be redirected to the single sign-on +provider's login page. Once the provider has validated the user, the browser is +redirected back to the homeserver. + +The homeserver then validates the response from the single sign-on provider and +updates the user-interactive authentication session to mark the single sign-on +stage has been completed. The browser is shown the fallback authentication +completion page. + +Once the flow has completed, the client retries the request with the session +only, as above. + Email-based (identity / homeserver) <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< :Type: diff --git a/specification/feature_profiles.rst b/specification/feature_profiles.rst index bb638380..8a3caf87 100644 --- a/specification/feature_profiles.rst +++ b/specification/feature_profiles.rst @@ -61,6 +61,7 @@ Summary `Stickers`_ Optional Optional Optional Optional Optional `Server ACLs`_ Optional Optional Optional Optional Optional `Server Notices`_ Optional Optional Optional Optional Optional + `Moderation policies`_ Optional Optional Optional Optional Optional ===================================== ========== ========== ========== ========== ========== *Please see each module for more details on what clients need to implement.* @@ -94,6 +95,7 @@ Summary .. _Stickers: `module:stickers`_ .. _Server ACLs: `module:server-acls`_ .. Server Notices already has a link elsewhere. +.. _Moderation Policies: `module:moderation-policies`_ Clients ------- diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index af7b2c59..0223d9f5 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -277,7 +277,7 @@ Parameter Type Description ========= ================ ===================================================== url string **Required.** The URL to the file. key JWK **Required.** A `JSON Web Key`_ object. -iv string **Required.** The Initialisation Vector used by +iv string **Required.** The 128-bit unique counter block used by AES-CTR, encoded as unpadded base64. hashes {string: string} **Required.** A map from an algorithm name to a hash of the ciphertext, encoded as unpadded base64. Clients @@ -505,7 +505,7 @@ framework outlined above. SAS verification is intended to be a highly interactiv process for users, and as such exposes verfiication methods which are easier for users to use. -The verification process is heavily inspired by Phil Zimmerman's ZRTP key agreement +The verification process is heavily inspired by Phil Zimmermann's ZRTP key agreement handshake. A key part of key agreement in ZRTP is the hash commitment: the party that begins the Diffie-Hellman key sharing sends a hash of their part of the Diffie-Hellman exchange, and does not send their part of the Diffie-Hellman exchange until they have @@ -565,9 +565,9 @@ The process between Alice and Bob verifying each other would be: they match or not. #. Assuming they match, Alice and Bob's devices calculate the HMAC of their own device keys and a comma-separated sorted list of of the key IDs that they wish the other user - to verify, using SHA-256 as the hash function. HMAC is defined in [RFC 2104](https://tools.ietf.org/html/rfc2104). + to verify, using SHA-256 as the hash function. HMAC is defined in `RFC 2104 `_. The key for the HMAC is different for each item and is calculated by generating - 32 bytes (256 bits) using `the key verification HKDF <#SAS-HKDF>`_. + 32 bytes (256 bits) using `the key verification HKDF <#sas-hkdf>`_. #. Alice's device sends Bob's device a ``m.key.verification.mac`` message containing the MAC of Alice's device keys and the MAC of her key IDs to be verified. Bob's device does the same for Bob's device keys and key IDs concurrently with Alice. @@ -653,14 +653,14 @@ are used in addition to those already specified: {{m_key_verification_mac_event}} -.. _`SAS-HKDF`: +.. _sas-hkdf: HKDF calculation <<<<<<<<<<<<<<<< -In all of the SAS methods, HKDF is as defined in [RFC 5869](https://tools.ietf.org/html/rfc5869) +In all of the SAS methods, HKDF is as defined in `RFC 5869 `_ and uses the previously agreed-upon hash function for the hash function. The shared -secret is supplied as the input keying material. No salt is used, and the input +secret is supplied as the input keying material. No salt is used, and the info parameter is the concatenation of: * The string ``MATRIX_KEY_VERIFICATION_SAS``. @@ -677,7 +677,7 @@ parameter is the concatenation of: For verification of each party's device keys, HKDF is as defined in RFC 5869 and uses SHA-256 as the hash function. The shared secret is supplied as the input keying -material. No salt is used, and in the input parameter is the concatenation of: +material. No salt is used, and in the info parameter is the concatenation of: * The string ``MATRIX_KEY_VERIFICATION_MAC``. * The Matrix ID of the user whose key is being MAC-ed. @@ -691,7 +691,7 @@ material. No salt is used, and in the input parameter is the concatenation of: SAS method: ``decimal`` <<<<<<<<<<<<<<<<<<<<<<< -Generate 5 bytes using `HKDF <#SAS-HKDF>`_ then take sequences of 13 bits to +Generate 5 bytes using `HKDF <#sas-hkdf>`_ then take sequences of 13 bits to convert to decimal numbers (resulting in 3 numbers between 0 and 8191 inclusive each). Add 1000 to each calculated number. @@ -708,7 +708,7 @@ such as dashes, or with the numbers on individual lines. SAS method: ``emoji`` <<<<<<<<<<<<<<<<<<<<< -Generate 6 bytes using `HKDF <#SAS-HKDF>`_ then split the first 42 bits into +Generate 6 bytes using `HKDF <#sas-hkdf>`_ then split the first 42 bits into 7 groups of 6 bits, similar to how one would base64 encode something. Convert each group of 6 bits to a number and use the following table to get the corresponding emoji: diff --git a/specification/modules/moderation_policies.rst b/specification/modules/moderation_policies.rst new file mode 100644 index 00000000..2e85fb07 --- /dev/null +++ b/specification/modules/moderation_policies.rst @@ -0,0 +1,128 @@ +.. Copyright 2020 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. + +Moderation policy lists +======================= + +.. _module:moderation-policies: + +With Matrix being an open network where anyone can participate, a very wide +range of content exists and it is important that users are empowered to select +which content they wish to see, and which content they wish to block. By +extension, room moderators and server admins should also be able to select +which content they do not wish to host in their rooms and servers. + +The protocol's position on this is one of neutrality: it should not be deciding +what content is undesirable for any particular entity and should instead be +empowering those entities to make their own decisions. As such, a generic +framework for communicating "moderation policy lists" or "moderation policy rooms" +is described. Note that this module only describes the data structures and not +how they should be interpreting: the entity making the decisions on filtering +is best positioned to interpret the rules how it sees fit. + +Moderation policy lists are stored as room state events. There are no restrictions +on how the rooms can be configured (they could be public, private, encrypted, etc). + +There are currently 3 kinds of entities which can be affected by rules: ``user``, +``server``, and ``room``. All 3 are described with ``m.policy.rule.`` state +events. The ``state_key`` for a policy rule is an arbitrary string decided by the +sender of the rule. + +Rules contain recommendations and reasons for the rule existing. The ``reason`` +is a human-readable string which describes the ``recommendation``. Currently only +one recommendation, ``m.ban``, is specified. + +``m.ban`` recommendation +------------------------ + +When this recommendation is used, the entities affected by the rule should be +banned from participation where possible. The enforcement of this is deliberately +left as an implementation detail to avoid the protocol imposing its opinion on how +the policy list is to be interpreted. However, a suggestion for a simple implementation +is as follows: + +* Is a ``user`` rule... + + * Applied to a user: The user should be added to the subscriber's ignore list. + * Applied to a room: The user should be banned from the room (either on sight or immediately). + * Applied to a server: The user should not be allowed to send invites to users on the server. + +* Is a ``room`` rule... + + * Applied to a user: The user should leave the room and not join it + (`MSC2270 `_-style ignore). + * Applied to a room: No-op because a room cannot ban itself. + * Applied to a server: The server should prevent users from joining the room and from receiving + invites to it. + +* Is a ``server`` rule... + + * Applied to a user: The user should not receive events or invites from the server. + * Applied to a room: The server is added as a denied server in the ACLs. + * Applied to a server: The subscriber should avoid federating with the server as much as + possible by blocking invites from the server and not sending traffic unless strictly + required (no outbound invites). + +Subscribing to policy lists +--------------------------- + +This is deliberatly left as an implementation detail. For implementations using the +Client-Server API, this could be as easy as joining or peeking the room. Joining or peeking +is not required, however: an implementation could poll for updates or use a different +technique for receiving updates to the policy's rules. + +Sharing +------- + +In addition to sharing a direct reference to the room which contains the policy's rules, +plain http or https URLs can be used to share links to the list. When the URL is approached +with a ``Accept: application/json`` header or has ``.json`` appended to the end of the URL, it +should return a JSON object containing a ``room_uri`` property which references the room. +Currently this would be a ``matrix.to`` URI, however in future it could be a Matrix-schemed +URI instead. When not approached with the intent of JSON, the service could return a +user-friendly page describing what is included in the ban list. + +Events +------ + +The ``entity`` described by the state events can contain ``*`` and ``?`` to match zero or more +and one or more characters respectively. Note that rules against rooms can describe a room ID +or room alias - the subscriber is responsible for resolving the alias to a room ID if desired. + +{{m_policy_rule_user_event}} + +{{m_policy_rule_room_event}} + +{{m_policy_rule_server_event}} + +Client behaviour +---------------- +As described above, the client behaviour is deliberatly left undefined. + +Server behaviour +---------------- +Servers have no additional requirements placed on them by this module. + +Security considerations +----------------------- +This module could be used to build a system of shared blacklists, which may create +a divide within established communities if not carefully deployed. This may well not +be a suitable solution for all communities. + +Depending on how implementations handle subscriptions, user IDs may be linked to +policy lists and therefore expose the views of that user. For example, a client implementation +which joins the user to the policy room would expose the user's ID to observers of the +policy room. In future, `MSC1228 `_ +and `MSC1777 `_ (or similar) could +help solve this concern. diff --git a/specification/modules/push.rst b/specification/modules/push.rst index c9489987..ebf1aef2 100644 --- a/specification/modules/push.rst +++ b/specification/modules/push.rst @@ -473,6 +473,9 @@ Definition (as a ``content`` rule): { "set_tweak": "sound", "value": "default" + }, + { + "set_tweak": "highlight" } ] } diff --git a/specification/proposals_intro.rst b/specification/proposals_intro.rst index 5ee82dc3..e6cebcf4 100644 --- a/specification/proposals_intro.rst +++ b/specification/proposals_intro.rst @@ -342,6 +342,36 @@ Closed proposal-closed A proposal which Obsolete obsolete A proposal which has been made obsolete by another proposal or decision elsewhere. =============================== ============================= ==================================== +Categories +---------- + +We use category labels on MSCs to place them into a track of work. The Spec Core Team +decides which of the tracks they are focusing on for the next while and generally makes +an effort to pull MSCs out of that category when possible. + +The current categories are: + +============ ================= ====================================== +Name Github Label Description +============ ================= ====================================== +Core kind:core Important for the protocol's success. +Feature kind:feature Nice to have additions to the spec. +Maintenance kind:maintenance Fixes or clarifies existing spec. +============ ================= ====================================== + +Some examples of core MSCs would be aggregations, cross-signing, and groups/communities. +These are the sorts of things that if not implemented could cause the protocol to +fail or become second-class. Features would be areas like enhanced media APIs, +new transports, and bookmarks in comparison. Finally, maintenance MSCs would include +improving error codes, clarifying what is required of an API, and adding properties +to an API which makes it easier to use. + +The Spec Core Team assigns a category to each MSC based on the descriptions above. +This can mean that new MSCs get categorized into an area the team isn't focused on, +though that can always change as priorities evolve. We still encourage that MSCs be +opened, even if not the focus for the time being, as they can still make progress and +even be merged without the Spec Core Team focusing on them specifically. + Implementing a proposal ----------------------- diff --git a/specification/rooms/v2.rst b/specification/rooms/v2.rst index 4e8365bf..afc114f8 100644 --- a/specification/rooms/v2.rst +++ b/specification/rooms/v2.rst @@ -148,8 +148,8 @@ The *resolution* of a set of states is obtained as follows: 1. Take all *power events* and any events in their auth chains, recursively, that appear in the *full conflicted set* and order them by the *reverse topological power ordering*. -2. Apply the *iterative auth checks algorithm* on the *unconflicted state map* - and the list of events from the previous step to get a partially resolved +2. Apply the *iterative auth checks algorithm*, starting from the *unconflicted state map*, + to the list of events from the previous step to get a partially resolved state. 3. Take all remaining events that weren't picked in step 1 and order them by the mainline ordering based on the power level in the partially resolved diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index a3a57dbf..655a8cfc 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -316,8 +316,8 @@ Example python code: "destination": destination_name, } - if content_json is not None: - request["content"] = content + if content is not None: + request_json["content"] = content signed_json = sign_json(request_json, origin_name, origin_signing_key) @@ -1077,7 +1077,6 @@ The following endpoint prefixes MUST be protected: * ``/_matrix/federation/v1/state_ids`` * ``/_matrix/federation/v1/backfill`` * ``/_matrix/federation/v1/event_auth`` -* ``/_matrix/federation/v1/query_auth`` * ``/_matrix/federation/v1/get_missing_events`` diff --git a/specification/targets.yaml b/specification/targets.yaml index 2cd911ba..4e0b068d 100644 --- a/specification/targets.yaml +++ b/specification/targets.yaml @@ -91,6 +91,7 @@ groups: # reusable blobs of files when prefixed with 'group:' - modules/mentions.rst - modules/room_upgrades.rst - modules/server_notices.rst + - modules/moderation_policies.rst title_styles: ["=", "-", "~", "+", "^", "`", "@", ":"]