From 3f5f44f3ae8109303353ee192170ff37e8653a07 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Wed, 26 Jul 2023 10:41:32 -0400 Subject: [PATCH] Add information on room version 11. --- content/rooms/_index.md | 14 +- content/rooms/fragments/v11-redactions.md | 38 +++ content/rooms/v11.md | 271 ++++++++++++++++++++++ 3 files changed, 316 insertions(+), 7 deletions(-) create mode 100644 content/rooms/fragments/v11-redactions.md create mode 100644 content/rooms/v11.md diff --git a/content/rooms/_index.md b/content/rooms/_index.md index e75fbb13..9334c3a1 100644 --- a/content/rooms/_index.md +++ b/content/rooms/_index.md @@ -36,11 +36,11 @@ Alternatively, consider flipping the column/row organization to be features up top and versions on the left. --> -| Feature \ Version | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -|-------------------|---|---|---|---|---|---|---|---|---|----| -| **Knocking** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | -| **Restricted join rules** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ | ✔ | ✔ | -| **`knock_restricted` join rule** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ | +| Feature \ Version | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | +|-------------------|---|---|---|---|---|---|---|---|---|----|----| +| **Knocking** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | +| **Restricted join rules** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | +| **`knock_restricted` join rule** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ | ✔ | ## Complete list of room versions @@ -57,8 +57,7 @@ the default room version when creating new rooms. The available room versions are: -- [Version 1](/rooms/v1) - **Stable**. The current version of most - rooms. +- [Version 1](/rooms/v1) - **Stable**. The initial room version. - [Version 2](/rooms/v2) - **Stable**. Implements State Resolution Version 2. - [Version 3](/rooms/v3) - **Stable**. Introduces events whose IDs @@ -76,6 +75,7 @@ The available room versions are: redacting some membership events. - [Version 10](/rooms/v10) - **Stable**. Enforces integer-only power levels and adds `knock_restricted` join rule. +- [Version 11](/rooms/v11) - **Stable**. Clarifies the redaction algorithm. ## Room version grammar diff --git a/content/rooms/fragments/v11-redactions.md b/content/rooms/fragments/v11-redactions.md new file mode 100644 index 00000000..9cda80a2 --- /dev/null +++ b/content/rooms/fragments/v11-redactions.md @@ -0,0 +1,38 @@ +--- +--- + +{{% added-in this=true %}} The top-level `origin`, `membership`, and `prev_state` properties +are no longer protected from redaction. The `m.room.create` event no longer keeps the `creator` +property and now keeps the entire `content` property. The `m.room.redaction` event keeps the +`redacts` property under `content`. The `m.room.power_levels` event keeps the `invite` property +under `content`. + +The full redaction algorithm follows. + +Upon receipt of a redaction event, the server must strip off any keys +not in the following list: + +- `event_id` +- `type` +- `room_id` +- `sender` +- `state_key` +- `content` +- `hashes` +- `signatures` +- `depth` +- `prev_events` +- `auth_events` +- `origin_server_ts` + +The content object must also be stripped of all keys, unless it is one +of the following event types: + +- `m.room.member` allows keys `membership`, `join_authorised_via_users_server`. + Additionally, it allows the `signed` key of the `third_party_invite` key. +- `m.room.create` allows all keys. +- `m.room.join_rules` allows keys `join_rule`, `allow`. +- `m.room.power_levels` allows keys `ban`, `events`, `events_default`, + `invite`, `kick`, `redact`, `state_default`, `users`, `users_default`. +- `m.room.history_visibility` allows key `history_visibility`. +- `m.room.redaction` allows key `redacts`. \ No newline at end of file diff --git a/content/rooms/v11.md b/content/rooms/v11.md new file mode 100644 index 00000000..a1d3aa26 --- /dev/null +++ b/content/rooms/v11.md @@ -0,0 +1,271 @@ +--- +title: Room Version 11 +type: docs +weight: 100 +--- + +This room version builds on [version 10](/rooms/v10) while clarifying redaction +rules. + +## Client considerations + +Clients should no longer depend on the `creator` property of `m.room.create` events. + +Clients should note that the format of `m.room.redaction` events has been modified +and look for the `redacts` key under `content` instead of a top-level event property. + +Clients should note that the `third_party_invite` key of `m.room.member` events +is no longer redacted, *but* will only contain the `signed` key after redaction. + +Clients which implement the redaction algorithm locally should refer to the +[redactions](#redactions) section below for a full overview. + +## Server implementation components + +{{% boxes/warning %}} +The information contained in this section is strictly for server +implementors. Applications which use the Client-Server API are generally +unaffected by the intricacies contained here. The section above +regarding client considerations is the resource that Client-Server API +use cases should reference. +{{% /boxes/warning %}} + +This room version updates the redaction algorithm and modifies how servers should +create `m.room.create` and `m.room.redaction` events. + +Room version 11 is based upon room version 10 with the following considerations. + +### Event format + +The event format is unchanged by this room version. See [below](#event-format-1) +for details on the current event format. + +#### Remove the `creator` property of `m.room.create` events + +The `m.room.create` event no longer has a `creator` property, which previously +was always equivalent to the `sender` of the event. + +#### Moving the `redacts` property of `m.room.redaction` events to a `content` property + +The `redacts` property of `m.room.redaction` events is moved from a top-level +event property to a property under the event `content`. + +For backwards-compatibility with older clients, servers should add a `redacts` property +to the top level of `m.room.redaction` events in when serving such events over the +Client-Server API. + +For improved compatibility with newer clients, servers should add a `redacts` property +to the `content` of `m.room.redaction` events in *older* room versions when serving +such events over the Client-Server API. + +### Authorization rules + +Events must be signed by the server denoted by the `sender` property. + +`m.room.redaction` events are not explicitly part of the auth rules. +They are still subject to the minimum power level rules, but should always +fall into "10. Otherwise, allow". Instead of being authorized at the time +of receipt, they are authorized at a later stage: see the +[Redactions](#redactions) section below for more information. + +The types of state events that affect authorization are: + +- [`m.room.create`](/client-server-api#mroomcreate) +- [`m.room.member`](/client-server-api#mroommember) +- [`m.room.join_rules`](/client-server-api#mroomjoin_rules) +- [`m.room.power_levels`](/client-server-api#mroompower_levels) +- [`m.room.third_party_invite`](/client-server-api#mroomthird_party_invite) + +{{% boxes/note %}} +Power levels are inferred from defaults when not explicitly supplied. +For example, mentions of the `sender`'s power level can also refer to +the default power level for users in the room. +{{% /boxes/note %}} + +The rules are as follows: + +1. {{< changed-in this="true" >}} + If type is `m.room.create`: + 1. If it has any `prev_events`, reject. + 2. If the domain of the `room_id` does not match the domain of the + `sender`, reject. + 3. If `content.room_version` is present and is not a recognised + version, reject. + 4. Otherwise, allow. +2. Considering the event's `auth_events`: + 1. If there are duplicate entries for a given `type` and `state_key` pair, + reject. + 2. If there are entries whose `type` and `state_key` don't match those + specified by the [auth events + selection](/server-server-api#auth-events-selection) + algorithm described in the server specification, reject. + 3. If there are entries which were themselves rejected under the [checks + performed on receipt of a + PDU](/server-server-api/#checks-performed-on-receipt-of-a-pdu), reject. + 4. If there is no `m.room.create` event among the entries, reject. +3. If the `content` of the `m.room.create` event in the room state has the + property `m.federate` set to `false`, and the `sender` domain of the event + does not match the `sender` domain of the create event, reject. +4. If type is `m.room.member`: + 1. If there is no `state_key` property, or no `membership` property in + `content`, reject. + 2. If `content` has a `join_authorised_via_users_server` + key: + 1. If the event is not validly signed by the homeserver of the user ID denoted + by the key, reject. + 3. If `membership` is `join`: + 1. {{< changed-in this="true" >}} + If the only previous event is an `m.room.create` and the + `state_key` is the sender, allow. + 2. If the `sender` does not match `state_key`, reject. + 3. If the `sender` is banned, reject. + 4. If the `join_rule` is `invite` or `knock` then allow if + membership state is `invite` or `join`. + 5. If the `join_rule` is `restricted` or `knock_restricted`: + 1. If membership state is `join` or `invite`, allow. + 2. If the `join_authorised_via_users_server` key in `content` + is not a user with sufficient permission to invite other + users, reject. + 3. Otherwise, allow. + 6. If the `join_rule` is `public`, allow. + 7. Otherwise, reject. + 4. If `membership` is `invite`: + 1. If `content` has a `third_party_invite` property: + 1. If *target user* is banned, reject. + 2. If `content.third_party_invite` does not have a `signed` + property, reject. + 3. If `signed` does not have `mxid` and `token` properties, + reject. + 4. If `mxid` does not match `state_key`, reject. + 5. If there is no `m.room.third_party_invite` event in the + current room state with `state_key` matching `token`, + reject. + 6. If `sender` does not match `sender` of the + `m.room.third_party_invite`, reject. + 7. If any signature in `signed` matches any public key in + the `m.room.third_party_invite` event, allow. The public + keys are in `content` of `m.room.third_party_invite` as: + 1. A single public key in the `public_key` property. + 2. A list of public keys in the `public_keys` property. + 8. Otherwise, reject. + 2. If the `sender`'s current membership state is not `join`, + reject. + 3. If *target user*'s current membership state is `join` or + `ban`, reject. + 4. If the `sender`'s power level is greater than or equal to + the *invite level*, allow. + 5. Otherwise, reject. + 5. If `membership` is `leave`: + 1. If the `sender` matches `state_key`, allow if and only if + that user's current membership state is `invite`, `join`, + or `knock`. + 2. If the `sender`'s current membership state is not `join`, + reject. + 3. If the *target user*'s current membership state is `ban`, + and the `sender`'s power level is less than the *ban level*, + reject. + 4. If the `sender`'s power level is greater than or equal to + the *kick level*, and the *target user*'s power level is + less than the `sender`'s power level, allow. + 5. Otherwise, reject. + 6. If `membership` is `ban`: + 1. If the `sender`'s current membership state is not `join`, + reject. + 2. If the `sender`'s power level is greater than or equal to + the *ban level*, and the *target user*'s power level is less + than the `sender`'s power level, allow. + 3. Otherwise, reject. + 7. If `membership` is `knock`: + 1. If the `join_rule` is anything other than `knock` or + `knock_restricted`, reject. + 2. If `sender` does not match `state_key`, reject. + 3. If the `sender`'s current membership is not `ban` or `join`, allow. + 4. Otherwise, reject. + 8. Otherwise, the membership is unknown. Reject. +5. If the `sender`'s current membership state is not `join`, reject. +6. If type is `m.room.third_party_invite`: + 1. Allow if and only if `sender`'s current power level is greater + than or equal to the *invite level*. +7. If the event type's *required power level* is greater than the + `sender`'s power level, reject. +8. If the event has a `state_key` that starts with an `@` and does not + match the `sender`, reject. +9. If type is `m.room.power_levels`: + 1. If any of the properties `users_default`, `events_default`, `state_default`, + `ban`, `redact`, `kick`, or `invite` in `content` are present and + not an integer, reject. + 2. If either of the properties `events` or `notifications` in `content` + are present and not an object with values that are integers, + reject. + 3. If the `users` property in `content` is not an obiect with keys that + are valid user IDs with values that are integers, reject. + 4. If there is no previous `m.room.power_levels` event in the room, + allow. + 5. For the properties `users_default`, `events_default`, `state_default`, + `ban`, `redact`, `kick`, `invite` check if they were added, + changed or removed. For each found alteration: + 1. If the current value is higher than the `sender`'s current + power level, reject. + 2. If the new value is higher than the `sender`'s current power + level, reject. + 6. For each entry being changed in, or removed from, the `events` or + `notifications` properties: + 1. If the current value is greater than the `sender`'s current + power level, reject. + 7. For each entry being added to, or changed in, the `events` or + `notifications` properties: + 1. If the new value is greater than the `sender`'s current power + level, reject. + 8. For each entry being changed in, or removed from, the `users` property, + other than the `sender`'s own entry: + 1. If the current value is greater than or equal to the `sender`'s + current power level, reject. + 9. For each entry being added to, or changed in, the `users` property: + 1. If the new value is greater than the `sender`'s current power + level, reject. + 10. Otherwise, allow. +10. Otherwise, allow. + +{{% boxes/note %}} +Some consequences of these rules: + +- Unless you are a member of the room, the only permitted operations + (apart from the initial create/join) are: joining a public room; + accepting or rejecting an invitation to a room. +- To unban somebody, you must have power level greater than or equal + to both the kick *and* ban levels, *and* greater than the target + user's power level. +{{% /boxes/note %}} + +### Redactions + +{{% rver-fragment name="v11-redactions" %}} + +## Unchanged from v10 + +The following sections have not been modified since v10, but are included for +completeness. + +### Handling redactions + +{{% rver-fragment name="v3-handling-redactions" %}} + +### Event IDs + +{{% rver-fragment name="v4-event-ids" %}} + +### Event format + +{{% rver-fragment name="v4-event-format" %}} + +### State resolution + +{{% rver-fragment name="v2-state-res" %}} + +### Canonical JSON + +{{% rver-fragment name="v6-canonical-json" %}} + +### Signing key validity period + +{{% rver-fragment name="v5-signing-requirements" %}}