Room version 12 (#2193)

* Placeholder

* i++

* Room version 12

Template out a v12 room version

Make v12 default, per MSC4304

Update PDU checks and auth event selection per MSC4291

Describe new room_id format per MSC4291

Move v6 depth definition to a component for easier referencing

Move room_id to a component to prep for v12, per MSC4291

Create and use a new room_id component for v12+ per MSC4291

Reflect auth events selection change onto all room versions per MSC4291

The MSC asks the `description` of `auth_events` to be adjusted, however this feels like a better representation of the change.

Add `room_id` format rules and renumber per MSC4291

Reflect change to rule 1.2 per MSC4291

Insert same room_id check to v1-12 auth rules per MSC4307 and MSC4291

Deprecate `predecessor.event_id` per MSC4291

Insert auth rule to validate `additional_creators` per MSC4289

Insert rule for `users` validation of creators and renumber per MSC4289

Define "room creator(s)" per MSC4289

Spec `additional_creators` on create events per MSC4289

Spec `additional_creators` on `/upgrade` per MSC4289

The MSC doesn't mention how to handle unsupported room versions, but the Synapse implementation used for FCP ignores the field in such room versions. This feels like a good approach, and will need clarifying in the MSC too (if accepted at the spec level).

Add notes to `/upgrade` behaviour per MSC4289 and MSC4291

Describe how additional creators work during room creation per MSC4289

Fix default user power level descriptions per MSC4289

Describe tombstone power level changes per MSC4289

Warn clients about event format changes in v12 per MSC4289 and MSC4291

Flag additional room creators support for client reference per MSC4289

Remove TODO now that it's fully addressed

Copy state res into v12 as-is for modification

Apply Modification 1 to SR2.1 per MSC4297

Apply Modification 2 to SR2.1 per MSC4297

Add summary box to the top of SR2.1 for ease of developer reference

Modification 2 was split into items 2 and 3 for further ease of understanding.

Add all the changelogs

`x` is used until a real PR number can be assigned.

Some changelogs are duplicated to the Client-Server API to increase visibility of the changes to v12.

Review: Minor phrasing adjustments in changelogs

Review: Clarify that v12 isn't quite the default yet in the changelog

Review: Clarify to clients that creators are immutable

Review: Improve 'how to parse a domain' advice for legacy apps

Review: Add a bit more detail as to why a room ID might be required

Apply suggestions from code review

Co-authored-by: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com>

Clarify that clients can override the tombstone default

Mention creatorship UI label by finishing the Permissions section

We probably should have removed the WIP note in v1.0, but alas.

Add changelog for tombstone changes

Use assigned spec PR number in changelogs

(cherry picked from commit ec81eea7e4532fd398b8013071d6981c97117d9e)
pull/2199/head
Travis Ralston 4 months ago committed by GitHub
parent c4bfd2feb8
commit f97d2944ae
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1 @@
Room IDs can now appear without a domain component in [room version 12](/rooms/v12), as per [MSC4291](https://github.com/matrix-org/matrix-spec-proposals/pull/4291).

@ -0,0 +1 @@
When upgrading rooms to [room version 12](/rooms/v12), `additional_creators` may be specified on the [`POST /_matrix/client/v3/rooms/{roomId}/upgrade`](/client-server-api/#post_matrixclientv3roomsroomidupgrade) endpoint, as per [MSC4289](https://github.com/matrix-org/matrix-spec-proposals/pull/4289).

@ -0,0 +1 @@
When creating rooms with [room version 12](/rooms/v12), the `trusted_private_chat` preset should merge the invitees into the supplied `content.additional_creators` in the resulting room, as per [MSC4289](https://github.com/matrix-org/matrix-spec-proposals/pull/4289).

@ -0,0 +1 @@
In [room version 12](/rooms/v12), the power level of room creators is now infinitely high as per [MSC4289](https://github.com/matrix-org/matrix-spec-proposals/pull/4289).

@ -0,0 +1 @@
In [room version 12](/rooms/v12), room IDs no longer have a domain component as per [MSC4291](https://github.com/matrix-org/matrix-spec-proposals/pull/4291).

@ -0,0 +1 @@
When creating rooms with [room version 12](/rooms/v12), the initial power levels will restrict the ability to upgrade rooms by default, as per [MSC4289](https://github.com/matrix-org/matrix-spec-proposals/pull/4289).

@ -0,0 +1 @@
In room versions 1 through 12, an event's `auth_events` have always needed to belong to the same room as per [MSC4307](https://github.com/matrix-org/matrix-spec-proposals/pull/4307).

@ -0,0 +1 @@
Add [room version 12](/rooms/v12) as per [MSC4304](https://github.com/matrix-org/matrix-spec-proposals/pull/4304).

@ -0,0 +1 @@
Room IDs in room version 12 are now the event ID of the create event with the normal room ID sigil (`!`), as per [MSC4291](https://github.com/matrix-org/matrix-spec-proposals/pull/4291).

@ -0,0 +1 @@
Room creators are formalized in room version 12 and have infinitely high power level, as per [MSC4289](https://github.com/matrix-org/matrix-spec-proposals/pull/4289).

@ -0,0 +1 @@
State Resolution is updated in room version 12 to reduce the opportunity for "state resets", as per [MSC4297](https://github.com/matrix-org/matrix-spec-proposals/pull/4297).

@ -0,0 +1 @@
The default room version is now room version 12, though servers SHOULD keep using room version 11 for a little while, as per [MSC4304](https://github.com/matrix-org/matrix-spec-proposals/pull/4304).

@ -657,27 +657,48 @@ provides no way to encode ASCII punctuation).
#### Room IDs
A room has exactly one room ID. A room ID has the format:
{{% changed-in v="1.16" %}} Room IDs can now appear without a domain depending on
the room version.
A room has exactly one room ID. Room IDs take the form:
!opaque_id
However, the precise format depends upon the [room version specification](/rooms):
some room versions included a `domain` component, whereas more recent room versions
omit the domain and use a base64-encoded hash instead.
Room IDs are case-sensitive and not meant to be human-readable. They are intended
to be used as fully opaque strings by clients, even when a `domain` component is
present.
If the room version requires a `domain` component, room IDs take the following
form:
!opaque_id:domain
The `domain` of a room ID is the [server name](#server-name) of the
homeserver which created the room. The domain is used only for
namespacing to avoid the risk of clashes of identifiers between
different homeservers. There is no implication that the room in
question is still available at the corresponding homeserver.
In such a form, the `opaque_id` is a localpart. The localpart MUST only contain
valid non-surrogate Unicode code points, including control characters, except `:`
and `NUL` (U+0000). The localpart SHOULD only consist of alphanumeric characters
(`A-Z`, `a-z`, `0-9`) when generating them. The `domain` is the [server name](#server-name)
of the homeserver which created the room - it is only used to reduce namespace
collisions. There is no implication that the room in question is still available
at the corresponding homeserver. Combined, the localpart, domain, and `!` sigil
MUST NOT exceed 255 bytes.
Room IDs are case-sensitive. They are not meant to be
human-readable. They are intended to be treated as fully opaque strings
by clients.
When a room version requires the `domain`-less format, room IDs are simply the
[event ID](#event-ids) of the `m.room.create` event using `!` as the sigil instead
of `$`. The grammar is otherwise inherited verbatim.
The localpart of a room ID (`opaque_id` above) may contain any valid
non-surrogate Unicode code points, including control characters, except `:` and `NUL`
(U+0000), but it is recommended to only include ASCII letters and
digits (`A-Z`, `a-z`, `0-9`) when generating them.
{{% boxes/note %}}
Applications which previously relied upon the `domain` in a room ID can instead
parse the [user IDs](#user-identifiers) found in the `m.room.create` event's `sender`.
The length of a room ID, including the `!` sigil and the domain, MUST
NOT exceed 255 bytes.
Though the `m.room.create` event's `additional_creators` (in `content`) may be
used when present, applications should take care when parsing or interpreting the
list. The user IDs in `additional_creators` will have correct grammar, but may
not be real users or may not belong to actual Matrix homeservers.
{{% /boxes/note %}}
#### Room Aliases

@ -2506,7 +2506,7 @@ and the client is not permitted to make any changes.
When `enabled` is `true`, clients are permitted to modify profile fields,
subject to the restrictions implied by the OPTIONAL lists `allowed` and
`disallowed`.
`disallowed`.
If `allowed` is present, clients can modify only the fields
listed. They SHOULD assume all other fields to be managed by
@ -2546,7 +2546,7 @@ This capability is now deprecated. Clients SHOULD use the
[`m.profile_fields`](/client-server-api/#mprofile_fields-capability)
capability instead.
For backwards compatibility, servers that forbid setting the
For backwards compatibility, servers that forbid setting the
`displayname` profile field in the `m.profile_fields` capability
MUST still present this capability with `"enabled": false`.
{{% /boxes/note %}}
@ -2581,7 +2581,7 @@ This capability is now deprecated. Clients SHOULD use the
[`m.profile_fields`](/client-server-api/#mprofile_fields-capability)
capability instead.
For backwards compatibility, servers that forbid setting the
For backwards compatibility, servers that forbid setting the
`avatar_url` profile field in the `m.profile_fields` capability
MUST still present this capability with `"enabled": false`.
{{% /boxes/note %}}
@ -3414,27 +3414,49 @@ request.
### Permissions
{{% boxes/note %}}
This section is a work in progress.
{{% /boxes/note %}}
{{% changed-in v="1.16" %}} Updated section to discuss creator power level
in room version 12 and beyond.
Permissions for rooms are done via the concept of power levels - to do
any action in a room a user must have a suitable power level. Power
levels are stored as state events in a given room. The power levels
required for operations and the power levels for users are defined in
`m.room.power_levels`, where both a default and specific users' power
levels can be set. By default all users have a power level of 0, other
than the room creator whose power level defaults to 100. Users can grant
other users increased power levels up to their own power level. For
example, user A with a power level of 50 could increase the power level
of user B to a maximum of level 50. Power levels for users are tracked
per-room even if the user is not present in the room. The keys contained
in `m.room.power_levels` determine the levels required for certain
operations such as kicking, banning and sending state events. See
[m.room.power\_levels](#room-events) for more information.
Clients may wish to assign names to particular power levels. A suggested
mapping is as follows: - 0 User - 50 Moderator - 100 Admin
required for operations and the power levels assigned to specific users
are defined in the `m.room.power_levels` state event. The `m.room.power_levels`
state event additionally defines some defaults, though room creators
are special in that:
* In [room versions](/rooms) 1 through 11, room creators by default
have power level 100 but still can have that level changed by power level
events, by the same rules as other members.
* In [room version 12](/rooms/v12) (and beyond), room creators are
*not* specified in the power levels event and have an infinitely high
power level that is immutable. After room creation, users
cannot be given this same infinitely high power level.
Users can grant other users increased power levels up to their own
power level (or the maximum allowable integer for the room when their
power level is infinitely high). For example, user A with a power level
of 50 could increase the power level of user B to a maximum of level 50.
Power levels for users are tracked per-room even if the user is not
present in the room. The keys contained in `m.room.power_levels` determine
the levels required for certain operations such as kicking, banning, and
sending state events. See [`m.room.power_levels`](#mroompower_levels) for more
information.
Clients may wish to assign names to particular power levels. Most rooms
will use the default power level hierarchy assigned during room creation,
but rooms may still deviate slightly.
A suggested mapping is as follows:
* 0 to `state_default-1` (typically 49): User
* `state_default` to the level required to send `m.room.power_levels` events
minus 1 (typically 99): Moderator
* The level required send `m.room.power_levels` events and above: Administrator
* Creators of the room, in room version 12 and beyond: Creator
Clients may also wish to distinguish "above admin" power levels based on the
level required to send `m.room.tombstone` events.
### Room membership

@ -36,6 +36,17 @@ server:
previous room, no `type` is specified on the new room's create event
either.
{{% boxes/note %}}
{{% added-in v="1.16" %}} If both the new and old [room version](/rooms) support
additional creators, the server will not transfer those additional creators automatically.
They must be explicitly set during the `/upgrade` call.
{{% /boxes/note %}}
{{% boxes/note %}}
{{% added-in v="1.16" %}} When upgrading to room version 12 or later, the `predecessor` field MAY NOT contain
an `event_id`.
{{% /boxes/note %}}
3. Replicates transferable state events to the new room. The exact
details for what is transferred is left as an implementation detail,
however the recommended state events to transfer are:

@ -36,11 +36,12 @@ 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 | 11 |
|-------------------|---|---|---|---|---|---|---|---|---|----|----|
| **Knocking** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ |
| **Restricted join rules** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ |
| **`knock_restricted` join rule** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ | ✔ |
| Feature \ Version | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
|-------------------|---|---|---|---|---|---|---|---|---|----|----|----|
| **Knocking** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| **Restricted join rules** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ |
| **`knock_restricted` join rule** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ | ✔ | ✔ |
| **Additional room creators** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ |
## Complete list of room versions
@ -52,9 +53,22 @@ stable and unstable periodically for a variety of reasons, including
discovered security vulnerabilities and age.
Clients should not ask room administrators to upgrade their rooms if the
room is running a stable version. Servers SHOULD use **room version 11** as
room is running a stable version. Servers SHOULD use **room version 12** as
the default room version when creating new rooms.
{{% boxes/note %}}
{{% added-in v="1.16" %}}
Room version 12 is introduced and made default in this specification release.
Servers are encouraged to continue using room version 11 as the default room
version for the early days and weeks following this specification release,
and then gradually switch the default over when they deem appropriate.
<!-- TODO(SCT): Remove this note box in Matrix 1.17 -->
{{% /boxes/note %}}
The available room versions are:
- [Version 1](/rooms/v1) - **Stable**. The initial room version.
@ -76,6 +90,9 @@ The available room versions are:
- [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.
- [Version 12](/rooms/v12) - **Stable**. Changes room IDs to be hashes of the
create event, formalizes room creators with infinite power level, and iterates
on state resolution.
## Room version grammar

@ -30,10 +30,14 @@ The rules are as follows:
specified by the [auth events
selection](/server-server-api#auth-events-selection)
algorithm described in the server specification, reject.
**Note**: This room version requires an `m.room.create` event to be selected.
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.
5. If any event in `auth_events` has a `room_id` which does not match that of
the event being authorised, 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.

@ -0,0 +1,4 @@
Events in rooms of this version have the following structure:
{{% definition path="api/server-server/definitions/pdu_v12" %}}

@ -38,10 +38,14 @@ The complete list of rules, as of room version 3, is as follows:
specified by the [auth events
selection](/server-server-api#auth-events-selection)
algorithm described in the server specification, reject.
**Note**: This room version requires an `m.room.create` event to be selected.
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.
5. If any event in `auth_events` has a `room_id` which does not match that of
the event being authorised, 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.

@ -44,10 +44,14 @@ The rules are as follows:
specified by the [auth events
selection](/server-server-api#auth-events-selection)
algorithm described in the server specification, reject.
**Note**: This room version requires an `m.room.create` event to be selected.
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.
5. If any event in `auth_events` has a `room_id` which does not match that of
the event being authorised, 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.

@ -120,10 +120,14 @@ The rules are as follows:
specified by the [auth events
selection](/server-server-api#auth-events-selection)
algorithm described in the server specification, reject.
**Note**: This room version requires an `m.room.create` event to be selected.
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.
5. If any event in `auth_events` has a `room_id` which does not match that of
the event being authorised, 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.

@ -127,10 +127,14 @@ The rules are as follows:
specified by the [auth events
selection](/server-server-api#auth-events-selection)
algorithm described in the server specification, reject.
**Note**: This room version requires an `m.room.create` event to be selected.
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.
5. If any event in `auth_events` has a `room_id` which does not match that of
the event being authorised, 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.

@ -0,0 +1,502 @@
---
title: Room Version 12
type: docs
weight: 100
version: 12
---
This room version builds on [version 11](/rooms/v11), iterating on the state resolution
algorithm, giving room creators infinite power level, and changing the format of room
IDs to be a hash of the create event.
## Client considerations
### Event format
Clients SHOULD observe the following changes to events in this room version:
* Room IDs no longer include a domain component and are instead a hash of the
`m.room.create` event, per below. See the [room ID grammar](/appendices#room-ids)
for more information.
* A concept of "room creators" is formally defined as the `sender` of the `m.room.create`
event *plus* any `additional_creators` from the `m.room.create` event's `content`,
if present. In prior room versions, the only creator was the `sender` of the
`m.room.create` event (or `creator` in much older room versions).
* Room creators have infinitely high power level and cannot be specified in the
`m.room.power_levels` event, nor can they be changed after the room is created.
## 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 %}}
Room version 12 is based upon room version 11 with the following considerations.
### Event format
{{% rver-fragment name="v12-event-format" %}}
### Authorization rules
Events must be signed by the server denoted by the `sender` property.
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 %}}
{{% boxes/note %}}
{{% added-in v=12 %}} The power level of "room creators" is infinitely high.
Room creators include:
* The user ID denoted by the `sender` of the `m.room.create` event in the room.
* Any user IDs contained in the `additional_creators` array in `content` of the
`m.room.create` event in the room, if `additional_creators` is present.
Room creators cannot be demoted to a lower power level, even through `m.room.power_levels`.
This is reflected in rule 10.4 below.
{{% /boxes/note %}}
{{% boxes/note %}}
`m.room.redaction` events are subject to auth rules in the same way as any other event.
In practice, that means they will normally be allowed by the auth rules, unless the
`m.room.power_levels` event sets a power level requirement for `m.room.redaction`
events via the `events` or `events_default` properties. In particular, the _redact
level_ is **not** considered by the auth rules.
The ability to send a redaction event does not mean that the redaction itself should
be performed. Receiving servers must perform additional checks, as described in
the [Handling redactions](#handling-redactions) section.
{{% /boxes/note %}}
{{% boxes/note %}}
The `m.room.create` event MUST NOT be selected for `auth_events` on events. The
`room_id` (being the `m.room.create` event's ID) implies this instead. This is
reflected in a change to rule 3.2 below.
{{% /boxes/note %}}
The rules are as follows:
1. If type is `m.room.create`:
1. If it has any `prev_events`, reject.
2. {{% changed-in v=12 %}} If the event has a `room_id`, reject.
**Note**: The room ID is the event ID of the event with sigil `!` instead
of `$`.
3. If `content.room_version` is present and is not a recognised
version, reject.
4. {{% added-in v=12 %}} If `additional_creators` is present in `content` and
is not an array of strings where each string passes the same [user ID](/appendices#user-identifiers)
validation applied to `sender`, reject.
5. Otherwise, allow.
2. {{% added-in v=12 %}} If the event's `room_id` is not an event ID for an accepted
(not rejected) `m.room.create` event, with the sigil `!` instead of `$`, reject.
3. Considering the event's `auth_events`:
1. If there are duplicate entries for a given `type` and `state_key` pair,
reject.
2. {{% changed-in v=12 %}} 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.
**Note**: In this room version, `m.room.create` MUST NOT be selected.
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.
5. If any event in `auth_events` has a `room_id` which does not match that of
the event being authorised, reject.
4. 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.
5. 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 v=11 %}}
If the only previous event is an `m.room.create` and the
`state_key` is the sender of the `m.room.create`, 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`, `invite`,
or `join`, allow.
4. Otherwise, reject.
8. Otherwise, the membership is unknown. Reject.
6. If the `sender`'s current membership state is not `join`, reject.
7. 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*.
8. If the event type's *required power level* is greater than the
`sender`'s power level, reject.
9. If the event has a `state_key` that starts with an `@` and does not
match the `sender`, reject.
10. 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 object with keys that
are valid user IDs with values that are integers, reject.
4. {{% added-in v=12 %}} If the `users` property in `content` contains the
`sender` of the `m.room.create` event or any of the `additional_creators`
array (if present) from the `content` of the `m.room.create` event, reject.
5. If there is no previous `m.room.power_levels` event in the room,
allow.
6. 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.
7. 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.
8. 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.
9. 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.
10. 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.
11. 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 %}}
### State resolution
{{% boxes/note %}}
{{% added-in v=12 %}} This state resolution algorithm is largely the same as the
algorithm found in [room version 2](/rooms/v2) with the following modifications:
1. The *iterative auth checks algorithm* in the [Algorithm](#algorithm) subsection
now starts with an *empty* state map instead of the unconflicted state map.
2. A new [definition](#definitions) for *conflicted state subgraph* has been added
which describes events that are required to authorize events during iterative
auth checks.
3. To ensure the new conflicted state subgraph is actually referenced, the definition
for *full conflicted set* additionally includes the subgraph.
{{% /boxes/note %}}
The room state *S(E)* after an event *E* is defined in terms of the
room state *S(E)* before *E*, and depends on whether *E* is a state
event or a message event:
- If *E* is a message event, then *S(E)*=*S(E)*.
- If *E* is a state event, then *S(E)* is *S(E)*, except that its
entry corresponding to the `event_type` and `state_key` of *E* is
replaced by the `event_id` of *E*.
The room state *S(E)* before *E* is the *resolution* of the set of
states {*S(E*<sub>1</sub>*)*,*S(E*<sub>2</sub>*)*, …}
after the `prev_event`s {*E*<sub>1</sub>,*E*<sub>2</sub>, …} of *E*.
The resolution of a set of states is given in the algorithm below.
#### Definitions
The state resolution algorithm for version 2 rooms uses the following
definitions, given the set of room states
{*S*<sub>1</sub>,*S*<sub>2</sub>, …}:
**Power events.**
A *power event* is a state event with type `m.room.power_levels` or
`m.room.join_rules`, or a state event with type `m.room.member` where
the `membership` is `leave` or `ban` and the `sender` does not match the
`state_key`. The idea behind this is that power events are events that
might remove someone's ability to do something in the room.
**Unconflicted state map and conflicted state set.**
The keys of the state maps *S<sub>i</sub>* are 2-tuples of strings of the form
*K* = `(event_type, state_key)`. The values *V* are state events.
The key-value pairs (*K*, *V*) across all state maps *S<sub>i</sub>* can be
divided into two collections.
If a given key *K* is present in every *S<sub>i</sub>* with the same value *V*
in each state map, then the pair (*K*, *V*) belongs to the *unconflicted state map*.
Otherwise, *V* belongs to the *conflicted state set*.
Note that the unconflicted state map only has one event for each key *K*,
whereas the conflicted state set may contain multiple events with the same key.
**Auth chain.**
The *auth chain* of an event *E* is the set containing all of *E*'s auth events,
all of *their* auth events, and so on recursively, stretching back to the
start of the room. Put differently, these are the events reachable by walking
the graph induced by an event's `auth_events` links.
**Auth difference.**
The *auth difference* is calculated by first calculating the full auth
chain for each state *S*<sub>*i*</sub>, that is the union of the auth
chains for each event in *S*<sub>*i*</sub>, and then taking every event
that doesn't appear in every auth chain. If *C*<sub>*i*</sub> is the
full auth chain of *S*<sub>*i*</sub>, then the auth difference is
*C*<sub>*i*</sub> − ∩ *C*<sub>*i*</sub>.
{{% added-in v=12 %}} **Conflicted state subgraph.**
Starting from an event in the *conflicted state set* and following `auth_events`
edges may lead to another event in the conflicted state set. The union of all
such paths between any pair of events in the conflicted state set (including
endpoints) forms a subgraph of the original `auth_event` graph, called the
*conflicted state subgraph*.
{{% changed-in v=12 %}} **Full conflicted set.**
The *full conflicted set* is the union of the conflicted state set, the conflicted
state subgraph, and the auth difference.
**Reverse topological power ordering.**
The *reverse topological power ordering* of a set of events is the
lexicographically smallest topological ordering based on the DAG formed
by auth events. The reverse topological power ordering is ordered from
earliest event to latest. For comparing two topological orderings to
determine which is the lexicographically smallest, the following
comparison relation on events is used: for events *x* and *y*,
*x*&lt;*y* if
1. *x*'s sender has *greater* power level than *y*'s sender, when
looking at their respective `auth_event`s; or
2. the senders have the same power level, but *x*'s `origin_server_ts`
is *less* than *y*'s `origin_server_ts`; or
3. the senders have the same power level and the events have the same
`origin_server_ts`, but *x*'s `event_id` is *less* than *y*'s
`event_id`.
The reverse topological power ordering can be found by sorting the
events using Kahn's algorithm for topological sorting, and at each step
selecting, among all the candidate vertices, the smallest vertex using
the above comparison relation.
**Mainline ordering.**
Let *P* = *P*<sub>0</sub> be an `m.room.power_levels` event.
Starting with *i* = 0, repeatedly fetch *P*<sub>*i*+1</sub>, the
`m.room.power_levels` event in the `auth_events` of *P<sub>i</sub>*.
Increment *i* and repeat until *P<sub>i</sub>* has no `m.room.power_levels`
event in its `auth_events`.
The *mainline of P*<sub>0</sub> is the list of events
[*P*<sub>0</sub> , *P*<sub>1</sub>, ... , *P<sub>n</sub>*],
fetched in this way.
Let *e* = *e<sub>0</sub>* be another event (possibly another
`m.room.power_levels` event). We can compute a similar list of events
[*e*<sub>1</sub>, ..., *e<sub>m</sub>*],
where *e*<sub>*j*+1</sub> is the `m.room.power_levels` event in the
`auth_events` of *e<sub>j</sub>* and where *e<sub>m</sub>* has no
`m.room.power_levels` event in its `auth_events`. (Note that the event we
started with, *e<sub>0</sub>*, is not included in this list. Also note that it
may be empty, because *e* may not cite an `m.room.power_levels` event in its
`auth_events` at all.)
Now compare these two lists as follows.
* Find the smallest index *j* ≥ 1 for which *e<sub>j</sub>* belongs to the
mainline of *P*.
* If such a *j* exists, then *e<sub>j</sub>* = *P<sub>i</sub>* for some unique
index *i* ≥ 0. Otherwise set *i* = ∞, where ∞ is a sentinel value greater
than any integer.
* In both cases, the *mainline position* of *e* is *i*.
Given mainline positions calculated from *P*, the *mainline ordering based on* *P* of a set of events is the ordering,
from smallest to largest, using the following comparison relation on
events: for events *x* and *y*, *x*&lt;*y* if
1. the mainline position of *x* is **greater** than
the mainline position of *y* (i.e. the auth chain of
*x* is based on an earlier event in the mainline than *y*); or
2. the mainline positions of the events are the same, but *x*'s
`origin_server_ts` is *less* than *y*'s `origin_server_ts`; or
3. the mainline positions of the events are the same and the events have the
same `origin_server_ts`, but *x*'s `event_id` is *less* than *y*'s
`event_id`.
**Iterative auth checks.**
The *iterative auth checks algorithm* takes as input an initial room
state and a sorted list of state events, and constructs a new room state
by iterating through the event list and applying the state event to the
room state if the state event is allowed by the [authorization
rules](/server-server-api#authorization-rules).
If the state event is not allowed by the authorization rules, then the
event is ignored. If a `(event_type, state_key)` key that is required
for checking the authorization rules is not present in the state, then
the appropriate state event from the event's `auth_events` is used if
the auth event is not rejected.
#### Algorithm
The *resolution* of a set of states is obtained as follows:
1. Select the set *X* of all *power events* that appear in the *full
conflicted set*. For each such power event *P*, enlarge *X* by adding
the events in the auth chain of *P* which also belong to the full
conflicted set. Sort *X* into a list using the *reverse topological
power ordering*.
2. {{% changed-in v=12 %}} Apply the *iterative auth checks algorithm*,
starting from an *empty* 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 state obtained in step 2.
4. Apply the *iterative auth checks algorithm* on the partial resolved
state and the list of events from the previous step.
5. Update the result by replacing any event with the event with the
same key from the *unconflicted state map*, if such an event exists,
to get the final resolved state.
#### Rejected events
Events that have been rejected due to failing auth based on the state at
the event (rather than based on their auth chain) are handled as usual
by the algorithm, unless otherwise specified.
Note that no events rejected due to failure to auth against their auth
chain should appear in the process, as they should not appear in state
(the algorithm only uses events that appear in either the state sets or
in the auth chain of the events in the state sets).
{{% boxes/rationale %}}
This helps ensure that different servers' view of state is more likely
to converge, since rejection state of an event may be different. This
can happen if a third server gives an incorrect version of the state
when a server joins a room via it (either due to being faulty or
malicious). Convergence of state is a desirable property as it ensures
that all users in the room have a (mostly) consistent view of the state
of the room. If the view of the state on different servers diverges it
can lead to bifurcation of the room due to e.g. servers disagreeing on
who is in the room.
Intuitively, using rejected events feels dangerous, however:
1. Servers cannot arbitrarily make up state, since they still need to
pass the auth checks based on the event's auth chain (e.g. they
can't grant themselves power levels if they didn't have them
before).
2. For a previously rejected event to pass auth there must be a set of
state that allows said event. A malicious server could therefore
produce a fork where it claims the state is that particular set of
state, duplicate the rejected event to point to that fork, and send
the event. The duplicated event would then pass the auth checks.
Ignoring rejected events would therefore not eliminate any potential
attack vectors.
{{% /boxes/rationale %}}
Rejected auth events are deliberately excluded from use in the iterative
auth checks, as auth events aren't re-authed (although non-auth events
are) during the iterative auth checks.
## Unchanged from v11
The following sections have not been modified since v11, but are included for
completeness.
### Redactions
{{% rver-fragment name="v11-redactions" %}}
### Handling redactions
{{% rver-fragment name="v3-handling-redactions" %}}
### Event IDs
{{% rver-fragment name="v4-event-ids" %}}
### Canonical JSON
{{% rver-fragment name="v6-canonical-json" %}}
### Signing key validity period
{{% rver-fragment name="v5-signing-requirements" %}}

@ -102,10 +102,14 @@ The rules are as follows:
specified by the [auth events
selection](/server-server-api#auth-events-selection)
algorithm described in the server specification, reject.
**Note**: This room version requires an `m.room.create` event to be selected.
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.
5. If any event in `auth_events` has a `room_id` which does not match that of
the event being authorised, 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.

@ -81,10 +81,14 @@ The rules are as follows:
specified by the [auth events
selection](/server-server-api#auth-events-selection)
algorithm described in the server specification, reject.
**Note**: This room version requires an `m.room.create` event to be selected.
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.
5. If any event in `auth_events` has a `room_id` which does not match that of
the event being authorised, 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.

@ -119,7 +119,7 @@ to send. The process overall is as follows:
server must present a valid certificate for the hostname.
3. If the hostname is not an IP literal, a regular HTTPS request is
made to `https://<hostname>/.well-known/matrix/server` (according to
made to `https://<hostname>/.well-known/matrix/server` (according to
[RFC 8615](https://datatracker.ietf.org/doc/html/rfc8615)), expecting
the schema defined later in this section. 30x redirects should be
followed, however redirection loops should be avoided. Responses
@ -461,9 +461,12 @@ specification](/rooms).
Whenever a server receives an event from a remote server, the receiving
server must ensure that the event:
1. Is a valid event, otherwise it is dropped. For an event to be valid, it
must contain a `room_id`, and it must comply with the event format of
that [room version](/rooms).
1. {{% changed-in v="1.16" %}} Is a valid event, otherwise it is dropped. For
an event to be valid, it must comply with the event format of that [room version](/rooms).
For some room versions, a `room_id` may also be required on the event in order
to determine the room version to check the event against. See the event format
section of the [room version specifications](/rooms) for details on when it
is required.
2. Passes signature checks, otherwise it is dropped.
3. Passes hash checks, otherwise it is redacted before being processed
further.
@ -529,7 +532,8 @@ the sender permission to send the event. The `auth_events` for the
`m.room.create` event in a room is empty; for other events, it should be
the following subset of the room state:
- The `m.room.create` event.
- {{% changed-in v="1.16" %}} Depending on the [room version](/rooms), the
`m.room.create` event.
- The current `m.room.power_levels` event, if any.
@ -1050,7 +1054,7 @@ from the user owning the invited third-party identifier.
## Published Room Directory
To complement the [room directory in the Client-Server API](/client-server-api#published-room-directory),
To complement the [room directory in the Client-Server API](/client-server-api#published-room-directory),
homeservers need a way to query the published rooms of another server.
This can be done by making a request to the `/publicRooms` endpoint for
the server the room directory should be retrieved for.

@ -33,9 +33,23 @@ paths:
2. An `m.room.member` event for the creator to join the room. This is
needed so the remaining events can be sent.
3. A default `m.room.power_levels` event, giving the room creator
(and not other members) permission to send state events. Overridden
by the `power_level_content_override` parameter.
3. A default `m.room.power_levels` event. Overridden by the
`power_level_content_override` parameter.
In [room versions](/rooms) 1 through 11, the room creator (and not
other members) will be given permission to send state events.
In room versions 12 and later, the room creator is given infinite
power level and cannot be specified in the `users` field of
`m.room.power_levels`, so is not listed explicitly.
**Note**: For `trusted_private_chat`, the users specified in the
`invite` parameter SHOULD also be appended to `additional_creators`
by the server, per the `creation_content` parameter.
If the room's version is 12 or higher, the power level for sending
`m.room.tombstone` events MUST explicitly be higher than `state_default`.
For example, set to 150 instead of 100.
4. An `m.room.canonical_alias` event if `room_alias_name` is given.
@ -61,8 +75,10 @@ paths:
The server will create a `m.room.create` event in the room with the
requesting user as the creator, alongside other keys provided in the
`creation_content`.
`creation_content` or implied by behaviour of `creation_content`.
operationId: createRoom
x-changedInMatrixVersion:
"1.16": Added server behaviour for how the initial power levels change depending on room version.
security:
- accessTokenQuery: []
- accessTokenBearer: []
@ -142,11 +158,20 @@ paths:
creation_content:
title: CreationContent
type: object
x-changedInMatrixVersion:
"1.16": Added server behaviour for how to handle `trusted_private_chat` and invited users.
description: |-
Extra keys, such as `m.federate`, to be added to the content
of the [`m.room.create`](/client-server-api/#mroomcreate) event. The server will overwrite the following
of the [`m.room.create`](/client-server-api/#mroomcreate) event.
The server will overwrite the following
keys: `creator`, `room_version`. Future versions of the specification
may allow the server to overwrite other keys.
When using the `trusted_private_chat` preset, the server SHOULD combine
`additional_creators` specified here and the `invite` array into the
eventual `m.room.create` event's `additional_creators`, deduplicating
between the two parameters.
initial_state:
type: array
description: |-
@ -225,7 +250,7 @@ paths:
}
"400":
description: |-
The request is invalid. A meaningful `errcode` and description
error text will be returned. Example reasons for rejection include:

@ -41,6 +41,23 @@ paths:
new_version:
type: string
description: The new version for the room.
additional_creators:
type: array
items:
type: string
description: Additional user ID to consider a room creator, if the room version supports it.
x-addedInMatrixVersion: "1.16"
description: |-
When upgrading to a [room version](/rooms) which supports additional creators,
the [user IDs](/appendices#user-identifiers) which should be considered room
creators in addition to the user performing the upgrade.
If the room being upgraded has additional creators, they are *not* automatically
copied to the new room. The full set of additional creators needs to be set to
retain (or add/remove) more room creators.
When upgrading to a room version which doesn't support additional creators, this
field is ignored and has no effect during the upgrade process.
example: {
"new_version": "2"
}

@ -0,0 +1,25 @@
# Copyright 2025 The Matrix.org Foundation C.I.C.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
type: object
description: |-
The depth field of PDUs for room version 6 and beyond.
properties:
# v6 enforces Canonical JSON and therefore needs a depth limit change
depth:
type: integer
description: |-
The maximum depth of the `prev_events`, plus one. Must be less than the
maximum value for an integer (2^53 - 1). If the room's depth is already at
the limit, the depth must be set to the limit.
example: 12

@ -14,10 +14,6 @@
type: object
description: Common fields for all PDU versions
properties:
room_id:
type: string
description: Room identifier.
example: "!abc123:matrix.org"
sender:
type: string
description: The ID of the user sending the event.
@ -69,7 +65,6 @@ properties:
description: The number of milliseconds that have passed since this message was sent.
example: 4612
required:
- room_id
- sender
- origin_server_ts
- type

@ -0,0 +1,23 @@
# Copyright 2025 The Matrix.org Foundation C.I.C.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
type: object
description: |-
The room_id field of PDUs for room version 11 and prior.
properties:
room_id:
type: string
description: Room identifier.
example: "!abc123:matrix.org"
required:
- room_id

@ -0,0 +1,23 @@
# Copyright 2025 The Matrix.org Foundation C.I.C.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
type: object
description: |-
The room_id field of PDUs for room version 12 and beyond.
properties:
room_id:
type: string
description: Room identifier. Omitted from `m.room.create` events.
example: "!Nhcu5BS-UMnFX7hBVfVSoXiD7OgH6iRT-xyIuqDnpYQ"
required:
- room_id

@ -18,6 +18,7 @@ example:
$ref: "../examples/pdu_v1.json"
allOf:
- $ref: "components/pdu_base.yaml"
- $ref: "components/room_id_before_v12.yaml"
- type: object
properties:
event_id:

@ -13,20 +13,12 @@
# limitations under the License.
type: object
title: Persistent Data Unit
description: A persistent data unit (event) for room version 11 and beyond.
description: A persistent data unit (event) for room version 11.
example:
$ref: "../examples/pdu_v11.json"
allOf:
# v11 is the v6 event, but without redacts.
- $ref: "components/pdu_base.yaml"
- $ref: "components/auth_events_prev_events_v4.yaml"
- type: object
properties:
# v6 enforces Canonical JSON and therefore needs a depth limit change
depth:
type: integer
description: |-
The maximum depth of the `prev_events`, plus one. Must be less than the
maximum value for an integer (2^53 - 1). If the room's depth is already at
the limit, the depth must be set to the limit.
example: 12
- $ref: "components/room_id_before_v12.yaml"
- $ref: "components/depth_v6.yaml"

@ -0,0 +1,24 @@
# Copyright 2025 The Matrix.org Foundation C.I.C.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
type: object
title: Persistent Data Unit
description: A persistent data unit (event) for room version 12 and beyond.
example:
$ref: "../examples/pdu_v12.json"
allOf:
# v12 is the v11 event, but with special room ID requirements.
- $ref: "components/pdu_base.yaml"
- $ref: "components/auth_events_prev_events_v4.yaml"
- $ref: "components/depth_v6.yaml"
- $ref: "components/room_id_v12.yaml" # this is the v12 change

@ -18,6 +18,7 @@ example:
$ref: "../examples/pdu_v3.json"
allOf:
- $ref: "components/pdu_base.yaml"
- $ref: "components/room_id_before_v12.yaml"
- type: object
properties:
redacts:

@ -20,6 +20,7 @@ example:
allOf:
- $ref: "components/pdu_base.yaml"
- $ref: "components/auth_events_prev_events_v4.yaml"
- $ref: "components/room_id_before_v12.yaml"
- type: object
properties:
redacts:

@ -20,17 +20,11 @@ example:
allOf:
- $ref: "components/pdu_base.yaml"
- $ref: "components/auth_events_prev_events_v4.yaml"
- $ref: "components/room_id_before_v12.yaml"
- $ref: "components/depth_v6.yaml"
- type: object
properties:
redacts:
type: string
description: For redaction events, the ID of the event being redacted.
example: "$def_456-oldevent"
# v6 enforces Canonical JSON and therefore needs a depth limit change
depth:
type: integer
description: |-
The maximum depth of the `prev_events`, plus one. Must be less than the
maximum value for an integer (2^53 - 1). If the room's depth is already at
the limit, the depth must be set to the limit.
example: 12

@ -0,0 +1,9 @@
{
"allOf": [
{ "$ref": "components/pdu_base.json" },
{ "$ref": "components/auth_events_prev_events_v4.json" },
{
"room_id": "!Nhcu5BS-UMnFX7hBVfVSoXiD7OgH6iRT-xyIuqDnpYQ"
}
]
}

@ -33,8 +33,36 @@ properties:
description: The ID of the old room.
event_id:
type: string
description: The event ID of the last known event in the old room.
required: [room_id, event_id]
deprecated: true
x-changedInMatrixVersion:
"1.16": |-
This field became deprecated and may not be present in all cases. It SHOULD still
be populated where possible/practical. Previously, it was required.
description: |-
The event ID of the last known event in the old room, if known.
If not set, clients SHOULD search for the `m.room.tombstone` state event to navigate to
when directing the user to the old room (potentially after joining the room, if requested
by the user).
required: [room_id]
additional_creators:
type: array
items:
type: string
description: Additional user ID to consider a creator of the room, if supported by the room version.
x-addedInMatrixVersion: "1.16"
description: |-
Starting with room version 12, the other user IDs to consider as creators for the room in
addition to the `sender` of this event. Each string MUST be a valid [user ID](/appendices#user-identifiers)
for the room version.
When not present or empty, the `sender` of the event is the only creator.
In room versions 1 through 11, this field serves no purpose and is not validated. Clients
SHOULD NOT attempt to parse or understand this field in these room versions.
**Note**: Because `creator` was removed in room version 11, the field is not used to determine
which user(s) are room creators in room version 12 and beyond either.
type: object
state_key:
description: A zero-length string.

@ -44,7 +44,15 @@ properties:
events:
additionalProperties:
type: integer
description: The level required to send specific event types. This is a mapping from event type to power level required.
description: |-
The level required to send specific event types. This is a mapping from event type to power level required.
Though not a default, when the server sends the initial power levels event during [room creation](/client-server-api#creation)
in [room versions](/rooms) 12 and higher, the `m.room.tombstone` event MUST be explicitly defined and given
a power level higher than `state_default`. For example, power level 150. Clients may override this using the
described `power_level_content_override` field.
x-changedInMatrixVersion:
"1.16": Described `m.room.tombstone` defaults during creation of a room version 12 or higher room.
title: Event power levels
type: object
events_default:
@ -71,16 +79,28 @@ properties:
"^@":
x-pattern-format: mx-user-id
type: integer
description: The power levels for specific users. This is a mapping from `user_id` to power level for that user.
description: |-
The power levels for specific users. This is a mapping from `user_id` to power level for that user.
**Note**: In [room versions](/rooms) 12 and higher it is not permitted to specify the room creators here.
x-changedInMatrixVersion:
"1.16": Added a note that room creators cannot be specified here in room versions 12 and higher.
title: User power levels
type: object
users_default:
x-changedInMatrixVersion:
"1.16": The room creator power level now changes depending on room version.
description: |-
The power level for users in the room whose `user_id` is not mentioned in the `users` key. Defaults to 0 if
unspecified.
**Note**: When there is no `m.room.power_levels` event in the room, the room creator has
a power level of 100, and all other users have a power level of 0.
**Note**: In [room versions](/rooms) 1 through 11, when there is no `m.room.power_levels`
event in the room, the room creator has a power level of 100, and all other users have a
power level of 0.
**Note**: In room versions 12 and higher, room creators have infinite power level regardless
of the existence of `m.room.power_levels` in the room. When `m.room.power_levels` is not
in the room however, all other users have a power level of 0.
type: integer
notifications:
properties:

Loading…
Cancel
Save