<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc version 1.6.36 (Ruby 3.2.2) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-ralston-mimi-linearized-matrix-03" category="std" consensus="true" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.17.4 -->
  <front>
    <title abbrev="Linearized Matrix">Linearized Matrix</title>
    <seriesInfo name="Internet-Draft" value="draft-ralston-mimi-linearized-matrix-03"/>
    <author fullname="Travis Ralston">
      <organization>The Matrix.org Foundation C.I.C.</organization>
      <address>
        <email>travisr@matrix.org</email>
      </address>
    </author>
    <author fullname="Matthew Hodgson">
      <organization>The Matrix.org Foundation C.I.C.</organization>
      <address>
        <email>matthew@matrix.org</email>
      </address>
    </author>
    <date year="2023" month="July" day="10"/>
    <area>Applications and Real-Time</area>
    <workgroup>More Instant Messaging Interoperability</workgroup>
    <keyword>matrix</keyword>
    <keyword>linearized</keyword>
    <keyword>interoperability</keyword>
    <keyword>messaging</keyword>
    <keyword>mimi</keyword>
    <keyword>decentralized</keyword>
    <abstract>
      <?line 66?>

<t>This document specifies Linearized Matrix (LM). LM is an extensible protocol for interoperability
between messaging providers, using Matrix's (<eref target="https://matrix.org">matrix.org</eref>) decentralized room
model. LM simplifies the Directed Acyclic Graph (DAG) persistence of Matrix while maintaining
compatibility with non-linearized servers within a room. It does this by using a doubly-linked list
of events/messages per room with hub and spoke fanout.</t>
      <t>LM's extensibility enables a wide range of transport protocol and end-to-end encryption possibilities.
This document uses Matrix's room access control semantics supported by Messaging Layer Security (MLS),
transported via HTTPS and JSON. The details of which server-to-server transport to use and what a is
put over MLS are replaceable.</t>
      <t>The threat model of LM does not place trust in a central owning server for each conversation. Instead,
it defines a hub server which handles maintaining linearized room history for other servers in the
room. This model permits transparent interconnection between LM servers and Matrix servers, in the
same room.</t>
    </abstract>
    <note removeInRFC="true">
      <name>About This Document</name>
      <t>
        The latest revision of this draft can be found at <eref target="https://turt2live.github.io/ietf-mimi-linearized-matrix/draft-ralston-mimi-linearized-matrix.html"/>.
        Status information for this document may be found at <eref target="https://datatracker.ietf.org/doc/draft-ralston-mimi-linearized-matrix/"/>.
      </t>
      <t>
        Discussion of this document takes place on the
        More Instant Messaging Interoperability Working Group mailing list (<eref target="mailto:mimi@ietf.org"/>),
        which is archived at <eref target="https://mailarchive.ietf.org/arch/browse/mimi/"/>.
        Subscribe at <eref target="https://www.ietf.org/mailman/listinfo/mimi/"/>.
      </t>
      <t>Source for this draft and an issue tracker can be found at
        <eref target="https://github.com/turt2live/ietf-mimi-linearized-matrix"/>.</t>
    </note>
  </front>
  <middle>
    <?line 84?>

<section anchor="int-intro">
      <name>Introduction</name>
      <t>Linearized Matrix derives from Matrix (<eref target="https://matrix.org">matrix.org</eref>). Matrix is an interoperable
decentralized communications protocol with an open specification. Matrix uses a Directed Acyclic Graph
(DAG) to persist rooms, synchronizing the DAG between servers. Linearized Matrix uses an append-only
doubly-linked list. A hub server is present in each room to persist the linked list, and to handle
linearization of events (user/application messages, as well as room configuration changes) from other
servers.</t>
      <t>The hub server in a room does not act as an owner for the room. All rooms support the doubly-linked
list and a DAG at the same time. The precise details of DAG and linked list interconnection are not
covered by this document; they are out of scope for the More Instant Messaging Interoperability (MIMI)
working group. Full details are available within the Matrix specification process as <xref target="MSC3995"/>. Where
applicable, this document covers the mandatory components.</t>
      <t>As rooms support these two representations, this permits a variable threat model. Messaging providers
who want to deliver all their messages/don't trust other servers to deliver their messages would choose
the DAG representation, at the cost of implementation complexity. Providers using the Linearized Matrix
representation place trust in the hub server to deliver the messages. Those providers attach verifiable
hashes and signatures to each event as a safeguard against the hub server modifying the events.</t>
      <t>The primary exports of Linearized Matrix are the room model and the rules which govern how a room
accepts events. This document specifies a server-centric approach, where one or more servers perform
access control. With some changes, it can become client-centric too. This document also specifies a
transport for synchronizing the doubly-linked list to other servers. More efficient and scalable
transport methods should replace this example.</t>
      <t>In a similar fashion, this document specifies how Messaging Layer Security (MLS) <xref target="I-D.ietf-mls-protocol"/>
        <xref target="I-D.ietf-mls-architecture"/> could run over a Linearized Matrix room. User messages use MLS, while
state events (room configuration information) are plain-text in this iteration of the document. Clients
synchronize room and MLS group membership, while servers verify those memberships. This ensures that
users who are not in the room are unable to gain access to encrypted messages.</t>
      <t>A key component for interoperability is consistent access control semantics. Where a single server
'owns' a room, it can establish arbitrary measures. For example, an owning provider might decide that
a different kind of password is required to join a room. This diminishes the user experience on providers
who do not (or can not) support those custom measures. With decentralization, all participating servers
must use the same consistent set of access controls. Linearized Matrix uses a decentralized room model
for this reason, with linear room history for ease of implementation.</t>
      <t>Linearized Matrix also supports transferring a hub to a different server in the room. This enables
two major features: a hub server that wishes to leave the room can do so, as it is no longer responsible
for handling events for the room, and because the hub could change at any time, access control semantics
must remain consistent. As a bonus, hub transfers make it possible for a (non-linearized) Matrix server
to take hub status. When it becomes the hub, it takes responsibility for linearizing the room's DAG
for other Linearized Matrix servers in the room. The DAG linearization algorithm is not specified in
this document; it is out of scope for the MIMI working group.</t>
    </section>
    <section anchor="conventions-and-definitions">
      <name>Conventions and Definitions</name>
      <t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
appear in all capitals, as shown here.</t>
      <?line -18?>

<t>This document uses <xref target="I-D.ralston-mimi-terminology"/> for the majority of terminology.</t>
      <t>This document additionally defines:</t>
      <t><strong>Rejection</strong>: An event which is "rejected" is not relayed to any local clients and is not appended
to the room in any way.</t>
      <t><strong>Soft Failure</strong>: An event which is "soft-failed" <bcp14>SHOULD NOT</bcp14> be relayed to any local clients, nor be
used as in <tt>auth_events</tt> if possible. The event is otherwise appended to the room as per usual.</t>
      <t>Further terms are introduced in-context within this document.</t>
      <t><strong>TODO</strong>: We should move/copy those definitions up here anyways.</t>
    </section>
    <section anchor="architecture">
      <name>Architecture</name>
      <t>For a given conversation/room:</t>
      <artset>
        <artwork type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="400" width="552" viewBox="0 0 552 400" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
            <path d="M 8,128 L 8,192" fill="none" stroke="black"/>
            <path d="M 56,72 L 56,128" fill="none" stroke="black"/>
            <path d="M 56,192 L 56,272" fill="none" stroke="black"/>
            <path d="M 104,200 L 104,240" fill="none" stroke="black"/>
            <path d="M 112,64 L 112,120" fill="none" stroke="black"/>
            <path d="M 160,128 L 160,192" fill="none" stroke="black"/>
            <path d="M 288,224 L 288,288" fill="none" stroke="black"/>
            <path d="M 336,296 L 336,352" fill="none" stroke="black"/>
            <path d="M 392,128 L 392,192" fill="none" stroke="black"/>
            <path d="M 392,288 L 392,344" fill="none" stroke="black"/>
            <path d="M 440,72 L 440,128" fill="none" stroke="black"/>
            <path d="M 440,224 L 440,288" fill="none" stroke="black"/>
            <path d="M 496,64 L 496,120" fill="none" stroke="black"/>
            <path d="M 544,128 L 544,192" fill="none" stroke="black"/>
            <path d="M 40,32 L 128,32" fill="none" stroke="black"/>
            <path d="M 424,32 L 512,32" fill="none" stroke="black"/>
            <path d="M 40,64 L 128,64" fill="none" stroke="black"/>
            <path d="M 424,64 L 512,64" fill="none" stroke="black"/>
            <path d="M 8,128 L 160,128" fill="none" stroke="black"/>
            <path d="M 392,128 L 544,128" fill="none" stroke="black"/>
            <path d="M 160,144 L 248,144" fill="none" stroke="black"/>
            <path d="M 320,144 L 384,144" fill="none" stroke="black"/>
            <path d="M 168,176 L 248,176" fill="none" stroke="black"/>
            <path d="M 320,176 L 392,176" fill="none" stroke="black"/>
            <path d="M 8,192 L 160,192" fill="none" stroke="black"/>
            <path d="M 392,192 L 544,192" fill="none" stroke="black"/>
            <path d="M 288,224 L 440,224" fill="none" stroke="black"/>
            <path d="M 104,240 L 144,240" fill="none" stroke="black"/>
            <path d="M 216,240 L 288,240" fill="none" stroke="black"/>
            <path d="M 56,272 L 144,272" fill="none" stroke="black"/>
            <path d="M 216,272 L 280,272" fill="none" stroke="black"/>
            <path d="M 288,288 L 440,288" fill="none" stroke="black"/>
            <path d="M 320,352 L 408,352" fill="none" stroke="black"/>
            <path d="M 320,384 L 408,384" fill="none" stroke="black"/>
            <path d="M 40,32 C 31.16936,32 24,39.16936 24,48" fill="none" stroke="black"/>
            <path d="M 128,32 C 136.83064,32 144,39.16936 144,48" fill="none" stroke="black"/>
            <path d="M 424,32 C 415.16936,32 408,39.16936 408,48" fill="none" stroke="black"/>
            <path d="M 512,32 C 520.83064,32 528,39.16936 528,48" fill="none" stroke="black"/>
            <path d="M 40,64 C 31.16936,64 24,56.83064 24,48" fill="none" stroke="black"/>
            <path d="M 128,64 C 136.83064,64 144,56.83064 144,48" fill="none" stroke="black"/>
            <path d="M 424,64 C 415.16936,64 408,56.83064 408,48" fill="none" stroke="black"/>
            <path d="M 512,64 C 520.83064,64 528,56.83064 528,48" fill="none" stroke="black"/>
            <path d="M 320,352 C 311.16936,352 304,359.16936 304,368" fill="none" stroke="black"/>
            <path d="M 408,352 C 416.83064,352 424,359.16936 424,368" fill="none" stroke="black"/>
            <path d="M 320,384 C 311.16936,384 304,376.83064 304,368" fill="none" stroke="black"/>
            <path d="M 408,384 C 416.83064,384 424,376.83064 424,368" fill="none" stroke="black"/>
            <polygon class="arrowhead" points="504,120 492,114.4 492,125.6" fill="black" transform="rotate(90,496,120)"/>
            <polygon class="arrowhead" points="448,72 436,66.4 436,77.6" fill="black" transform="rotate(270,440,72)"/>
            <polygon class="arrowhead" points="400,344 388,338.4 388,349.6" fill="black" transform="rotate(90,392,344)"/>
            <polygon class="arrowhead" points="392,144 380,138.4 380,149.6" fill="black" transform="rotate(0,384,144)"/>
            <polygon class="arrowhead" points="344,296 332,290.4 332,301.6" fill="black" transform="rotate(270,336,296)"/>
            <polygon class="arrowhead" points="288,272 276,266.4 276,277.6" fill="black" transform="rotate(0,280,272)"/>
            <polygon class="arrowhead" points="176,176 164,170.4 164,181.6" fill="black" transform="rotate(180,168,176)"/>
            <polygon class="arrowhead" points="120,120 108,114.4 108,125.6" fill="black" transform="rotate(90,112,120)"/>
            <polygon class="arrowhead" points="112,200 100,194.4 100,205.6" fill="black" transform="rotate(270,104,200)"/>
            <polygon class="arrowhead" points="64,72 52,66.4 52,77.6" fill="black" transform="rotate(270,56,72)"/>
            <g class="text">
              <text x="76" y="52">Client</text>
              <text x="112" y="52">A</text>
              <text x="460" y="52">Client</text>
              <text x="496" y="52">B</text>
              <text x="184" y="100">Client-Server</text>
              <text x="256" y="100">API</text>
              <text x="284" y="148">events</text>
              <text x="80" y="164">Provider/Server</text>
              <text x="464" y="164">Provider/Server</text>
              <text x="80" y="180">A</text>
              <text x="284" y="180">events</text>
              <text x="464" y="180">B</text>
              <text x="240" y="196">Server-Server</text>
              <text x="332" y="196">Protocol</text>
              <text x="180" y="244">events</text>
              <text x="360" y="260">Provider/Server</text>
              <text x="180" y="276">events</text>
              <text x="360" y="276">C</text>
              <text x="356" y="372">Client</text>
              <text x="392" y="372">C</text>
            </g>
          </svg>
        </artwork>
        <artwork type="ascii-art"><![CDATA[
   .------------.                                  .------------.
  |   Client A   |                                |   Client B   |
   '---------+--'                                  '---------+--'
      ^      |                                        ^      |
      |      |  Client-Server API                     |      |
      |      V                                        |      V
+-----+------------+                            +-----+------------+
|                  +----------( events )------->|                  |
| Provider/Server  |                            | Provider/Server  |
|        A         |<---------( events )--------+        B         |
+-----+------------+   Server-Server Protocol   +------------------+
      |     ^
      |     |                      +------------------+
      |     +----( events )--------+                  |
      |                            | Provider/Server  |
      +----------( events )------->|        C         |
                                   +------------+-----+
                                         ^      |
                                         |      |
                                         |      V
                                      .--+---------.
                                     |   Client C   |
                                      '------------'
]]></artwork>
      </artset>
      <t>In this diagram, events (<xref target="int-pdu"/>) are objects which carry information about the room as well as messages
between users within that room.</t>
      <t>Server A is acting as a hub for the other two servers in the diagram. Servers B and C do
not converse directly when sending events to the room: those events are instead sent to the
hub which then distributes them back out to all participating servers. Servers communicate
with each other using the API surface described by <xref target="int-transport"/>.</t>
      <t>Clients are shown in the diagram here for demonstrative purposes only. No Client-Server API
or other requirements of clients are specified in this document.</t>
      <t>This leads to two distinct roles:</t>
      <ul spacing="normal">
        <li>
          <strong>Hub server</strong>: the server responsible for holding conversation history on behalf of
other servers in the room.</li>
        <li>
          <strong>Participant server</strong>: any non-hub server. This server <bcp14>MAY</bcp14> persist conversation history
or rely on the hub server instead.</li>
      </ul>
      <t><strong>OPEN QUESTION</strong>: Should we support having multiple hubs for increased trust between
participant and hub? (participant can pick the hub it wants to use rather than being
forced to use a single hub)</t>
      <t><strong>OPEN QUESTION</strong>: Should we instead require that each server persist events they create, with the hub
being responsible for purely distribution/fetching? It'd be in the hub's best interest to store all
history, but equally if it can rebuild the room by reaching out to origin servers then it might be
fine enough (it'd only be storing event IDs rather than whole events).</t>
      <section anchor="int-server-names">
        <name>Server Names</name>
        <t>Each messaging provider is referred to as a "server" and has a "domain name" or "server name"
to uniquely identify it. This server name is then used to namespace user IDs, room IDs/aliases,
etc.</t>
        <t>A server name <bcp14>MUST</bcp14> be compliant with <xref section="2.1" sectionFormat="of" target="RFC1123"/>. Improper server names <bcp14>MUST</bcp14> be
considered "uncontactable" by a server.</t>
        <t>A server <bcp14>MUST NOT</bcp14> use a literal IPv4 or IPv6 address as a server name. Doing so reduces the ability
for the server to move to another internet address later, and IP addresses are generally difficult
to acquire a certificate for (required in <xref target="int-transport"/>). Additionally, servers <bcp14>SHOULD NOT</bcp14> use
an explicit port in their server name for similar portability reasons.</t>
        <t>The approximate ABNF <xref target="RFC5234"/> grammar for a server name is:</t>
        <artwork><![CDATA[
server_name = hostname [ ":" port ]
port        = 1*5DIGIT
hostname    = 1*255dns-char
dns-char    = DIGIT / ALPHA / "-" / "."
]]></artwork>
        <t>Server names <bcp14>MUST</bcp14> be treated as case sensitive (<tt>eXaMpLe.OrG</tt>, <tt>example.org</tt>, and <tt>EXAMPLE.ORG</tt>
are 3 different servers). Server names <bcp14>SHOULD</bcp14> be lower case (<tt>example.org</tt>) and <bcp14>SHOULD NOT</bcp14> exceed
230 characters for ease of use. The 230 characters specifically gives room for a suitably long
localpart while being within the 255 allowable characters from <xref section="2.1" sectionFormat="of" target="RFC1123"/>.</t>
        <t>Examples:</t>
        <ul spacing="normal">
          <li>
            <tt>example.org</tt> (DNS host name)</li>
          <li>
            <tt>example.org:5678</tt> (DNS host name with explicit port)</li>
        </ul>
      </section>
      <section anchor="int-room-id">
        <name>Rooms</name>
        <t>Rooms hold the same definition under <xref target="I-D.ralston-mimi-terminology"/>: a conceptual place
where users send and receive events. All users with sufficient access to the room receive
events sent to that room.</t>
        <t>The different chat types are represented by rooms through state events (<xref target="int-state-events"/>), which
ultimately change how the different algorithms in the room version (<xref target="int-room-versions"/>) behave.</t>
        <t>Rooms have a single internal "Room ID" to identify them from another room. The ABNF <xref target="RFC5234"/>
grammar for a room ID is:</t>
        <artwork><![CDATA[
room_id = "!" room_id_localpart ":" server_name
room_id_localpart = 1*opaque
opaque = DIGIT / ALPHA / "-" / "." / "~" / "_"
]]></artwork>
        <t><tt>server_name</tt> is inherited from <xref target="int-server-names"/>.</t>
        <t><tt>room_id</tt> <bcp14>MUST NOT</bcp14> exceed 255 characters and <bcp14>MUST</bcp14> be treated as case sensitive.</t>
        <t>Example: <tt>!abc:example.org</tt>.</t>
        <t>The <tt>server_name</tt> for a room ID does <em>NOT</em> indicate the room is "hosted" or served by that
domain. The domain is used as a namespace to prevent another server from maliciously taking
over a room. The server represented by that domain may no longer be participating in the room.</t>
        <t>The entire room ID after the <tt>!</tt> sigil <bcp14>MUST</bcp14> be treated as opaque. No part of the room ID should
be parsed, and cannot be assumed to be human-readable.</t>
        <section anchor="int-room-versions">
          <name>Room Versions</name>
          <t><strong>TODO</strong>: We should consider naming this something else.</t>
          <t>Each room declares which room version it's using, and each room version (identified by a single
string) describes the specific algorithms a server needs to follow in order to particpate in rooms
with that version. Room versions are immutable once specified, as otherwise a change in algorithms
could cause a split-brain between servers participating in affected rooms.</t>
          <t>Room versions prefixed with <tt>I.</tt> <bcp14>MUST</bcp14> only be used within the IETF specification process.
Room versions consisting solely of <tt>0-9</tt> and <tt>.</tt> <bcp14>MUST</bcp14> only be used by the Matrix protocol.</t>
          <t>This document as a whole describes <tt>I.1</tt> as a room version.</t>
          <t>Servers <bcp14>MUST</bcp14> implement support for <tt>I.1</tt> at a minimum. Servers <bcp14>SHOULD</bcp14> use <tt>I.1</tt> when creating
new rooms.</t>
          <t><strong>Implementation note</strong>: Currently <tt>I.1</tt> is not a real thing. Use
<tt>org.matrix.i-d.ralston-mimi-linearized-matrix.02</tt> when testing against other Linearized Matrix
implementations. This string may be updated later to account for breaking changes.</t>
          <t><strong>Implementation note</strong>: <tt>org.matrix.i-d.ralston-mimi-linearized-matrix.00</tt> also exists in the
wild, defining a set of algorithms which exist in a prior version of this document (00 and 01).</t>
          <t><strong>TODO</strong>: Remove implementation notes.</t>
          <t>There is no implicit ordering or hierarchy to room versions. Future room versions, such as an <tt>I.2</tt>,
can choose to build upon <tt>I.1</tt>'s algorithms or start completely from scratch if they prefer.</t>
          <t>A room version has the following algorithms defined:</t>
          <ul spacing="normal">
            <li>Event authorization - Rules which govern when events are accepted, rejected, or soft-failed
by a server. For <tt>I.1</tt>, this is <xref target="int-auth-rules"/>.</li>
            <li>Redaction - Description of which fields to keep on an event during redaction. Redaction is
used by the signing and hash algorithms, meaning they need to be consistent across implementations.
For <tt>I.1</tt>, this is <xref target="int-redactions"/>.</li>
            <li>Event format - Which fields are expected to be present on an event, and the schema for each. For
<tt>I.1</tt>, this is <xref target="int-pdu"/>.</li>
            <li>Canonical JSON - Specific details about how to canonicalize an event as JSON. This is used
by the signing algorithm and must be consistent between implementations. For <tt>I.1</tt>, this is
<xref target="int-canonical-json"/>.</li>
            <li>Hub selection - Rules around picking the hub server and transferring to a new hub. For <tt>I.1</tt>,
this is <xref target="int-hub-selection"/>.</li>
            <li>Identifier grammar - All identifiers (room IDs, user IDs, event IDs, etc) can change grammar
within a room version. As such, they <bcp14>SHOULD</bcp14> generally be treated as opaque as possible over a
transport. For <tt>I.1</tt>, these details are described in <xref target="int-server-names"/>, <xref target="int-room-id"/>,
<xref target="int-user-id"/>, <xref target="int-device-id"/>, and <xref target="int-pdu"/>.</li>
          </ul>
          <t>The transport between servers is decoupled from the algorithms above. For example, events are
treated as blobs with no specific format over the wire but have strict schema in the context
of a room or room version. Endpoints <bcp14>MUST</bcp14> be designed with this distinction in mind.</t>
          <t>Each room version has a "stable" or "unstable" designation. Stable room versions <bcp14>SHOULD</bcp14> be used
in production by messaging providers. Unstable room versions might contain bugs or are not yet
fully specified and <bcp14>SHOULD NOT</bcp14> be used in production by messaging providers.</t>
          <t><tt>I.1</tt> shall be considered "stable".</t>
          <t><strong>Implementation note</strong>: <tt>org.matrix.i-d.ralston-mimi-linearized-matrix.02</tt> is considered "unstable".</t>
          <t><strong>TODO</strong>: Remove implementation notes.</t>
          <t><strong>TODO</strong>: Matrix considers a version as stable once accepted through FCP. When would be the
process equivalent for the IETF?</t>
          <t>The ABNF <xref target="RFC5234"/> grammar for a room version is:</t>
          <artwork><![CDATA[
room_version = 1*128room_version_char
room_version_char = DIGIT
                  / %x61-7A         ; a-z
                  / "-" / "."
]]></artwork>
          <t>Examples:</t>
          <ul spacing="normal">
            <li>
              <tt>1</tt></li>
            <li>
              <tt>I.1</tt></li>
            <li>
              <tt>org.example.my-room-version</tt></li>
          </ul>
          <t>Room versions not formally specified <bcp14>SHOULD</bcp14> be prefixed using reverse domain name notation,
creating a sort of namespace. <tt>org.example.my-room-version</tt> is an example of this.</t>
        </section>
      </section>
      <section anchor="int-user-id">
        <name>Users</name>
        <t>As described by <xref target="I-D.ralston-mimi-terminology"/>, a user is typically a human which operates
a client. Each user has a distinct user ID.</t>
        <t>The ABNF <xref target="RFC5234"/> grammar for a user ID is:</t>
        <artwork><![CDATA[
user_id = "@" user_id_localpart ":" server_name
user_id_localpart = 1*user_id_char
user_id_char = DIGIT
             / %x61-7A                   ; a-z
             / "-" / "." / "="
             / "_" / "/" / "+"
]]></artwork>
        <t><tt>server_name</tt> is inherited from <xref target="int-server-names"/>.</t>
        <t><tt>user_id</tt> <bcp14>MUST NOT</bcp14> exceed 255 characters and <bcp14>MUST</bcp14> be treated as case sensitive.</t>
        <t>Examples:</t>
        <ul spacing="normal">
          <li>
            <tt>@alice:example.org</tt></li>
          <li>
            <tt>@watch/for/slashes:example.org</tt></li>
        </ul>
        <t><tt>user_id_localpart</tt> <bcp14>SHOULD</bcp14> be human-readable and notably <bcp14>MUST NOT</bcp14> contain uppercase letters.</t>
        <t><tt>server_name</tt> denotes the domain name (<xref target="int-server-names"/>) which allocated the ID, or would allocate
the ID if the user doesn't exist yet.</t>
        <t>Identity systems and messaging providers <bcp14>SHOULD NOT</bcp14> use a phone number in a localpart. Using a phone
number would mean that when a human operator's changes their phone number then they'd lose access to
their existing chats and potentially gain access to any chats the new number is participating in.
Providers which use phone numbers <bcp14>SHOULD</bcp14> ensure the new user ID is not in chats belonging to a different
logical user. To prevent this case, a GUID (scoped to the allocating server) or an account ID is
recommended as a localpart, allowing users to change their phone number without losing chats.</t>
        <t>This document does not define how a user ID is acquired. It is expected that an identity specification
under MIMI will handle resolving email addresses, phone numbers, names, and other common queries
to user IDs.</t>
        <t>User IDs are sometimes informally referenced as "MXIDs", short for "Matrix User IDs".</t>
      </section>
      <section anchor="int-device-id">
        <name>Devices</name>
        <t>Each user can have zero or more devices/active clients. These devices are intended to be members
of the MLS group and thus have their own key package material associated with them.</t>
        <t>Because device IDs are used as "key versions" in a key ID (<xref target="int-signing"/>), they have a compatible
ABNF <xref target="RFC5234"/> grammar:</t>
        <artwork><![CDATA[
device_id = 1*key_version_char
device_id_char = ALPHA / DIGIT / "_"
]]></artwork>
      </section>
      <section anchor="int-pdu">
        <name>Events</name>
        <t>All data exchanged over Linearized Matrix is expressed as an "event". Each client action
(such as sending a message) correlates with exactly one event. All events have a <tt>type</tt>
to distinguish them, and use reverse domain name notation to namespace custom events
(for example, <tt>org.example.appname.eventname</tt>).</t>
        <t>Event types using <tt>m.</tt> as a prefix <bcp14>MUST</bcp14> only be used by the protocol.</t>
        <t>When events are traversing a transport to another server they are referred to as a
<strong>Persistent Data Unit</strong> or <strong>PDU</strong>. Structurally, an event and PDU are the same.</t>
        <t>An event has the following minimum fields:</t>
        <ul spacing="normal">
          <li>
            <tt>room_id</tt> (string; required) - The room ID for where the event is being sent. This <bcp14>MUST</bcp14> be
a valid room ID (<xref target="int-room-id"/>).</li>
          <li>
            <tt>type</tt> (string; required) - A UTF-8 <xref target="RFC3629"/> string to distinguish different data types
being carried by events. Event types are case sensitive. This <bcp14>MUST NOT</bcp14> exceed 255 characters.</li>
          <li>
            <t><tt>state_key</tt> (string; optional) - A UTF-8 <xref target="RFC3629"/> string to further distinguish an event
as a state event (see <xref target="int-state-events"/>). Can be an empty string. This <bcp14>MUST NOT</bcp14> exceed 255
characters.  </t>
            <t>
Each event type specifies its own state key requirements. For <tt>m.room.member</tt> (<xref target="int-ev-member"/>),
the state key is the user ID (<xref target="int-user-id"/>) for which the membership applies to. For
<tt>m.room.join_rules</tt> (<xref target="int-ev-join-rules"/>), this is an empty string. For a custom event type
this may be an opaque string such as a UUID or randomly generated string.</t>
          </li>
          <li>
            <tt>sender</tt> (string; required) - The user ID which is sending this event. This <bcp14>MUST</bcp14> be a valid
user ID (<xref target="int-user-id"/>).</li>
          <li>
            <tt>origin_server_ts</tt> (64-bit integer; required) - The milliseconds since the unix epoch for when this
event was created.</li>
          <li>
            <t><tt>hub_server</tt> (string; optional) - When a hub server is converting an LPDU (<xref target="int-lpdu"/>) to a
formal event, it <bcp14>MUST</bcp14> specify its own server name (<xref target="int-server-names"/>) here. The value <bcp14>MUST</bcp14> be
a valid server name.  </t>
            <t>
To support interconnection with non-linearized Matrix, as discussed in <xref target="int-intro"/>, events
created outside of a hub server <bcp14>MUST NOT</bcp14> populate this field.</t>
          </li>
          <li>
            <tt>content</tt> (object; required) - The event content. The specific schema depends on the event
type. Clients and servers processing an event <bcp14>MUST NOT</bcp14> assume the <tt>content</tt> is safe or
accurately represented. Malicious clients and servers are able to send payloads which don't
comply with a given schema, which may cause unexpected behaviour on the receiving side.
For example, a field marked as "required" might be missing.</li>
          <li>
            <t><tt>hashes</tt> (object; required) - The content hashes (<xref target="int-content-hashes"/>) for the event. There is
a special <tt>lpdu</tt> key to contain the LPDU (partial PDU schema; see <xref target="int-lpdu"/>) hashes, which is
itself keyed by hash algorithm and has the encoded hash as the value. The <tt>hashes</tt> object, outside
of <tt>lpdu</tt>, similarly is keyed by hash algorithm with encoded hash values.  </t>
            <t>
Events which specify a <tt>hub_server</tt> <bcp14>MUST</bcp14> additionally contain an <tt>lpdu</tt> hash. All other events <bcp14>MUST
NOT</bcp14> contain <tt>lpdu</tt> hashes. This is to support interconnection with non-linearized Matrix, as discussed
in <xref target="int-intro"/>.</t>
          </li>
          <li>
            <tt>signatures</tt> (object; required) - Keyed first by domain name then by key ID, the signatures for
the event.</li>
          <li>
            <tt>auth_events</tt> (array of strings; required) - The event IDs which prove the sender is able to
send this event in the room. Which specific events are put here are defined by the auth events
selection algorithm (<xref target="int-auth-selection"/>).</li>
          <li>
            <tt>prev_events</tt> (array of strings; required) - This field is to support interconnection with
non-linearized Matrix, discussed in <xref target="int-intro"/>. Events which specify a <tt>hub_server</tt> are expected
to have exactly 1 entry in this array, while other events <bcp14>MAY</bcp14> have 1 or more entries.</li>
        </ul>
        <t>Note that an event ID is not specified on the schema. Event IDs are calculated to ensure accuracy
and consistency between servers. To determine the ID for an event, calculate the reference hash
(<xref target="int-reference-hashes"/>) then encode it using URL-safe Unpadded Base64 (<xref target="int-unpadded-base64"/>)
and prefix that with the event ID sigil, <tt>$</tt>. For example, <tt>$nKHVqt3iyLA_HEE8lT1yUaaVjjBRR-fAqpN4t7opadc</tt>.</t>
        <t>Using a reference hash in the event ID prevents other servers from changing what that event ID represents.
If an event ID was just a UUID (or similar), any server along the send or receive path could swap the
actual event payload out for a different event. The hashes and signatures in this case do nothing to
protect the actual event, as a malicious server can simply generate legal hashes/signatures as part of
their modification. If we add a namespace condition where the event ID <em>must</em> reference the same server
name as the <tt>sender</tt> (<tt>$uuid:example.org</tt>) then the sending server is free to re-assign the event ID
to a different payload during the sending of that event, though all other servers along the send/receive
path cannot change the event. This is particularly problematic if the event's sender is the hub for
the room: the hub can send one copy of an event to half the room, and a very different copy to the other
half while still maintaining the same event ID for both halves. To fix this, a hash of the event itself
would need to become part of the event ID such that any modification or reassignment of the event ID
is made obvious to receipient servers. This could be a tuple of <tt>(uuid, hash)</tt>, though for simplicity
this document uses just the reference hash on its own.</t>
        <t>With event IDs containing hashes of the events it's theoretically possible for a sufficiently motivated
person to build a database of event IDs. With that database, they could eventually determine enough
information to identify parts of the event payload itself. There is not enough anchoring information
on an event (or sent over the transport) for this to be efficient or effective, however.</t>
        <t>The ABNF <xref target="RFC5234"/> for an event ID is:</t>
        <artwork><![CDATA[
event_id = "$" reference_hash
reference_hash = 1*urlsafe_unpadded_base64_char
urlsafe_unpadded_base64_char = ALPHA / DIGIT / "-" / "_"
]]></artwork>
        <t>If both the sender and receiver are implementing the algorithms correctly, the event ID will be
the same. When different, the receiver will have issues accepting the event (none of the <tt>auth_events</tt>
will make sense, for example). The sender and receiver will need to review that their implementation
matches the specification in this case.</t>
        <t>Events are treated as JSON <xref target="RFC8259"/> within the protocol, but can be encoded and represented by
any binary-compatible format. Additional overhead may be introduced when converting between formats,
however.</t>
        <t>An example event is:</t>
        <sourcecode type="json"><![CDATA[
{
  "room_id": "!abc:example.org",
  "type": "m.room.member",
  "state_key": "@alice:first.example.org",
  "sender": "@bob:second.example.org",
  "origin_server_ts": 1681340188825,
  "hub_server": "first.example.org",
  "content": {
    "membership": "invite"
  },
  "hashes": {
    "lpdu": {
      "sha256": "<unpadded base64>"
    },
    "sha256": "<unpadded base64>"
  },
  "signatures": {
    "first.example.org": {
      "ed25519:1": "<unpadded base64 signature covering whole event>"
    },
    "second.example.org": {
      "ed25519:1": "<unpadded base64 signature covering LPDU>"
    }
  },
  "auth_events": ["$first", "$second"],
  "prev_events": ["$parent"]
}
]]></sourcecode>
        <t>An event/PDU <bcp14>MUST NOT</bcp14> exceed 65536 bytes when formatted using Canonical JSON (<xref target="int-canonical-json"/>).
Note that this includes all <tt>signatures</tt> on the event.</t>
        <t>Fields have no size limit unless specified above, other than the maximum 65536 bytes for the whole
event.</t>
        <section anchor="int-lpdu">
          <name>Linearized PDU</name>
          <t>All events generated by participant servers are routed through the hub, but the participant servers
themselves are unable to populate fields like <tt>prev_events</tt> because they can't guarantee order and
those fields contribute to the event ID, signatures, and overall validity. To fix this, participant
servers send the hub server a "Linearized PDU" or "LPDU" which does not include the fields they cannot
set while still ensuring integrity of the event contents themselves.</t>
          <t>The participant server <bcp14>MUST NOT</bcp14> populate the following fields on events (LPDUs) they are sending to
the hub:</t>
          <ul spacing="normal">
            <li>
              <tt>auth_events</tt> - the participant cannot reliably determine what allows it to send the event.</li>
            <li>
              <tt>prev_events</tt> - the participant cannot reliably know what event precedes theirs.</li>
            <li>
              <tt>hashes</tt> (except <tt>hashes.lpdu</tt>) - top-level hashes cover the above two fields.</li>
          </ul>
          <t>The participant server <bcp14>MUST</bcp14> populate the <tt>hashes.lpdu</tt> object, covering a content hash
(<xref target="int-content-hashes"/>) of the partial event, giving authenticity to the sender's contents. The
participant server additionally signs this partial event before sending it to the hub.</t>
          <t>The participant server will receive an echo of the fully-formed event from the hub once appended
to the room.</t>
        </section>
        <section anchor="int-state-events">
          <name>State Events</name>
          <t>State events track metadata for the room, such as name, topic, and members. State is keyed by a
tuple of <tt>type</tt> and <tt>state_key</tt>. The state "at" an event is the set of state events which have
the most recent (in terms of event ordering, not timestamp) state tuple.</t>
          <t>For example, consider the following (simplified) room history:</t>
          <sourcecode type="json"><![CDATA[
[
   /* in all events, irrelevant fields are not shown for brevity */

   /* 0 */ {
      "type": "m.room.create", "state_key": ""
   },

   /* 1 */ {
      "type": "m.room.member", "state_key": "@alice:example.org"
   },

   /* 2 */ {
      "type": "m.room.encrypted"
   },

   /* 3 */ {
      "type": "m.room.member", "state_key": "@bob:example.org"
   },

   /* 4 */ {
      "type": "m.room.member", "state_key": "@alice:example.org"
   }
]
]]></sourcecode>
          <t>The state at index 2 consists of Alice's <tt>m.room.member</tt> event (<xref target="int-ev-member"/>) and the <tt>m.room.create</tt>
event (<xref target="int-ev-create"/>) from the room. The <tt>m.room.encrypted</tt> event itself is not a state event
and therefore does not get appended to the state "at" any particular event.</t>
          <t>The state at index 4 would have Alice's new <tt>m.room.member</tt> event, Bob's <tt>m.room.member</tt> event, and the
<tt>m.room.create</tt> event from before. Alice's old membership event is overridden due to having the same
<tt>type</tt> and <tt>state_key</tt> as the previous event. Note however that the state at index 3 still contains
the older membership event, as the new event happens later with respect to event ordering.</t>
          <t>"Current state" is the state at the most recent event in the room. Calculating the state at a given
event is needed for the authorization rules (<xref target="int-auth-rules"/>) and event visibility (<xref target="int-calc-event-visibility"/>)
algorithms. Clients additionally need to know current state to show accurate room names, topics,
avatars, etc.</t>
          <section anchor="int-stripped-state">
            <name>Stripped State</name>
            <t>Stripped state event are extremely simplified state events to provide context to a user for an invite
(<xref target="int-transport-invites"/>) or knock (<xref target="int-transport-knocks"/>). Servers and clients have no ability
to verify the events outside of the context for a room, so all such fields are removed. Servers and
clients <bcp14>MUST NOT</bcp14> rely on the events being accurate because they cannot independently verify them.</t>
            <t>When generating stripped state for an invite or knock, the following events <bcp14>SHOULD</bcp14> be included
if present in the current room state itself:</t>
            <ul spacing="normal">
              <li>
                <tt>m.room.create</tt> (<xref target="int-ev-create"/>)</li>
              <li>
                <tt>m.room.name</tt> (<strong>TODO</strong>: Link)</li>
              <li>
                <tt>m.room.avatar</tt> (<strong>TODO</strong>: Link)</li>
              <li>
                <tt>m.room.topic</tt> (<strong>TODO</strong>: Link)</li>
              <li>
                <tt>m.room.join_rules</tt> (<xref target="int-ev-join-rules"/>)</li>
              <li>
                <tt>m.room.canonical_alias</tt> (<strong>TODO</strong>: Link)</li>
            </ul>
            <t>Servers <bcp14>MAY</bcp14> include other event types/state keys. The above set gives users enough context to determine
if they'd like to knock/join the room, as features such as the name and avatar are generally key pieces
of information for a user.</t>
            <t>Stripped state events <bcp14>MUST</bcp14> only have <tt>sender</tt>, <tt>type</tt>, <tt>state_key</tt>, and <tt>content</tt> from the event
schema (<xref target="int-pdu"/>).</t>
            <t>Example:</t>
            <sourcecode type="json"><![CDATA[
{
   "type": "m.room.create",
   "sender": "@alice:example.org",
   "state_key": "",
   "content": {
      "room_version": "I.1"
   }
}
]]></sourcecode>
          </section>
        </section>
        <section anchor="event-types">
          <name>Event Types</name>
          <t>Linearized Matrix defines the following event types. The section headers are the event <tt>type</tt>.</t>
          <section anchor="int-ev-create">
            <name><tt>m.room.create</tt></name>
            <t>The very first event in the room. It <bcp14>MUST NOT</bcp14> have any <tt>auth_events</tt> or <tt>prev_events</tt>, and the
domain of the <tt>sender</tt> <bcp14>MUST</bcp14> be the same as the domain in the <tt>room_id</tt>. The <tt>state_key</tt> <bcp14>MUST</bcp14>
be an empty string.</t>
            <t>The <tt>content</tt> for a create event <bcp14>MUST</bcp14> have at least a <tt>room_version</tt> field to denote what set
of algorithms the room is using.</t>
            <t>These conditions are checked as part of the event authorization rules (<xref target="int-auth-rules"/>).</t>
          </section>
          <section anchor="int-ev-join-rules">
            <name><tt>m.room.join_rules</tt></name>
            <t>Defines whether users can join without an invite and other similar conditions. The <tt>state_key</tt>
              <bcp14>MUST</bcp14> be an empty string. Any other state key, including lack thereof, serve no meaning and
are treated as though they were a custom event.</t>
            <t>The <tt>content</tt> for a join rules event <bcp14>MUST</bcp14> have at least a <tt>join_rule</tt> field to denote the
join policy for the room. Allowable values are:</t>
            <ul spacing="normal">
              <li>
                <tt>public</tt> - anyone can join without an invite.</li>
              <li>
                <tt>knock</tt> - users must receive an invite to join, and can request an invite (knock) too.</li>
              <li>
                <tt>invite</tt> - users must receive an invite to join.</li>
            </ul>
            <t><strong>TODO</strong>: Describe <tt>restricted</tt> (and <tt>knock_restricted</tt>) rooms?</t>
            <t><strong>TODO</strong>: What's the default?</t>
          </section>
          <section anchor="int-ev-member">
            <name><tt>m.room.member</tt></name>
            <t>Defines the membership for a user in the room. If the user does not have a membership event then
they are presumed to be in the <tt>leave</tt> state.</t>
            <t>The <tt>state_key</tt> <bcp14>MUST</bcp14> be a non-empty string denotating the user ID the membership is affecting.</t>
            <t>The <tt>content</tt> for a membership event <bcp14>MUST</bcp14> have at least a <tt>membership</tt> field to denote the
membership state for the user. Allowable values are:</t>
            <ul spacing="normal">
              <li>
                <tt>leave</tt> - not participating in the room. If the <tt>state_key</tt> and <tt>sender</tt> do not match, this was
a kick rather than voluntary leave.</li>
              <li>
                <tt>join</tt> - participating in the room.</li>
              <li>
                <tt>knock</tt> - requesting an invite to the room.</li>
              <li>
                <tt>invite</tt> - invited to participate in the room.</li>
              <li>
                <tt>ban</tt> - implies kicked/not participating. Cannot be invited or join the room without being
unbanned first (moderator sends a kick, essentially).</li>
            </ul>
            <t>These conditions are checked as part of the event authorization rules (<xref target="int-auth-rules"/>),
as are the rules for moving between membership states.</t>
            <t>The <tt>content</tt> for a membership event <bcp14>MAY</bcp14> additionally have a <tt>reason</tt> field containing a human-readable
(and usually human-supplied) description for why the membership change happened. For example, the reason
why a user was kicked/banned or why they are requesting an invite by knocking.</t>
          </section>
          <section anchor="int-ev-power-levels">
            <name><tt>m.room.power_levels</tt></name>
            <t>Defines what given users can and can't do, as well as which event types they are able to send.
The enforcement of these power levels is determined by the event authorization rules (<xref target="int-auth-rules"/>).</t>
            <t>The <tt>state_key</tt> <bcp14>MUST</bcp14> be an empty string.</t>
            <t>The <tt>content</tt> for a power levels event <bcp14>SHOULD</bcp14> have at least the following:</t>
            <ul spacing="normal">
              <li>
                <tt>ban</tt> (integer) - the level required to ban a user. Defaults to <tt>50</tt> if unspecified.</li>
              <li>
                <tt>kick</tt> (integer) - the level required to kick a user. Defaults to <tt>50</tt> if unspecified.</li>
              <li>
                <tt>invite</tt> (integer) - the level required to invite a user. Defaults to <tt>0</tt> if unspecified.</li>
              <li>
                <tt>redact</tt> (integer) - the level required to redact an event sent by another user. Defaults
to <tt>50</tt> if unspecified.</li>
              <li>
                <tt>events</tt> (map) - keyed by event type string, the level required to send that event type to
the room. Defaults to an empty map if unspecified.</li>
              <li>
                <tt>events_default</tt> (integer) - the level required to send events in the room. Overridden by
the <tt>events</tt> map. Defaults to <tt>0</tt> if unspecified.</li>
              <li>
                <tt>state_default</tt> (integer) - the level required to send state events in the room. Overridden
by the <tt>events</tt> map. Defaults to <tt>50</tt> if unspecified.</li>
              <li>
                <tt>users</tt> (map) - keyed by user ID, the level of that user. Defaults to an empty map if
unspecified.</li>
              <li>
                <tt>users_default</tt> (integer) - the level for users. Overridden by the <tt>users</tt> map. Defaults to
<tt>0</tt> if unspecified.</li>
            </ul>
            <t><strong>TODO</strong>: Include notifications for at-room here too?</t>
            <t>Note that if no power levels event is specified in the room then the room creator (<tt>sender</tt> of
the <tt>m.room.create</tt> state event) has a default power level of 100.</t>
            <t>These conditions are checked as part of the event authorization rules (<xref target="int-auth-rules"/>).</t>
          </section>
          <section anchor="mroomhistoryvisibility">
            <name><tt>m.room.history_visibility</tt></name>
            <t><strong>TODO</strong>: Describe.</t>
            <section anchor="int-calc-event-visibility">
              <name>Calculating Event Visibility</name>
              <t><strong>TODO</strong>: Describe. (when can a server see an event?). Mention that <tt>m.mls.commit</tt> is exempt.</t>
              <t><strong>TODO</strong>: This section feels like it's in the wrong place. Bring it closer to on-receive-event sections.</t>
            </section>
          </section>
          <section anchor="todo-other-events">
            <name>TODO: Other events</name>
            <t><strong>TODO</strong>: <tt>m.room.name</tt>, <tt>m.room.topic</tt>, <tt>m.room.avatar</tt>, <tt>m.room.canonical_alias</tt></t>
          </section>
        </section>
      </section>
    </section>
    <section anchor="int-mls-considerations">
      <name>MLS Considerations</name>
      <t><strong>TODO</strong>: We should consider running <xref target="I-D.robert-mimi-delivery-service"/> over LM instead.
Using something like <xref target="I-D.mahy-mimi-group-chat"/> would be good for more of a client-side
representation of the LM room model.</t>
      <t>The MIMI working group is chartered to use Messaging Layer Security (MLS) <xref target="I-D.ietf-mls-protocol"/>
        <xref target="I-D.ietf-mls-architecture"/> for encryption in chats, and this document specifies no different.
Each room has a single MLS Group associated with it, both identified by the room ID (<xref target="int-room-id"/>).</t>
      <t>Rooms additionally track membership at a per-user level while MLS tracks group membership at a
per-device level. With this consideration, commits to the MLS Group <bcp14>MUST</bcp14> use <tt>PublicMessage</tt>, giving
the hub server an ability to inspect MLS group membership changes for illegal joins and leaves.</t>
      <t>Encryption can only be enabled at the time the room is created. This prevents the room having encryption
disabled or downgraded without an entirely new room being created. The exact ciphersuite and other
algorithmic details are contained in the <tt>content</tt> for the <tt>m.room.create</tt> event (<xref target="int-ev-create"/>):</t>
      <sourcecode type="json"><![CDATA[
{
   "encryption": {
      "algorithm": "m.mls.v1.dhkemx25519-aes128gcm-sha256-ed25519"
   }
}
]]></sourcecode>
      <t><tt>algorithm</tt> denotes which specific algorithm clients <bcp14>MUST</bcp14> use for sending and receiving encrypted
events in the room. If a received event is encrypted using a different algorith, it <bcp14>MUST</bcp14> be treated
as undecryptable (even if the client has sufficient key information to decrypt it).</t>
      <t><tt>m.mls.v1.</tt> as a prefix describes the behaviour for encrypted clients, with the remainder of the
algorithm string covering the exact ciphersuite. This document uses the same mandatory ciphersuite
as MLS: <tt>MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519</tt>. Thus, this is encoded as
<tt>m.mls.v1.dhkemx25519-aes128gcm-sha256-ed25519</tt>. Other ciphersuites can be represented similarly,
though are considered to be entirely new encryption algorithms for the purposes of this document.</t>
      <t>Custom or non-standard encryption algorithms are possible with this approach, however out of scope
for MIMI. If such an algorithm is used, it <bcp14>SHOULD</bcp14> be prefixed using reverse domain name notation.
For example, <tt>org.example.my-encryption</tt>.</t>
      <t>Mentioned in the introduction (<xref target="int-intro"/>), this document does not explore the details for what is
needed to interconnect Linearized Matrix and Matrix's existing room model. However, for interconnection
to be successful, extensions to MLS are needed to support decentralization. One possible extension
is "Decentralised MLS" <xref target="DMLS"/>.</t>
      <section anchor="int-mls-credentials">
        <name>Device Credentials</name>
        <t>Under Section 5.3 of <xref target="I-D.ietf-mls-protocol"/>, each MLS group member (a device, <xref target="int-device-id"/>)
has a "credential" or signing key associated with it. These are published to each client's local server
and available over federation (<xref target="int-transport-mls"/>).</t>
        <t>This document relies upon out-of-band verification and therefore uses basic credentials. The format
for the credential is:</t>
        <artwork><![CDATA[
struct {
    opaque user_id<V>;
    opaque device_id<V>;
    opaque signature_key<V>;
} BasicCredential;
]]></artwork>
        <t><tt>user_id</tt> is as described by <xref target="int-user-id"/>, and <tt>device_id</tt> is as described by <xref target="int-device-id"/>.
<tt>signature_key</tt> is from MLS.</t>
        <t>The device then constructs the following object, signs it using each of the listed <tt>keys</tt>, and publishes
it through its local server (<xref target="int-transport-devices"/>):</t>
        <sourcecode type="json"><![CDATA[
{
   "device_id": "ABCDEF",
   "user_id": "@alice:example.org",
   "algorithms": [
      "m.mls.v1.dhkemx25519-aes128gcm-sha256-ed25519"
   ],
   "keys": {
      "m.mls.v1.credential.ed25519:ABCDEF":
         "<unpadded base64 BasicCredential>"
   },
   "signatures": {
      "@alice:example.org": {
         "m.mls.v1.credential.ed25519:ABCDEF":
            "<unpadded base64 signature>"
      }
   }
}
]]></sourcecode>
        <t><tt>device_id</tt> is the client's device ID (<xref target="int-device-id"/>). <tt>user_id</tt> is the user ID (<xref target="int-user-id"/>)
to which the device ID belongs. <tt>algorithms</tt> are the encryption algorithms the device supports, and
<bcp14>SHOULD</bcp14> contain at least <tt>m.mls.v1.dhkemx25519-aes128gcm-sha256-ed25519</tt>.</t>
        <t>When a device supports <tt>m.mls.v1.dhkemx25519-aes128gcm-sha256-ed25519</tt>, it <bcp14>MUST</bcp14> specify its basic
credential with the <tt>m.mls.v1.credential.ed25519</tt> key algorithm.</t>
        <t><tt>keys</tt> is an object containing each algorithm-specific key (or keys) for the device. The fields for
the object form a key ID, with the device ID representing the "key version", as per <xref target="int-signing"/>.</t>
        <t>All top-level fields in the object above <bcp14>MUST</bcp14> be supplied.</t>
        <t>For each of the device's <tt>keys</tt>, a valid signature <bcp14>MUST</bcp14> be produced. If there is a missing signature
from any of the keys, or from the <tt>user_id</tt>, the device information is considered invalid. Invalid
devices <bcp14>MUST NOT</bcp14> be members of the MLS group, and are removed if already members prior to the device
information becoming invalid.</t>
      </section>
      <section anchor="group-creation">
        <name>Group Creation</name>
        <t>After the <tt>m.room.create</tt> event and other initial state events for the room are sent, the room creator
<bcp14>MUST</bcp14> establish the appropriate MLS group. This is sent as an <tt>m.mls.commit</tt> event (<xref target="int-ev-mls-commit"/>).
Afterwards, the remaining devices are added as normal (<xref target="int-mls-add-remove"/>).</t>
        <t>Ideally, the <tt>m.room.create</tt> event would also contain the initial public group state, however doing
so would mean either tracking an independent MLS group ID or allowing the client to specify the room
ID. While servers <bcp14>MAY</bcp14> allow the client to specify the room ID, servers usually have better context
for which localparts (see <xref target="int-room-id"/>) are already claimed by other rooms. Having independent
group IDs and room IDs can lead to confusion and a similar sort of namespacing issue (a room creator
can create a conflicting group ID). Instead, the server (usually) creates the room on behalf of the
client, allowing the client to then send the initial public group state to the room for other MLS
members.</t>
      </section>
      <section anchor="int-mls-add-remove">
        <name>Updating Group State</name>
        <t>This document does not provide a way to send proposals to the MLS group, meaning all commits <bcp14>MUST</bcp14> only
contain proposals which are sent by the same member (see <xref section="12" sectionFormat="of" target="I-D.ietf-mls-protocol"/>).</t>
        <t>All commits are encoded as <tt>m.mls.commit</tt> events (<xref target="int-ev-mls-commit"/>) and are sent to the room.
These commits are additionally encoded using <tt>PublicMessage</tt>, giving servers visibility on the contents
of the commits. Upon receiving the event (see <xref target="int-receiving-events"/>), the hub server <bcp14>MUST</bcp14> additionally
validate that any membership changes match what is possible with the room membership:</t>
        <ul spacing="normal">
          <li>Devices can only be added to the group if they belong to a user which is joined to the room, or if the
room is "world readable" (<xref target="int-calc-event-visibility"/>). It is generally not enough to be invited,
knocking, etc on the room - the user ID must usually be in the <tt>join</tt> state.</li>
          <li>
            <t>Devices can be removed in two ways:
            </t>
            <ul spacing="normal">
              <li>A device can remove another device if they both belong to the same user ID.</li>
              <li>A device can be removed by anyone if the user ID to which it belongs is no longer in the <tt>join</tt> state.
This condition is required to satisy a case in MLS where a device cannot self-remove itself from
the group.</li>
            </ul>
          </li>
        </ul>
        <t>If this validation fails, the hub server <bcp14>MUST</bcp14> reject the request if it's shaped as an LPDU (<xref target="int-lpdu"/>)
and soft-fail the event if it's a PDU (<xref target="int-pdu"/>).</t>
        <t>Welcome messages are sent to devices over to-device messaging (<xref target="int-transport-to-device"/>). The <tt>message_type</tt>
for the message is <tt>m.room.encrypted</tt> [<strong>TODO</strong>: Rename to avoid confusion with room event?] and <tt>message</tt>
of:</t>
        <sourcecode type="json"><![CDATA[
{
   "algorithm": "m.mls.v1.welcome.[ciphersuite]",
   "ciphertext": "<unpadded base64 encoded welcome message>",
   "commit_event_id": "<event ID of the m.mls.commit event>"
}
]]></sourcecode>
        <t><tt>algorithm</tt> is the ciphersuite, <tt>dhkemx25519-aes128gcm-sha256-ed25519</tt>, prefixed with <tt>m.mls.v1.welcome</tt>.</t>
        <t>The remaining fields are as described in the example. See <xref target="int-unpadded-base64"/> for "unpadded base64".</t>
        <t>All fields <bcp14>MUST</bcp14> be supplied. Note that the sender's user ID and device ID are made available over the
to-device messaging endpoints (<xref target="int-transport-to-device"/>).</t>
        <t>In all cases, a device remembers the event ID (either from the <tt>m.mls.commit</tt> event or <tt>commit_event_id</tt>
from a to-device message) after decryption to associate it with the MLS epoch. The device can then do
a reverse lookup of epoch to event ID to MLS group state. Note that a client <em>always</em> has access to
<tt>m.mls.commit</tt> events, even when hidden by history visibility (<xref target="int-calc-event-visibility"/>).</t>
        <t><strong>TODO</strong>: Is it correct to say all commits are visible as "shared"?</t>
        <t><strong>TODO</strong>: We may need to store the group state in the media repo if it gets to be too big, or otherwise
allow oversized events.</t>
        <t><strong>TODO</strong>: The server also likely needs to prevent devices being added to the group which don't support
the ciphersuite/algorithm.</t>
      </section>
      <section anchor="int-mls-key-packages">
        <name>Key Packages</name>
        <t>Clients "claim" another device's key package through their server (<xref target="int-transport-key-claim"/>). Clients
will typically generate several key packages and upload them to their server, making them available even
if the client goes offline.</t>
        <t>The algorithm for a key package is <tt>m.mls.v1.key_package.dhkemx25519-aes128gcm-sha256-ed25519</tt> and is
combined with a device-generated key version, forming a key ID described by <xref target="int-signing"/>. The key
version <bcp14>SHOULD</bcp14> be generated based upon the key package itself rather than using an unrelated string,
such as a hash or the public key of the key package.</t>
      </section>
      <section anchor="room-event-types">
        <name>Room Event Types</name>
        <t><strong>TODO</strong>: Should these be defined with the other event types rather than here?</t>
        <t>This document describes the following event types for use with MLS-encrypted rooms. The section headers
are the event <tt>type</tt>. See <xref target="int-pdu"/> for more information on events.</t>
        <t>These event types are non-state events, also called "room events".</t>
        <section anchor="int-ev-mls-commit">
          <name><tt>m.mls.commit</tt></name>
          <t>Represents an MLS commit, which may be rejected by the hub server.</t>
          <t><tt>content</tt> for the event <bcp14>MUST</bcp14> contain at least the following example:</t>
          <sourcecode type="json"><![CDATA[
{
   "message": "<unpadded base64 encoded PublicMessage>",
   "public_group_state": "<unpadded base64 encoded public group state>"
}
]]></sourcecode>
          <t>As mentioned, <tt>message</tt> is a <tt>PublicMessage</tt> from MLS. <tt>public_group_state</tt> is to enable external
joins.</t>
          <t>An optional field, <tt>prev_commit_event_id</tt>, <bcp14>SHOULD</bcp14> be specified when a parent commit exists. This is
to enable clients to find the commit they have keys for upon joining the room, as the most recent one
may not be decryptable to them. The client can then work forwards from where they can decrypt the
message.</t>
          <t><strong>TODO</strong>: Should we use the <tt>RatchetTree</tt> extension? It might make the group state massive...</t>
          <t><strong>TODO</strong>: Which fields from this need to be protected by <xref target="int-redactions"/>?</t>
        </section>
        <section anchor="int-ev-encrypted">
          <name><tt>m.room.encrypted</tt></name>
          <t>Represents an encrypted MLS application message. The sender first encrypts the message per the content
format then <bcp14>MUST</bcp14> send an event with <tt>content</tt> matching:</t>
          <sourcecode type="json"><![CDATA[
{
   "algorithm": "m.mls.v1.[ciphersuite]",
   "ciphertext": "<unpadded base64 encoded MLS ciphertext>",
   "commit_event_id": "<event ID of applicable m.mls.commit event>"
}
]]></sourcecode>
          <t>Within this document, <tt>algorithm</tt> will be <tt>m.mls.v1.dhkemx25519-aes128gcm-sha256-ed25519</tt>. The other
fields are as described in the example.</t>
          <t>Clients <bcp14>SHOULD</bcp14> treat <tt>m.room.encrypted</tt> events which are improperly structured as undecryptable events.</t>
          <t><strong>TODO</strong>: Which fields from this need to be protected by <xref target="int-redactions"/>?</t>
        </section>
      </section>
    </section>
    <section anchor="processing-events">
      <name>Processing Events</name>
      <t>An event has several authenticity properties:</t>
      <ul spacing="normal">
        <li>Content hashes (<xref target="int-content-hashes"/>) to cover the LPDU (<xref target="int-lpdu"/>) and event (<xref target="int-pdu"/>)
contents.</li>
        <li>Reference hashes (<xref target="int-reference-hashes"/>) which double as the event ID, covering the
redacted event.</li>
        <li>Signatures from the direct senders (server name of the <tt>sender</tt> and the <tt>hub_server</tt> if
present), ensuring the entities did actually produce that event.</li>
      </ul>
      <t><strong>TODO</strong>: Does the hub's signature actually guard anything?</t>
      <t>These properties are validated throughout this document. Each property has different behaviour
when violated. For example, a difference in content hash ultimately causes the event to be
stored as a redacted copy.</t>
      <section anchor="int-receiving-events">
        <name>Receiving Events/PDUs</name>
        <t><strong>TODO</strong>: This section conflates sending and receiving a bit more than it should. Split sending
out to its own section.</t>
        <t>When a hub receives an LPDU from a participant it <bcp14>MUST</bcp14> add the missing fields to create a fully
formed PDU then <bcp14>MUST</bcp14> send that PDU back out to all participants, including the original sender.</t>
        <t>A server is considered to have "received" an event when it does not recognize the event ID. This
may be because the event has not yet been persisted, or the server is not persisting anything (in
the case of a participant server). This includes when the server asks another server for an event
it might be missing.</t>
        <t>When a server (hub or participant) receives an event, it <bcp14>MUST</bcp14>:</t>
        <ol spacing="normal" type="1"><li>Verify the event matches the schema for the room version (<xref target="int-pdu"/>), without considering
type-specific schemas applied to <tt>content</tt>. If an event fails to meet this requirement, it is
dropped/ignored.</li>
          <li>Ensure the required signatures are present and that they are valid (<xref target="int-checking-signatures"/>).
If the event has a <tt>hub_server</tt> field, the event <bcp14>MUST</bcp14> be signed by that server. The event
<bcp14>MUST</bcp14> also be signed by the server implied by the <tt>sender</tt>, noting that this will be an LPDU
if <tt>hub_server</tt> is present. All other signatures <bcp14>MUST NOT</bcp14> be considered for signature
validation, regardless of their individual validity. If the event fails to meet this
requirement, it is dropped/ignored.</li>
          <li>Ensure the event has a valid content hashes (<xref target="int-content-hashes"/>). If the event has a
<tt>hub_server</tt> field, it <bcp14>MUST</bcp14> have a content hash which covers the LPDU. If either the LPDU
or PDU content hash doesn't match what the receiving server calculations, the event is
redacted before further processing. The server will ultimately persist the redacted copy.</li>
        </ol>
        <t>Additionally, a hub server <bcp14>MUST</bcp14> complete the following checks. Participant servers <bcp14>SHOULD</bcp14>
also perform the following checks to validate that the hub server is acting in a compliant
manner. If the hub is not acting appropriately (for example, by sending the participant an
event which never should have been accepted), the participant server <bcp14>MAY</bcp14> choose to warn its
local users that the room history may have been tampered with.</t>
        <ol spacing="normal" type="1"><li>The constraints described by <xref target="int-mls-add-remove"/> validated, if the room is encrypted.</li>
        </ol>
      </section>
      <section anchor="int-auth-rules">
        <name>Authorization Rules</name>
        <t>These are the rules which govern whether an event is accepted into the room, depending on
the state events surrounding that event. A given event is checked against multiple different
sets of state.</t>
        <section anchor="int-auth-selection">
          <name>Auth Events Selection</name>
          <t>The <tt>auth_events</tt> on an event <bcp14>MUST</bcp14> consist of the following state events, with the exception
of an <tt>m.room.create</tt> event which has no <tt>auth_events</tt>.</t>
          <ol spacing="normal" type="1"><li>The <tt>m.room.create</tt> state event.</li>
            <li>The current <tt>m.room.power_levels</tt> state event, if any.</li>
            <li>The sender's current <tt>m.room.member</tt> state event, if any.</li>
            <li>
              <t>If the <tt>type</tt> is <tt>m.room.member</tt>:
              </t>
              <ol spacing="normal" type="1"><li>The target's (<tt>state_key</tt>) current <tt>m.room.member</tt> state event, if any.</li>
                <li>If <tt>content.membership</tt> is <tt>join</tt> or <tt>invite</tt>, the current <tt>m.room.join_rules</tt> state
event, if any.</li>
              </ol>
            </li>
          </ol>
          <t><strong>TODO</strong>: Talk about restricted room joins here?</t>
        </section>
        <section anchor="int-calc-power-levels">
          <name>Calculating Power Levels</name>
          <t>A requirement of the authorization rules is being able to determine the current/future "power level"
for a user. All power levels are calculated with reference to the <tt>content</tt> of an <tt>m.room.power_levels</tt>
state event (<xref target="int-ev-power-levels"/>).</t>
          <t>To calculate a user's current power level:</t>
          <ol spacing="normal" type="1"><li>If <tt>users</tt> is present, use the power level for the user ID, if present.</li>
            <li>If <tt>users</tt> is not present, or the user ID is not present in <tt>users</tt>, use <tt>users_default</tt>.</li>
            <li>If <tt>users_default</tt> is not present, use <tt>0</tt>.</li>
          </ol>
          <t>To calculate the required power level to do an action:</t>
          <ol spacing="normal" type="1"><li>If the action (<tt>kick</tt>, <tt>ban</tt>, <tt>invite</tt>, or <tt>redact</tt>) is present, use that power level.</li>
            <li>If not present, use the default for the action (<tt>50</tt> for <tt>kick</tt>, <tt>ban</tt>, and <tt>redact</tt>, <tt>0</tt>
for <tt>invite</tt>).</li>
          </ol>
          <t>To calculate the required power level to send an event:</t>
          <ol spacing="normal" type="1"><li>If <tt>events</tt> is present, use the power level for the event <tt>type</tt>, if present.</li>
            <li>
              <t>If <tt>events</tt> is not present, or the event <tt>type</tt> is not present in <tt>events</tt>:
              </t>
              <ol spacing="normal" type="1"><li>
                  <t>If <tt>state_key</tt> is present (including empty), use <tt>state_default</tt>.
                  </t>
                  <ol spacing="normal" type="1"><li>If <tt>state_default</tt> is not specified, use <tt>50</tt>.</li>
                  </ol>
                </li>
                <li>
                  <t>If <tt>state_key</tt> is not present, use <tt>events_default</tt>.
                  </t>
                  <ol spacing="normal" type="1"><li>If <tt>events_default</tt> is not specified, use <tt>0</tt>.</li>
                  </ol>
                </li>
              </ol>
            </li>
          </ol>
        </section>
        <section anchor="auth-rules-algorithm">
          <name>Auth Rules Algorithm</name>
          <t>With consideration for default/calculated power levels (<xref target="int-calc-power-levels"/>), each event <bcp14>MUST</bcp14>
pass the following rules. "Current state" (and "current membership", etc) are the state of the room
<em>before</em> the event being checked is applied.</t>
          <t><strong>TODO</strong>: should we reference <tt>m.federate</tt>?</t>
          <ol spacing="normal" type="1"><li>Events must be signed (<xref target="int-checking-signatures"/>) by the server denoted by the <tt>sender</tt>
field. Note that this may be an LPDU if the <tt>hub_server</tt> is specified and not the same server.
If the event is improperly signed, reject the event.</li>
            <li>If <tt>hub_server</tt> is present on the event, the event must be signed (<xref target="int-checking-signatures"/>)
by that server. If it is improperly signed, reject the event.</li>
            <li>
              <t>If the event's <tt>type</tt> is <tt>m.room.create</tt>:  </t>
              <ol spacing="normal" type="1"><li>If it has any <tt>prev_events</tt>, reject the event.</li>
                <li>If the domain of the <tt>room_id</tt> is not the same domain as the <tt>sender</tt>, reject the event.</li>
                <li>If <tt>content.room_version</tt> is not <tt>I.1</tt>, reject the event.</li>
                <li>Otherwise, allow the event.</li>
              </ol>
            </li>
            <li>
              <t>Considering the event's <tt>auth_events</tt>:  </t>
              <t><strong>TODO</strong>: Does this check make sense for Linearized Matrix? We already removed what was #3 because
it talked about rejecting events which reference rejected events.  </t>
              <ol spacing="normal" type="1"><li>If there are duplicate entries for a given <tt>type</tt> and <tt>state_key</tt> pair, reject the event.</li>
                <li>If there are entries whose <tt>type</tt> and <tt>state_key</tt> do not match those specified by the
auth events selection algorithm (<xref target="int-auth-selection"/>), reject the event.</li>
                <li>If there is no <tt>m.room.create</tt> event among the entries, reject.</li>
              </ol>
            </li>
            <li>
              <t>If the event's <tt>type</tt> is <tt>m.room.member</tt>:  </t>
              <ol spacing="normal" type="1"><li>If there is no <tt>state_key</tt> property, or no <tt>membership</tt> in <tt>content</tt>, reject the event.</li>
                <li>
                  <t>If the event <tt>content</tt>'s <tt>membership</tt> field is <tt>join</tt>:      </t>
                  <ol spacing="normal" type="1"><li>If the previous event is an <tt>m.room.create</tt> event and the <tt>state_key</tt> is the
creator, allow the event.</li>
                    <li>If <tt>sender</tt> does not match <tt>state_key</tt>, reject the event.</li>
                    <li>If the <tt>sender</tt> is banned, reject the event.</li>
                    <li>If the <tt>join_rule</tt> for <tt>m.room.join_rules</tt> is <tt>invite</tt> or <tt>knock</tt>, then allow the event if
the current membership state is <tt>invite</tt> or <tt>join</tt>.</li>
                    <li>If the <tt>join_rule</tt> for <tt>m.room.join_rules</tt> is <tt>public</tt>, allow the event.</li>
                    <li>Otherwise, reject the event.</li>
                  </ol>
                </li>
                <li>
                  <t>If the event <tt>content</tt>'s <tt>membership</tt> field is <tt>invite</tt>:      </t>
                  <ol spacing="normal" type="1"><li>If the <tt>sender</tt>'s current membership state is not <tt>join</tt>, reject the event.</li>
                    <li>If the target user's (<tt>state_key</tt>) membership is <tt>join</tt> or <tt>ban</tt>, reject the event.</li>
                    <li>If the <tt>sender</tt>'s power level is greater than or equal to the power level needed
to send invites, allow the event.</li>
                    <li>Otherwise, reject the event.</li>
                  </ol>
                </li>
                <li>
                  <t>If the event <tt>content</tt>'s <tt>membership</tt> field is <tt>leave</tt>:      </t>
                  <ol spacing="normal" type="1"><li>If the <tt>sender</tt> matches the <tt>state_key</tt>, allow the event if and only if that user's current
membership state is <tt>knock</tt>, <tt>join</tt>, or <tt>invite</tt>.</li>
                    <li>If the <tt>sender</tt>'s current membership state is not <tt>join</tt>, reject the event.</li>
                    <li>If the target user's (<tt>state_key</tt>) current membership state is <tt>ban</tt>, and the
<tt>sender</tt>'s power level is less than the power level needed to ban other users, reject the event.</li>
                    <li>If the <tt>sender</tt>'s power level is greater than or equal to the power level needed to
kick users, and the target user's (<tt>state_key</tt>) power level is less than the <tt>sender</tt>'s,
allow the event.</li>
                    <li>Otherwise, reject the event.</li>
                  </ol>
                </li>
                <li>
                  <t>If the event <tt>content</tt>'s <tt>membership</tt> field is <tt>ban</tt>:      </t>
                  <ol spacing="normal" type="1"><li>If the <tt>sender</tt>'s current membership state is not <tt>join</tt>, reject the event.</li>
                    <li>If the <tt>sender</tt>'s power level is greater than or equal to the power level needed
to ban users, and the target user's (<tt>state_key</tt>) power level is less than the
<tt>sender</tt>'s power level, allow the event.</li>
                    <li>Otherwise, reject the event.</li>
                  </ol>
                </li>
                <li>
                  <t>If the event <tt>content</tt>'s <tt>membership</tt> field is <tt>knock</tt>:      </t>
                  <ol spacing="normal" type="1"><li>If the <tt>join_rule</tt> for <tt>m.room.join_rules</tt> is anything other than <tt>knock</tt>, reject the event.</li>
                    <li>If the <tt>sender</tt> does not match the <tt>state_key</tt>, reject the event.</li>
                    <li>If the <tt>sender</tt>'s current membership state is not <tt>ban</tt> or <tt>join</tt>, allow the event.</li>
                    <li>Otherwise, reject the event.</li>
                  </ol>
                </li>
                <li>Otherwise, the <tt>membership</tt> is unknown. reject the event.</li>
              </ol>
            </li>
            <li>If the <tt>sender</tt>'s current membership state is not <tt>join</tt>, reject the event.</li>
            <li>If the event <tt>type</tt>'s required power level to send it is greater than the <tt>sender</tt>'s power level,
reject the event.</li>
            <li>
              <t>If the event has a <tt>state_key</tt> which starts with an <tt>@</tt> and does not match the <tt>sender</tt>,
reject the event.  </t>
              <t><strong>TODO</strong>: Do we care? This is theoretically to allow for owned state events, but in practice nothing
which uses this concept makes it this far into the auth rules (membership events are validated above).</t>
            </li>
            <li>
              <t>If the event's <tt>type</tt> is <tt>m.room.power_levels</tt>:  </t>
              <ol spacing="normal" type="1"><li>If any of the fields <tt>users_default</tt>, <tt>events_default</tt>, <tt>state_default</tt>, <tt>ban</tt>, <tt>redact</tt>,
<tt>kick</tt>, or <tt>invite</tt> in <tt>content</tt> are present and not an integer, reject the event.</li>
                <li>If <tt>events</tt> in <tt>content</tt> is present and not an object with values that are integers,
reject the event.</li>
                <li>If the <tt>users</tt> in <tt>content</tt> is present and not an object with valid user IDs as keys and
integers as values, reject the event.</li>
                <li>If there is no previous <tt>m.room.power_levels</tt> event in the room, allow the event.</li>
                <li>
                  <t>For the fields <tt>users_default</tt>, <tt>events_default</tt>, <tt>state_default</tt>, <tt>ban</tt>, <tt>redact</tt>, <tt>kick</tt>,
and <tt>invite</tt>, check if they were added, changed, or removed. For each found alteration:      </t>
                  <ol spacing="normal" type="1"><li>If the current value is higher than the <tt>sender</tt>'s current power level, reject the event.</li>
                    <li>If the new value is higher than the <tt>sender</tt>'s current power level, reject the event.</li>
                  </ol>
                </li>
                <li>
                  <t>For each entry being changed in or removed from <tt>events</tt>:      </t>
                  <ol spacing="normal" type="1"><li>If the current value is higher than the <tt>sender</tt>'s current power level, reject the event.</li>
                  </ol>
                </li>
                <li>
                  <t>For each entry being added to or changed in <tt>events</tt>:      </t>
                  <ol spacing="normal" type="1"><li>If the new value is greater than the <tt>sender</tt>'s current power level, reject the event.</li>
                  </ol>
                </li>
                <li>
                  <t>For each entry being changed in or removed from <tt>users</tt>, other than the <tt>sender</tt>'s own
entry:      </t>
                  <ol spacing="normal" type="1"><li>If the current value is higher than the <tt>sender</tt>'s current power level, reject the event.</li>
                  </ol>
                </li>
                <li>
                  <t>For each entry being added to or changed in <tt>users</tt>:      </t>
                  <ol spacing="normal" type="1"><li>If the new value is greater than the <tt>sender</tt>'s current power level, reject the event.</li>
                  </ol>
                </li>
                <li>Otherwise, allow the event.</li>
              </ol>
            </li>
            <li>Otherwise, allow the event.</li>
          </ol>
          <t>There are some consequences to these rules:</t>
          <ul spacing="normal">
            <li>Unless you are already a member of the room, the only permitted operations (aside from
the initial create/join) are being able to join public rooms, accept invites to rooms,
and reject invites to rooms.</li>
            <li>To unban another user, the sender must have a power level greater than or equal to both
the kick and ban power levels, <em>and</em> greater than the target user's power level.</li>
          </ul>
          <t><strong>TODO</strong>: If we want to enforce a single hub in a room, we'd do so here with auth rules.</t>
        </section>
      </section>
    </section>
    <section anchor="int-signing">
      <name>Signing</name>
      <t>All servers, including hubs and participants, publish an ed25519 <xref target="RFC8032"/> signing key
to be used by other servers when verifying signatures. These keys can then be fetched over
the transport as needed (<xref target="int-transport-get-server-keys"/>).</t>
      <t><strong>TODO</strong>: Verify RFC reference. We might be using a slightly different ed25519 key today?
See https://hdevalence.ca/blog/2020-10-04-its-25519am</t>
      <t>Each key ID consists of an algorithm name and version. Signing keys <bcp14>MUST</bcp14> use an algorithm
of <tt>ed25519</tt> (and therefore <bcp14>MUST</bcp14> be an ed25519 key). The key version <bcp14>MUST</bcp14> be valid under
the following ABNF <xref target="RFC5234"/>:</t>
      <artwork><![CDATA[
key_version = 1*key_version_char
key_version_char = ALPHA / DIGIT / "_"
]]></artwork>
      <t>An algorithm and version combined is a "key ID", deliminated by <tt>:</tt> as per the following
ABNF <xref target="RFC5234"/>:</t>
      <artwork><![CDATA[
key_id = key_algorithm ":" key_version
key_algorithm = "ed25519"
]]></artwork>
      <t>Additional key algorithms may be supported by future documents.</t>
      <section anchor="int-signing-events">
        <name>Signing Events</name>
        <t>To sign an event:</t>
        <ol spacing="normal" type="1"><li>Redact it (<xref target="int-redactions"/>).</li>
          <li>Sign the result as an arbitrary object (<xref target="int-signing-objects"/>).</li>
        </ol>
      </section>
      <section anchor="int-signing-objects">
        <name>Signing Arbitrary Objects</name>
        <t>To sign an object:</t>
        <ol spacing="normal" type="1"><li>Remove <tt>signatures</tt> if present.</li>
          <li>Encode the result with Canonical JSON (<xref target="int-canonical-json"/>).</li>
          <li>Using the relevant ed25519 signing key (usually the server's), sign the object.</li>
          <li>Encode that signature under <tt>signatures</tt> using unpadded base64 (<xref target="int-unpadded-base64"/>).</li>
        </ol>
        <t>Note that <tt>signatures</tt> is an object with keys being the entity which did the signing and value
being the key ID to encoded signature pair. See <xref target="int-pdu"/> for details on the <tt>signatures</tt>
structure for events specifically.</t>
      </section>
      <section anchor="int-checking-signatures">
        <name>Checking Signatures</name>
        <t>If the <tt>signatures</tt> field is missing, doesn't contain the entity that is expected to have done
the signing (usually a server name), doesn't have a known key ID, or is otherwise structurally invalid
then the signature check fails.</t>
        <t>If decoding the base64 fails, the check fails.</t>
        <t>If the object is an event, redact (<xref target="int-redactions"/>) it before continuing.</t>
        <t>If removing the <tt>signatures</tt> property, canonicalizing the JSON (<xref target="int-canonical-json"/>),
and verifying the signature fails, the check fails. Note that to verify the signature the server
may need to fetch another server's key first (<xref target="int-transport-get-server-keys"/>).</t>
        <t>Otherwise, the check passes.</t>
        <t><strong>TODO</strong>: Which specific signatures are required? If a server has multiple signing keys, possibly
a combination of new and old, do we require all or some of them to sign?</t>
      </section>
    </section>
    <section anchor="int-canonical-json">
      <name>Canonical JSON</name>
      <t>When signing a JSON object, such as an event, it is important that the bytes be ordered in
the same way for everyone. Otherwise, the signatures will never match.</t>
      <t>To canonicalize a JSON object, use <xref target="RFC8785"/>.</t>
      <t><strong>TODO</strong>: Matrix currently doesn't use RFC8785, but it should (or similar).</t>
    </section>
    <section anchor="int-redactions">
      <name>Event Redactions</name>
      <t>All fields at the top level except the following are stripped from the event:</t>
      <ul spacing="normal">
        <li>
          <tt>type</tt></li>
        <li>
          <tt>room_id</tt></li>
        <li>
          <tt>sender</tt></li>
        <li>
          <tt>state_key</tt></li>
        <li>
          <tt>content</tt></li>
        <li>
          <tt>origin_server_ts</tt></li>
        <li>
          <tt>hashes</tt></li>
        <li>
          <tt>signatures</tt></li>
        <li>
          <tt>prev_events</tt></li>
        <li>
          <tt>auth_events</tt></li>
        <li>
          <tt>hub_server</tt></li>
      </ul>
      <t>Additionally, some event types retain specific fields under the event's <tt>content</tt>. All other
fields are stripped.</t>
      <ul spacing="normal">
        <li>
          <tt>m.room.create</tt> retains all fields in <tt>content</tt>.</li>
        <li>
          <tt>m.room.member</tt> retains <tt>membership</tt>.</li>
        <li>
          <tt>m.room.join_rules</tt> retains <tt>join_rule</tt>.</li>
        <li>
          <tt>m.room.power_levels</tt> retains <tt>ban</tt>, <tt>events</tt>, <tt>events_default</tt>, <tt>kick</tt>, <tt>redact</tt>, <tt>state_default</tt>,
<tt>users</tt>, <tt>users_default</tt>, and <tt>invite</tt>.</li>
        <li>
          <tt>m.room.history_visibility</tt> retains <tt>history_visibility</tt>.</li>
      </ul>
    </section>
    <section anchor="hashes">
      <name>Hashes</name>
      <t>An event is covered by two hashes: a content hash and a reference hash. The content hash covers the
unredacted event to ensure it was not modified in transit. The reference hash covers the essential
fields of the event, including content hashes, and serves as the event's ID.</t>
      <section anchor="int-content-hashes">
        <name>Content Hash Calculation</name>
        <t><strong>TODO</strong>: Describe what this protects, and why it matters.</t>
        <ol spacing="normal" type="1"><li>
            <t>Remove any existing <tt>signatures</tt> field.
            </t>
            <ol spacing="normal" type="1"><li>If calculating an LPDU's (<xref target="int-lpdu"/>) content hash, remove any existing <tt>hashes</tt> field as well.</li>
              <li>If <em>not</em> calculating an LPDU's content hash, remove any existing fields under <tt>hashes</tt> except
for <tt>lpdu</tt>.</li>
            </ol>
          </li>
          <li>Encode the object using canonical JSON.</li>
          <li>Hash the resulting bytes with SHA-256 <xref target="RFC6234"/>.</li>
          <li>Encode the hash using unpadded base64 (<xref target="int-unpadded-base64"/>).</li>
        </ol>
      </section>
      <section anchor="int-reference-hashes">
        <name>Reference Hash Calculation</name>
        <t><strong>TODO</strong>: Describe what this protects, and why it matters.</t>
        <ol spacing="normal" type="1"><li>Redact the event.</li>
          <li>Remove <tt>signatures</tt> field.</li>
          <li>Encode the object using canonical JSON.</li>
          <li>Hash the resulting bytes with SHA-256 <xref target="RFC6234"/>.</li>
          <li>Encode the hash using URL-safe unpadded base64 (<xref target="int-unpadded-base64"/>).</li>
        </ol>
      </section>
    </section>
    <section anchor="int-unpadded-base64">
      <name>Unpadded Base64</name>
      <t>Throughout this document, "unpadded base64" is used to represent binary values as strings. Base64 is
as specified by <xref section="4" sectionFormat="of" target="RFC4648"/>, and "unpadded base64" simply removes any <tt>=</tt> padding from
the resulting string.</t>
      <t>Implementations <bcp14>SHOULD</bcp14> accept input with or without padding on base64 values, where possible.</t>
      <t><xref section="5" sectionFormat="of" target="RFC4648"/> describes <em>URL-safe</em> base64. The same changes are adopted here. Namely, the
62nd and 63rd characters are replaced with <tt>-</tt> and <tt>_</tt> respectively. The unpadded behaviour is as
described above.</t>
    </section>
    <section anchor="int-hub-selection">
      <name>Hub Selection</name>
      <t><strong>TODO</strong>: Describe impacts of hub transfers</t>
      <t>The hub server for a room is the server denoted by the <tt>sender</tt> of the <tt>m.room.create</tt> event
(<xref target="int-ev-create"/>). Note that this is effectively the same as the server name contained in the
room ID (<xref target="int-room-id"/>) currently, however is deliberately not defined as such. In a future
scenario where hub transfers are possible, the room ID does not change when the hub server does.</t>
      <section anchor="hub-transfers">
        <name>Hub Transfers</name>
        <t><strong>TODO</strong>: This section, if we want a single canonical hub in the room. Some expected problems in this
area are: who signs the transfer event? who <em>sends</em> the transfer event? how does a transfer start?</t>
        <t><strong>TODO</strong>: Likely to be done with an <tt>m.room.hub</tt> state event in the room, where the "current hub" is
either the sender of <tt>m.room.hub</tt> or <tt>m.room.create</tt> if no hub state event is present. Auth rules
would govern what makes for a legal <tt>m.room.hub</tt> event.</t>
        <t><strong>TODO</strong>: <xref target="I-D.kohbrok-mimi-portability"/> may be of help here.</t>
      </section>
    </section>
    <section anchor="int-transport">
      <name>Transport</name>
      <t>This document specifies a wire transport which uses JSON <xref target="RFC8259"/> over HTTPS <xref target="RFC9110"/>. Servers
<bcp14>MUST</bcp14> support a minimum of HTTP/2 <xref target="RFC9113"/> and TLS 1.3 <xref target="RFC8446"/>.</t>
      <t><strong>TODO</strong>: This transport doesn't scale, and doesn't use RESTful endpoints. This example transport is
heavily inspired by Matrix's existing Server-Server API, largely acting as a starting point for testing
interoperability of the access control semantics. A better option might be gRPC, which might change how
events are structured but keep the overall semantics the same. <xref target="I-D.rosenberg-mimi-protocol"/> might
have ideas here as well for REST APIs.</t>
      <section anchor="int-tls">
        <name>TLS Certificates</name>
        <t>Servers <bcp14>MUST</bcp14> provide a TLS certificate signed by a known Certificate Authority. Requesting servers
are ultimately responsible for the Certificate Authorities they place trust in, however servers
<bcp14>SHOULD</bcp14> trust authorities which would commonly be trusted by an operating system or web browser.</t>
      </section>
      <section anchor="api-standards">
        <name>API Standards</name>
        <section anchor="int-transport-requests-responses">
          <name>Requests and Responses</name>
          <t>All HTTP <tt>POST</tt> and <tt>PUT</tt> endpoints require the sending server to supply a (potentially empty) JSON
object as the request body. Requesting servers <bcp14>SHOULD</bcp14> supply a <tt>Content-Type</tt> header of <tt>application/json</tt>
for such requests.</t>
          <t>All endpoints which require a server to respond with a JSON object <bcp14>MUST</bcp14> include a <tt>Content-Type</tt> header
of <tt>application/json</tt>.</t>
          <t>All JSON data, in requests or responses, <bcp14>MUST</bcp14> be encoded using UTF-8 <xref target="RFC3629"/>.</t>
          <t>All endpoints in this document do <em>not</em> support trailing slashes on them. When such a request is
encountered, it <bcp14>MUST</bcp14> be handled as an unknown endpoint (<xref target="int-unknown-endpoints"/>). Examples include:</t>
          <ul spacing="normal">
            <li>
              <tt>https://example.org/_matrix/path</tt> - valid.</li>
            <li>
              <tt>https://example.org/_matrix/path/</tt> - unknown/invalid.</li>
            <li>
              <tt>https://example.org//_matrix/path</tt> - unknown/invalid (domain also can't have a trailing slash).</li>
            <li>
              <tt>https://example.org//_matrix/path/</tt> - doubly unknown/invalid.</li>
          </ul>
          <t>Servers (both hub and participants) <bcp14>MUST</bcp14> implement all endpoints unless otherwise specified.</t>
          <t>Most endpoints have a version number as part of the path. This version number is that endpoint's version,
allowing for breaking changes to be made to the schema of that endpoint. For clarity, the version number
is <em>not</em> representative of an API version.</t>
        </section>
        <section anchor="int-transport-errors">
          <name>Errors</name>
          <t>All errors are represented by an error code defined by this document and an accompanied HTTP status code.
It is possible for a HTTP status code to map to multiple error codes, and it's possible for an error
code to map to multiple HTTP status codes.</t>
          <t>When a server is returning an error to a caller, it <bcp14>MUST</bcp14> use the most appropriate error response defined
by the endpoint. If no appropriate error response is specified, the server <bcp14>SHOULD</bcp14> use <tt>M_UNKNOWN</tt> as the
error code and <tt>500 Internal Server Error</tt> as the HTTP status code.</t>
          <t>Errors are represented as JSON objects, requiring a <tt>Content-Type: application/json</tt> response header:</t>
          <sourcecode type="json"><![CDATA[
{
  "errcode": "M_UNKNOWN",
  "error": "Something went wrong."
}
]]></sourcecode>
          <t><tt>errcode</tt> is required and denotes the error code. <tt>error</tt> is an optional human-readable description of
the error. <tt>error</tt> can be as precise or vague as the responding server desires - the strings in this
document are suggestions.</t>
          <t>Some common error codes are:</t>
          <ul spacing="normal">
            <li>
              <tt>M_UNKNOWN</tt> - An unknown error has occurred.</li>
            <li>
              <tt>M_FORBIDDEN</tt> - The caller is not permitted to access the resource. For example, trying to join a room
the user does not have an invite for.</li>
            <li>
              <tt>M_NOT_JSON</tt> - The request did not contain valid JSON. Must be accompanied by a <tt>400 Bad Request</tt> HTTP
status code.</li>
            <li>
              <tt>M_BAD_JSON</tt> - The request did contain valid JSON, but it was missing required keys or was malformed in
 another way. Must be accompanied by a <tt>400 Bad Request</tt> HTTP status code.</li>
            <li>
              <tt>M_LIMIT_EXCEEDED</tt> - Too many requests have been sent. The caller should wait before trying the request
again.</li>
            <li>
              <tt>M_TOO_LARGE</tt> - The request was too large for the receiver to handle.</li>
          </ul>
        </section>
        <section anchor="int-unknown-endpoints">
          <name>Unsupported Endpoints</name>
          <t>If a server receives a request for an unsupported or otherwise unknown endpoint, the server <bcp14>MUST</bcp14> respond
with an HTTP <tt>404 Not Found</tt> status code and <tt>M_UNRECOGNIZED</tt> error code. If the request was for a known
endpoint, but wrong HTTP method, a <tt>405 Method Not Allowed</tt> HTTP status code and <tt>M_UNRECOGNIZED</tt> error
code (<xref target="int-transport-errors"/>).</t>
        </section>
        <section anchor="malformed-requests">
          <name>Malformed Requests</name>
          <t>If a server is expecting JSON in the request body but receives something else, it <bcp14>MUST</bcp14> respond with an
HTTP status code of <tt>400 Bad Request</tt> and error code <tt>M_NOT_JSON</tt> (<xref target="int-transport-errors"/>). If the
request contains JSON, and is for a known endpoint, but otherwise missing required keys or is malformed,
the server <bcp14>MUST</bcp14> respond with an HTTP status code of <tt>400 Bad Request</tt> and error code <tt>M_BAD_JSON</tt>
(<xref target="int-transport-errors"/>). Where possible, <tt>error</tt> for <tt>M_BAD_JSON</tt> should describe the missing keys
or other parsing error.</t>
        </section>
        <section anchor="int-txn-ids">
          <name>Transaction Identifiers</name>
          <t>Where endpoints use HTTP <tt>PUT</tt>, it is typical for a "transaction ID" to be specified in the path
parameters. This transaction ID <bcp14>MUST</bcp14> ONLY be used for making requests idempotent - if a server receives
two (or more) requests with the same transaction ID, it <bcp14>MUST</bcp14> return the same response for each and only
process the request body once. It is assumed that requests using the same transaction ID also contain
the same request body between calls.</t>
          <t>A transaction ID only needs to be unique per-endpoint and per-sending server. A server's transaction IDs
do not affect requests made by other servers or made to other endpoints by the same server.</t>
        </section>
        <section anchor="rate-limiting">
          <name>Rate Limiting</name>
          <t>Servers <bcp14>SHOULD</bcp14> implement rate limiting semantics to reduce the risk of being overloaded. Endpoints which
support being rate limited are annotated in this document.</t>
          <t>If a rate limit is encountered, the server <bcp14>MUST</bcp14> respond with an HTTP <tt>429 Too Many Requests</tt> status code
and <tt>M_LIMIT_EXCEEDED</tt> error code (<xref target="int-transport-errors"/>). If applicable, the server should additionally
include a <tt>retry_after_ms</tt> integer field on the error response to denote how long the caller should
wait before retrying, in milliseconds.</t>
          <sourcecode type="json"><![CDATA[
{
  "errcode": "M_LIMIT_EXCEEDED",
  "error": "Too many requests. Try again later.",
  "retry_after_ms": 10254
}
]]></sourcecode>
          <t>The exact rate limit mechanics are left as an implementation detail. A potential approach may be to
prevent repeated requests for the same resource at a high rate and ensuring a remote server does not
request more than a defined number of resources at a time.</t>
        </section>
      </section>
      <section anchor="int-resolve-domain">
        <name>Resolving Server Names</name>
        <t>Before making an API request, the caller <bcp14>MUST</bcp14> resolve a server name (<xref target="int-server-names"/>) to an IP
address and port, suitable for HTTPS <xref target="RFC9110"/> traffic.</t>
        <t>A server <bcp14>MAY</bcp14> change the IP/port combination used for API endpoints using SRV DNS records <xref target="RFC2782"/>.
Servers <bcp14>MAY</bcp14> additionally change which TLS certificate is presented by using <tt>.well-known</tt> delegation.</t>
        <t><tt>.well-known</tt> delegation (step 3 below) is recommended for its ease of configuration over SRV DNS records.</t>
        <t>The target server <bcp14>MUST</bcp14> present a valid TLS certificate (<xref target="int-tls"/>) for the name described in each
step. Similarly, the requesting server <bcp14>MUST</bcp14> use an HTTP <tt>Host</tt> header matching the description in each
step.</t>
        <t>Server developers should note that many of the DNS requirements for the steps below are typically handled
by the software language or library implicitly. It is rare that a DNS A record needs to be resolved manually,
for example.</t>
        <t>Per <xref target="int-server-names"/>, a server name consists of <tt>&lt;hostname&gt;[:&lt;port&gt;]</tt>. The steps to convert that
server name to an IP address and port are:</t>
        <ol spacing="normal" type="1"><li>
            <t>If <tt>&lt;hostname&gt;</tt> has an explicit <tt>&lt;port&gt;</tt> is present, resolve <tt>&lt;hostname&gt;</tt> to
an IP address using CNAME <xref target="RFC1034"/> <xref target="RFC2181"/>, AAAA <xref target="RFC3596"/>, or A <xref target="RFC1035"/> DNS
records. Requests are made to the resolved IP address and port number.  </t>
            <t>
TLS certificate: <tt>&lt;hostname&gt;</tt> (always without port)  </t>
            <t>
Host header: <tt>&lt;hostname&gt;:&lt;port&gt;</tt></t>
          </li>
          <li>
            <t>A regular (non-Matrix) HTTPS request is made to <tt>https://&lt;hostname&gt;/.well-known/matrix/server</tt>,
expecting the schema defined by <xref target="int-wellknown"/>. If the response is invalid (bad/not JSON, missing
properties, non-200 response, etc), skip to Step 4. If the response is valid, the <tt>m.server</tt> property
is parsed as <tt>&lt;delegated_hostname&gt;[:&lt;delegated_port&gt;]</tt>.  </t>
            <ol spacing="normal" type="1"><li>
                <t>If <tt>&lt;delegated_hostname&gt;</tt> has an explicit <tt>&lt;delegated_port&gt;</tt> is present, resolve
<tt>&lt;delegated_hostname&gt;</tt> to an IP address using CNAME, AAAA, or A DNS records. Requests are made to the
resolved IP address and port number.      </t>
                <t>
TLS certificate: <tt>&lt;delegated_hostname&gt;</tt> (always without port)      </t>
                <t>
Host header: <tt>&lt;delegated_hostname&gt;:&lt;delegated_port&gt;</tt></t>
              </li>
              <li>
                <t>An SRV DNS record is resolved for <tt>_matrix._tcp.&lt;delegated_hostname&gt;</tt>. This may result in another
hostname and port to be resolved using AAAA or A DNS records. Requests are made to the resolved IP
address and port number.      </t>
                <t>
TLS certificate: <tt>&lt;delegated_hostname&gt;</tt>      </t>
                <t>
Host header: <tt>&lt;delegated_hostname&gt;</tt> (without port)</t>
              </li>
              <li>
                <t>If no SRV record is found, an IP address is resolved for <tt>&lt;delegated_hostname&gt;</tt> is resolved using
CNAME, AAAA, or A DNS records. Requests are made to the resolved IP address with port number 8448.      </t>
                <t>
TLS certificate: <tt>&lt;delegated_hostname&gt;</tt>      </t>
                <t>
Host header: <tt>&lt;delegated_hostname&gt;</tt> (without port)</t>
              </li>
            </ol>
          </li>
          <li>
            <t>If the <tt>.well-known</tt> call from Step 3 resulted in an invalid response, an SRV DNS record is resolved
for <tt>_matrix._tcp.&lt;hostname&gt;</tt>. This may result in another hostname and port to be resolved using AAAA
or A DNS records. Requests are made to the resolved IP address and port number.  </t>
            <t>
TLS certificate: <tt>&lt;hostname&gt;</tt> (always without port)  </t>
            <t>
Host header: <tt>&lt;hostname&gt;</tt> (without port)</t>
          </li>
          <li>
            <t>If the <tt>.well-known</tt> call from Step 3 resulted in an invalid response, and the SRV record from Step 4
was not found, and IP address is resolved using CNAME, AAAA, or A DNS records. Requests are made to the
resolved IP address and port 8448.  </t>
            <t>
TLS certificate: <tt>&lt;hostname&gt;</tt> (always without port)  </t>
            <t>
Host header: <tt>&lt;hostname&gt;</tt> (without port)</t>
          </li>
        </ol>
        <t>We require <tt>&lt;[delegated_]hostname&gt;</tt> rather than <tt>&lt;srv_hostname&gt;</tt> in Steps 3.3 and 4 for the following reasons:</t>
        <ol spacing="normal" type="1"><li>DNS is largely insecure (not all domains use DNSSEC <xref target="RFC9364"/>), so the target of the SRV record must
prove it is a valid delegate/target for <tt>&lt;[delegated_]hostname&gt;</tt> via TLS.</li>
          <li>
            <xref section="6.2.1" sectionFormat="of" target="RFC6125"/> recommends this approach, and is consistent with other applications
which use SRV records (such as <xref section="13.7.2.1" sectionFormat="of" target="RFC6120"/>/XMPP).</li>
        </ol>
        <t>Server implementations and owners should additionally note that the target of a SRV record <bcp14>MUST NOT</bcp14> be a CNAME,
as per RFC 2782 <xref target="RFC2782"/>:</t>
        <ul empty="true">
          <li>
            <t>the name <bcp14>MUST NOT</bcp14> be an alias (in the sense of RFC 1034 or RFC 2181)</t>
          </li>
        </ul>
        <t><xref target="RFC1034"/> <xref target="RFC2181"/></t>
        <section anchor="int-wellknown">
          <name><tt>GET /.well-known/matrix/server</tt></name>
          <t>Used by the server name resolution approach to determine a delegated hostname for a given server. 30x HTTP
redirection <bcp14>MUST</bcp14> be followed, though loops <bcp14>SHOULD</bcp14> be avoided. Normal X.509 certificate validation is applied
to this endpoint (not the specific validation required by the server name resolution steps) <xref target="RFC5280"/>.</t>
          <t>This endpoint <bcp14>MAY</bcp14> be implemented by servers (it is optional).</t>
          <t><strong>Rate-limited</strong>: No.</t>
          <t><strong>Authentication required</strong>: No.</t>
          <t>This HTTP endpoint does not specify any request parameters or body.</t>
          <t><tt>200 OK</tt> response:</t>
          <sourcecode type="json"><![CDATA[
{
   "m.server": "delegated.example.org:8448"
}
]]></sourcecode>
          <t><tt>m.server</tt> is a required response field. Responses <bcp14>SHOULD</bcp14> have a <tt>Content-Type</tt> HTTP header of
<tt>application/json</tt>, however servers parsing the response should assume that the body is JSON regardless
of <tt>Content-Type</tt> header. Failures in parsing the JSON or otherwise invalid data that prevents parsing
<bcp14>MUST NOT</bcp14> result in discovery failure. Instead, the caller is expected to move on to the next step of
the name resolution approach.</t>
          <t>Cache control headers <bcp14>SHOULD</bcp14> be respected on a <tt>200 OK</tt> response. Callers <bcp14>SHOULD</bcp14> impose a maximum
cache time of 48 hours, regardless of cache control headers. A default of 24 hours <bcp14>SHOULD</bcp14> be used
when no cache control headers are present.</t>
          <t>Error responses (non-200) <bcp14>SHOULD</bcp14> be cached for no longer than 1 hour. Callers <bcp14>SHOULD</bcp14> exponentially
back off (to a defined limit) upon receiving repeated error responses.</t>
        </section>
      </section>
      <section anchor="int-transport-auth">
        <name>Request Authentication</name>
        <t>Most endpoints in this document require authentication to prove which server is making the request.
This is done using public key digital signatures.</t>
        <t>The request method, target, and body are represented as a JSON object, signed, and appended as an HTTP
<tt>Authorization</tt> header with an auth scheme of <tt>X-Matrix</tt>.</t>
        <t>The object to be signed is:</t>
        <sourcecode type="json"><![CDATA[
{
   "method": "GET",
   "uri": "/path/to/endpoint?with_qs=true",
   "origin": "requesting.server.name.example.org",
   "destination": "target.server.name.example.org",
   "content": {"json_request_body": true}
}
]]></sourcecode>
        <t><tt>method</tt> is the HTTP request method, capitalized. <tt>uri</tt> is the full request path, beginning with the
leading slash and containing the query string (if present). <tt>uri</tt> does not contain the <tt>https:</tt> scheme
or hostname.</t>
        <t><strong>TODO</strong>: Define an ordering algorithm for the query string (if we need to?).</t>
        <t><tt>origin</tt> and <tt>destination</tt> are the sender and receiver server names (<xref target="int-server-names"/>), respectively.</t>
        <t><tt>content</tt> is the JSON-encoded request body. When a request doesn't contain a body, such as in <tt>GET</tt>
requests, use an empty JSON object.</t>
        <t>That object is then signed (<xref target="int-signing-objects"/>) by the requesting server. The resulting signature
is appended as an <tt>Authentication</tt> HTTP header on the request:</t>
        <artwork><![CDATA[
GET /path/to/endpoint?with_qs=true
Authorization: X-Matrix origin="requesting.server.name.example.org",
   destination="target.server.name.example.org",
   key="ed25519:0",
   sig="<unpadded base64 encoded signature>"
Content-Type: application/json

{"json_request_body": true}
]]></artwork>
        <t>Linebreaks within <tt>Authorization</tt> are for clarity and are non-normative.</t>
        <t>The format of the Authorization header matches <xref section="11.4" sectionFormat="of" target="RFC9110"/>. The header begins with an
authorization scheme of <tt>X-Matrix</tt>, followed by one or more spaces, followed by an (unordered)
comma-separated list of parameters written as name=value pairs. The names are case insensitive, though
the values are. The values must be enclosed in quotes if they contain characters which are not allowed
in a <tt>token</tt>, as defined by <xref section="5.6.2" sectionFormat="of" target="RFC9110"/>. If a value is a valid <tt>token</tt> it may not be
enclosed in quotes. Quoted values <bcp14>MAY</bcp14> contain backslash-escaped characters. When parsing the header,
the recipient must unescape the characters.</t>
        <t>The exact parameters are:</t>
        <ul spacing="normal">
          <li>
            <tt>origin</tt> - The name of the sending server. <bcp14>MUST</bcp14> match the <tt>origin</tt> in the signed JSON.</li>
          <li>
            <tt>destination</tt> - The name of the receiving server. <bcp14>MUST</bcp14> match the <tt>destination</tt> in the signed JSON.</li>
          <li>
            <tt>key</tt> - The ID, including algorithm name, of the sending server's signing key used to sign the request.</li>
          <li>
            <tt>signature</tt> - The unpadded base64 (<xref target="int-unpadded-base64"/>) encoded signature from step 2.</li>
        </ul>
        <t>Unknown parameters are ignored and <bcp14>MUST NOT</bcp14> result in authentication errors.</t>
        <t>A receiving server validates the Authorization header by composing the JSON object represented above
and checking the sender's signature (<xref target="int-checking-signatures"/>). Note that to comply with
<xref target="int-checking-signatures"/> the receiver may need to append a <tt>signatures</tt> field to the JSON object
manually. All signatures <bcp14>MUST</bcp14> use an unexpired key at the time of the request
(<xref target="int-transport-keys-validity"/>).</t>
        <t>A server with multiple signing keys <bcp14>SHOULD</bcp14> include an <tt>Authorization</tt> header for each signing key.</t>
        <t>If an endpoint requires authentication, servers <bcp14>MUST</bcp14>:</t>
        <ul spacing="normal">
          <li>Validate all presented <tt>Authorization</tt> headers.</li>
          <li>Ensure at least one <tt>Authorization</tt> header is present.</li>
        </ul>
        <t>If either fails (lack of headers, or any of the headers fail validation), the request <bcp14>MUST</bcp14> be rejected
with an HTTP <tt>401 Unauthorized</tt> status code and <tt>M_FORBIDDEN</tt> error code (<xref target="int-transport-errors"/>):</t>
        <sourcecode type="json"><![CDATA[
{
   "errcode": "M_FORBIDDEN",
   "error": "Signature error on request."
}
]]></sourcecode>
        <t>If an endpoint does <em>not</em> require authentication, <tt>Authorization</tt> headers are ignored entirely.</t>
        <t>Responses from a server are authenticated using TLS and do not have additional signing requirements.</t>
        <section anchor="int-transport-get-server-keys">
          <name>Retrieving Server Keys</name>
          <t><strong>TODO</strong>: Explain what notaries are and what they do, if we keep this section at all.</t>
          <t>A server's signing keys are published under <tt>/_matrix/key/v2/server</tt> (<xref target="int-api-self-key"/>) and can
be queried through notary servers in two ways: <xref target="int-api-notary-query"/> and <xref target="int-api-notary-query-bulk"/>.
Notary servers implicitly call <tt>/_matrix/key/v2/server</tt> when queried, signing and caching the response
for some time. This allows the target server to offline without affecting their previously sent events.</t>
          <t>The approach used here is borrowed from the Perspectives Project <xref target="PerspectivesProject"/>, modified to
cover the server's ed25519 keys and to use JSON instead of XML. The advantage of this system is it allows
each server to pick which notaries it trusts, and can contact multiple notaries to corroborate the keys
returned by any given notary.</t>
          <t>Servers <bcp14>SHOULD</bcp14> attempt to contact the target server directly before using a notary server.</t>
          <t>Note that these endpoints operate outside the context of a room: a server does not need to participate
in any shared rooms to be used as a notary by another server, and does not need to use the hub as a
notary.</t>
          <section anchor="int-transport-keys-validity">
            <name>Validity</name>
            <t>A server's keys are only valid for a short time, denoted by <tt>valid_until_ts</tt>. Around the <tt>valid_until_ts</tt>
timestamp, a server would re-fetch the server's keys to discover any changes. In the vast majority of
cases, only <tt>valid_until_ts</tt> changes between requests (keys are long-lived, but validated frequently).</t>
            <t><tt>valid_until_ts</tt> <bcp14>MUST</bcp14> be handled as the lesser of <tt>valid_until_ts</tt> and 7 days into the future, preventing
attackers from publishing long-lived keys that are unable to be revoked. Servers <bcp14>SHOULD</bcp14> use a timestamp
approximately 12 hours into the future when responding with their keys.</t>
            <t><strong>TODO</strong>: What does it mean to require events have an <tt>origin_server_ts</tt> which is less than that of
<tt>valid_until_ts</tt>? Do we reject the event, soft-fail it, or do something else? Do we only do this on the
hub?</t>
          </section>
          <section anchor="int-api-self-key">
            <name><tt>GET /_matrix/key/v2/server</tt></name>
            <t>Retrieves the server's signing keys. The server can have any number of active or inactive keys at a
time, but <bcp14>SHOULD</bcp14> have at least 1 active key at all times.</t>
            <t><strong>Rate-limited</strong>: No.</t>
            <t><strong>Authentication required</strong>: No.</t>
            <t>This HTTP endpoint does not specify any request parameters or body.</t>
            <t><tt>200 OK</tt> response:</t>
            <sourcecode type="json"><![CDATA[
{
   "server_name": "example.org",
   "valid_until_ts": 1686776437176,
   "m.linearized": true,
   "verify_keys": {
      "ed25519:0": {
         "key": "<unpadded base64 encoded public key>"
      }
   },
   "old_verify_keys": {
      "ed25519:bad": {
         "expired_ts": 1586776437176,
         "key": "<unpadded base64 encoded public key>"
      }
   },
   "signatures": {
      "example.org": {
         "ed25519:0": "<unpadded base64 encoded signature>"
      }
   }
}
]]></sourcecode>
            <t><tt>server_name</tt> <bcp14>MUST</bcp14> be the name of the server (<xref target="int-server-names"/>) which is returning the keys.</t>
            <t><tt>valid_until_ts</tt> is the integer timestamp (milliseconds since Unix epoch) for when the server's keys
should be re-fetched. See <xref target="int-transport-keys-validity"/>.</t>
            <t><tt>m.linearized</tt> is an optional boolean, but <bcp14>SHOULD</bcp14> be set to <tt>true</tt>. Semantics for <tt>false</tt> and not
being present apply to contexts outside of this document.</t>
            <t><tt>verify_keys</tt> are the current signing keys for the server, keyed by key ID (<xref target="int-signing"/>). The
object value for each key ID under <tt>verify_keys</tt> is simply the <tt>key</tt>, consisting of the unpadded
base64 encoded public key matching that algorithm and version.</t>
            <t><tt>old_verify_keys</tt> are similar to <tt>verify_keys</tt>, but have an additional required <tt>expired_ts</tt> property
to denote when the key ceased usage. This overrides <tt>valid_until_ts</tt> for the purposes of
<xref target="int-transport-keys-validity"/> at an individual key level.</t>
            <t><strong>TODO</strong>: What about events sent with <tt>old_verify_keys</tt>?</t>
            <t>For request authentication (<xref target="int-transport-auth"/>), only keys listed under <tt>verify_keys</tt> are honoured.
If another key is referenced by the <tt>Authorization</tt> headers, the request fails authentication.</t>
            <t>Notaries <bcp14>SHOULD</bcp14> cache a 200 OK response for half of its lifetime to avoid serving stale values.
Responding servers <bcp14>SHOULD</bcp14> avoid returning responses which expire in less than an hour to avoid
repeated requests. Requesting servers <bcp14>SHOULD</bcp14> limit how frequently they query for keys to avoid
flooding a server with requests.</t>
            <t>If the server fails to respond to this request, notaries <bcp14>SHOULD</bcp14> continue to return the last response
they received from the server so that the signatures of old events can still be checked, even if that
response is no longer considered valid (<xref target="int-transport-keys-validity"/>).</t>
            <t>Servers are capable of rotating their keys without populating <tt>old_verify_keys</tt>, though this can cause
reliability issues if other servers don't see both keys. Notaries <bcp14>SHOULD</bcp14> cache responses with distinct
key IDs indefinitely. For example, if a server has <tt>ed25519:0</tt> and <tt>ed25519:1</tt> on its first response,
and a later response returns <tt>ed25519:1</tt> and <tt>ed25519:2</tt>, the notary should cache both responses. This
gives servers an ability to validate <tt>ed25519:0</tt> for old events in a room.</t>
          </section>
          <section anchor="int-api-notary-query">
            <name><tt>GET /_matrix/key/v2/query/:serverName</tt></name>
            <t>This is one of two endpoints for querying a server's keys through another server. The notary (receiving)
server will attempt to refresh its cached copy of the target server's keys through <tt>/_matrix/key/v2/server</tt>,
falling back to any cached values if needed.</t>
            <t><strong>Rate-limited</strong>: No.</t>
            <t><strong>Authentication required</strong>: No.</t>
            <t>Path parameters:</t>
            <ul spacing="normal">
              <li>
                <tt>:serverName</tt> - the target server's name (<xref target="int-server-names"/>) to retrieve keys for.</li>
            </ul>
            <t>Query parameters:</t>
            <ul spacing="normal">
              <li>
                <tt>minimum_valid_until_ts</tt> (integer; optional) - The time in milliseconds since the Unix epoch the
target server's keys will need to be valid until to be useful to the caller. If not specified the
notary server's current time will be used.</li>
            </ul>
            <t>Request body: None applicable.</t>
            <t><tt>200 OK</tt> response:</t>
            <sourcecode type="json"><![CDATA[
{
   "server_keys": [
      {/* server key */}
   ]
}
]]></sourcecode>
            <t><tt>server_keys</tt> is the array of keys (see <xref target="int-api-self-key"/> response format) for the target server.
If the target server could not be reached and the notary has no cached keys, this array is empty. If
the keys do not meet <tt>minimum_valid_until_ts</tt> per <xref target="int-transport-keys-validity"/>, they are not included.</t>
            <t>The notary server <bcp14>MUST</bcp14> sign each key returned in <tt>server_keys</tt> by at least one of its own signing keys.
The calling server <bcp14>MUST</bcp14> validate all signatures on the objects.</t>
          </section>
          <section anchor="int-api-notary-query-bulk">
            <name><tt>POST /_matrix/key/v2/query</tt></name>
            <t>A bulk version of <tt>/_matrix/key/v2/query/:serverName</tt> (<xref target="int-api-notary-query"/>). The same behaviour
applies to this endpoint.</t>
            <t><strong>Rate-limited</strong>: No.</t>
            <t><strong>Authentication required</strong>: No.</t>
            <t>Path parameters: None applicable.</t>
            <t>Query parameters: None applicable.</t>
            <t>Request body:</t>
            <sourcecode type="json"><![CDATA[
{
   "server_keys": {
      "example.org": {
         "ed25519:0": {
            "minimum_valid_until_ts": 1686783382189
         }
      }
   }
}
]]></sourcecode>
            <t><tt>server_keys</tt> is required and is the search criteria. The object value is first keyed by server name
which maps to another object keyed by Key ID, mapping to the specific criteria. If no key IDs are
given in the request, all of the server's known keys are queried. If no servers are given in the
request, the response <bcp14>MUST</bcp14> contain an empty <tt>server_keys</tt> array.</t>
            <t><tt>minimum_valid_until_ts</tt> holds the same meaning as in <xref target="int-api-notary-query"/>.</t>
            <t><tt>200 OK</tt> response:</t>
            <t>Same as <xref target="int-api-notary-query"/> with the following added detail:</t>
            <t>Responding servers <bcp14>SHOULD</bcp14> only return signed key objects for the key IDs requested by the caller, however
servers <bcp14>MAY</bcp14> respond with more keys than requested. The caller is expected to filter the response if
needed.</t>
          </section>
        </section>
      </section>
      <section anchor="int-transport-send-events">
        <name>Sending Events</name>
        <t>Events accepted into the room by a hub server must be sent to all other servers in that room. Similarly,
participant servers need a way to send partial events through the hub server, as mentioned by <xref target="int-lpdu"/>.</t>
        <t>A single endpoint is used for all rooms on either server, and can contain both fully-formed PDUs
(<xref target="int-pdu"/>) or Linearized PDUs (partial events; <xref target="int-lpdu"/>) depending on the server's role in the
applicable room.</t>
        <t>A typical event send path will be:</t>
        <artset>
          <artwork type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="432" width="504" viewBox="0 0 504 432" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
              <path d="M 8,32 L 8,64" fill="none" stroke="black"/>
              <path d="M 32,72 L 32,296" fill="none" stroke="black"/>
              <path d="M 32,312 L 32,416" fill="none" stroke="black"/>
              <path d="M 56,32 L 56,64" fill="none" stroke="black"/>
              <path d="M 176,240 L 176,272" fill="none" stroke="black"/>
              <path d="M 192,32 L 192,64" fill="none" stroke="black"/>
              <path d="M 256,72 L 256,288" fill="none" stroke="black"/>
              <path d="M 256,320 L 256,392" fill="none" stroke="black"/>
              <path d="M 320,32 L 320,64" fill="none" stroke="black"/>
              <path d="M 352,112 L 352,144" fill="none" stroke="black"/>
              <path d="M 368,32 L 368,64" fill="none" stroke="black"/>
              <path d="M 432,72 L 432,296" fill="none" stroke="black"/>
              <path d="M 432,312 L 432,416" fill="none" stroke="black"/>
              <path d="M 496,32 L 496,64" fill="none" stroke="black"/>
              <path d="M 8,32 L 56,32" fill="none" stroke="black"/>
              <path d="M 192,32 L 320,32" fill="none" stroke="black"/>
              <path d="M 368,32 L 496,32" fill="none" stroke="black"/>
              <path d="M 8,64 L 56,64" fill="none" stroke="black"/>
              <path d="M 192,64 L 320,64" fill="none" stroke="black"/>
              <path d="M 368,64 L 496,64" fill="none" stroke="black"/>
              <path d="M 256,112 L 352,112" fill="none" stroke="black"/>
              <path d="M 264,144 L 352,144" fill="none" stroke="black"/>
              <path d="M 40,192 L 256,192" fill="none" stroke="black"/>
              <path d="M 32,240 L 176,240" fill="none" stroke="black"/>
              <path d="M 40,272 L 176,272" fill="none" stroke="black"/>
              <path d="M 8,304 L 136,304" fill="none" stroke="black"/>
              <path d="M 368,304 L 496,304" fill="none" stroke="black"/>
              <path d="M 32,352 L 248,352" fill="none" stroke="black"/>
              <path d="M 32,400 L 424,400" fill="none" stroke="black"/>
              <polygon class="arrowhead" points="432,400 420,394.4 420,405.6" fill="black" transform="rotate(0,424,400)"/>
              <polygon class="arrowhead" points="272,144 260,138.4 260,149.6" fill="black" transform="rotate(180,264,144)"/>
              <polygon class="arrowhead" points="256,352 244,346.4 244,357.6" fill="black" transform="rotate(0,248,352)"/>
              <polygon class="arrowhead" points="48,272 36,266.4 36,277.6" fill="black" transform="rotate(180,40,272)"/>
              <polygon class="arrowhead" points="48,192 36,186.4 36,197.6" fill="black" transform="rotate(180,40,192)"/>
              <g class="text">
                <text x="32" y="52">Hub</text>
                <text x="252" y="52">Participant1</text>
                <text x="428" y="52">Participant2</text>
                <text x="292" y="100">Create</text>
                <text x="340" y="100">LPDU</text>
                <text x="128" y="180">PUT</text>
                <text x="196" y="180">/send/:txnId</text>
                <text x="68" y="228">Append</text>
                <text x="112" y="228">PDU</text>
                <text x="156" y="228">fields</text>
                <text x="188" y="308">Concurrent</text>
                <text x="268" y="308">requests</text>
                <text x="332" y="308">follow</text>
                <text x="56" y="340">PUT</text>
                <text x="124" y="340">/send/:txnId</text>
                <text x="56" y="388">PUT</text>
                <text x="124" y="388">/send/:txnId</text>
                <text x="256" y="420">|</text>
              </g>
            </svg>
          </artwork>
          <artwork type="ascii-art"><![CDATA[
+-----+                +---------------+     +---------------+
| Hub |                | Participant1  |     | Participant2  |
+-----+                +---------------+     +---------------+
   |                           |                     |
   |                           | Create LPDU         |
   |                           +-----------+         |
   |                           |           |         |
   |                           |<----------+         |
   |                           |                     |
   |          PUT /send/:txnId |                     |
   |<--------------------------+                     |
   |                           |                     |
   | Append PDU fields         |                     |
   +-----------------+         |                     |
   |                 |         |                     |
   |<----------------+         |                     |
   |                           |                     |
----------------- Concurrent requests follow -----------------
   |                           |                     |
   | PUT /send/:txnId          |                     |
   +-------------------------->|                     |
   |                           |                     |
   | PUT /send/:txnId          |                     |
   +------------------------------------------------>|
   |                           |                     |
]]></artwork>
        </artset>
        <t><tt>PUT /send/:txnId</tt> is shorthand for <xref target="int-api-send-txn"/>.</t>
        <t>Hubs which generate events would skip to the point where they create a fully-formed PDU and send it
out to all other participants.</t>
        <t>When a hub is broadcasting events to participant servers, it <bcp14>MUST</bcp14> include the following targets:</t>
        <ul spacing="normal">
          <li>The server implied by the <tt>sender</tt> for a kick or ban <tt>m.room.member</tt> (<xref target="int-ev-member"/>) event, up
to the point of that kick or ban.</li>
          <li>All servers which have at least 1 user which is joined to the room.</li>
        </ul>
        <section anchor="int-api-send-txn">
          <name><tt>PUT /_matrix/federation/v2/send/:txnId</tt></name>
          <t>Sends (L)PDUs (<xref target="int-pdu"/>, <xref target="int-lpdu"/>) to another server. The sending server <bcp14>MUST</bcp14> wait for a
<tt>200 OK</tt> response from the receiver before sending another request with a different <tt>:txnId</tt>.</t>
          <t><strong>Implementation note</strong>: Currently this endpoint doesn't actually exist. Use
<tt>PUT /_matrix/federation/unstable/org.matrix.i-d.ralston-mimi-linearized-matrix.02/send/:txnId</tt>
when testing against other Linearized Matrix implementations. This string may be updated later to
account for breaking changes.</t>
          <t><strong>TODO</strong>: Remove implementation notes.</t>
          <t><strong>Rate-limited</strong>: No.</t>
          <t><strong>Authentication required</strong>: Yes.</t>
          <t>Path parameters:</t>
          <ul spacing="normal">
            <li>
              <tt>:txnId</tt> - the transaction ID (<xref target="int-txn-ids"/>) for the request.</li>
          </ul>
          <t>Query parameters: None applicable.</t>
          <t>Request body:</t>
          <sourcecode type="json"><![CDATA[
{
   "edus": [
      {/* EDU */}
   ],
   "pdus": [
      {/* Either an LPDU or PDU */}
   ]
}
]]></sourcecode>
          <t><tt>edus</tt> are the Ephemeral Data Units (<xref target="int-transport-edus"/>) to send. If no EDUs are being sent, this
field <bcp14>MAY</bcp14> be excluded from the request body. There <bcp14>MUST NOT</bcp14> be more than 100 entries in <tt>edus</tt>.</t>
          <t><tt>pdus</tt> are the events/PDUs (<xref target="int-pdu"/>) and LPDUs (<xref target="int-lpdu"/>) to send to the server. Whether
it's an LPDU or PDU depends on the sending server's role in that room: if they are a non-hub server,
it will be an LPDU. There <bcp14>MUST NOT</bcp14> be more than 50 entries in <tt>pdus</tt>.</t>
          <t>Each event in the <tt>pdus</tt> array gets processed as such:</t>
          <ol spacing="normal" type="1"><li>
              <t>Identify the room ID for the event. The exact format of the event can differ between room versions,
however currently this would be done by extracting the <tt>room_id</tt> property.  </t>
              <ol spacing="normal" type="1"><li>If that room ID is invalid/not found, the event is rejected.</li>
                <li>If the server is not participating in the room, the event is dropped/skipped.</li>
              </ol>
            </li>
            <li>If the event is an LPDU and the receiving server is the hub, the additional PDU fields are appended
before continuing.</li>
            <li>If the event is an LPDU and the receiving server is not the hub, the event is dropped/skipped.</li>
            <li>The checks defined by <xref target="int-receiving-events"/> are performed.</li>
            <li>If the event still hasn't been dropped/rejected, it is appended to the room. For participant servers,
this may mean it's queued for sending to local clients.</li>
          </ol>
          <t>Server implementation authors should note that these steps can be condensed, but are expanded here
for specification purposes. For example, an LPDU's signature can/will fail without ever needing to
append the PDU fields first - the server can skip some extra work this way.</t>
          <t><tt>200 OK</tt> response:</t>
          <sourcecode type="json"><![CDATA[
{
   "failed_pdus": {
      "$eventid": {
         "error": "Invalid event format"
      },
      "$eventid": {
         "error":
            "@alice:example.org cannot send m.room.power_levels"
      }
   }
}
]]></sourcecode>
          <t>The receiving server <bcp14>MUST NOT</bcp14> send a <tt>200 OK</tt> response until all events have been processed. Servers
<bcp14>SHOULD NOT</bcp14> block responding to this endpoint on sending accepted events to local clients or other
participant servers, as doing so could lead to a lengthy backlog of events waiting to be sent.</t>
          <t>Sending servers <bcp14>SHOULD</bcp14> apply/expect a timeout and retry the exact same request with the same transaction
ID until they see a <tt>200 OK</tt> response. If the sending server attempts to send a different transaction
ID from the one already in flight, the receiving server <bcp14>MUST</bcp14> respond with a <tt>400 Bad Request</tt> HTTP
status code and <tt>M_BAD_STATE</tt> error code (<xref target="int-transport-errors"/>). Receiving servers <bcp14>SHOULD</bcp14> continue
processing requests to this endpoint event after the sender has disconnected/timed out, but <bcp14>SHOULD NOT</bcp14>
process the request multiple times due to the transaction ID (<xref target="int-txn-ids"/>).</t>
          <t><tt>failed_pdus</tt> is an object mapping event ID (<xref target="int-pdu"/>) to error string. Event IDs are based upon
the received object, not the final/complete object. For example, if an LPDU is sent, gets its PDU
fields appended, and fails event authorization, then the error would be for the event ID of the LPDU,
not the fully-formed PDU. This is to allow the sender to correlate what they sent with errors.</t>
          <t>The object for each event ID <bcp14>MUST</bcp14> contain an <tt>error</tt> string field, representing the human-readable
reason for an event being rejected.</t>
          <t>Events which are dropped/ignored or accepted do <em>not</em> appear in <tt>failed_pdus</tt>.</t>
          <t><strong>TODO</strong>: Should we also return fully-formed PDUs for the LPDUs we received?</t>
        </section>
      </section>
      <section anchor="event-and-state-apis">
        <name>Event and State APIs</name>
        <t>When a participant in the room is missing an event, or otherwise needs a new copy of it, it can retrieve
that event from the hub server. Similar mechanics apply for getting state events, current state of a room,
and backfilling scrollback in a room.</t>
        <t>All servers are required to implement all endpoints (<xref target="int-transport-requests-responses"/>), however
only hub servers are guaranteed to have the full history/state for a room. While other participant
servers might have history, they <bcp14>SHOULD NOT</bcp14> be contacted due to the high likelihood of a Not Found-style
error.</t>
        <section anchor="get-matrixfederationv2eventeventid">
          <name><tt>GET /_matrix/federation/v2/event/:eventId</tt></name>
          <t>Retrieves a single event.</t>
          <t><strong>Implementation note</strong>: Currently this endpoint doesn't actually exist. Use
<tt>GET /_matrix/federation/unstable/org.matrix.i-d.ralston-mimi-linearized-matrix.02/event/:eventId</tt>
when testing against other Linearized Matrix implementations. This string may be updated later to
account for breaking changes.</t>
          <t><strong>TODO</strong>: Remove implementation notes.</t>
          <t><strong>Rate-limited</strong>: Yes.</t>
          <t><strong>Authentication required</strong>: Yes.</t>
          <t>Path parameters:</t>
          <ul spacing="normal">
            <li>
              <tt>:eventId</tt> - the event ID (<xref target="int-pdu"/>) to retrieve. Note that event IDs are typically reference
hashes (<xref target="int-reference-hashes"/>) of the event itself, which includes the room ID. This makes
event IDs globally unique.</li>
          </ul>
          <t>Query parameters: None applicable.</t>
          <t>Request body: None applicable.</t>
          <t><tt>200 OK</tt> response:</t>
          <sourcecode type="json"><![CDATA[
{
   /* the event */
}
]]></sourcecode>
          <t>The response body is simply the event (<xref target="int-pdu"/>) itself, if the requesting server has reasonable
visibility of the event (<xref target="int-calc-event-visibility"/>). When the server can see an event but not the
contents, the event is served redacted (<xref target="int-redactions"/>) instead.</t>
          <t>If the event isn't known to the server, or the requesting server has no reason to know that the event
even exists, a <tt>404 Not Found</tt> HTTP status code and <tt>M_NOT_FOUND</tt> error code (<xref target="int-transport-errors"/>)
is returned.</t>
          <t>The returned event <bcp14>MUST</bcp14> be checked before being used by the requesting server (<xref target="int-receiving-events"/>).
This endpoint <bcp14>MUST NOT</bcp14> return LPDUs (<xref target="int-lpdu"/>), instead treating such events as though they didn't
exist.</t>
        </section>
        <section anchor="int-api-get-state">
          <name><tt>GET /_matrix/federation/v1/state/:roomId</tt></name>
          <t>Retrieves a snapshot of the room state (<xref target="int-state-events"/>) at the given event. This is typically
most useful when a participant server prefers to store minimal information about the room, but still
needs to offer context to its clients.</t>
          <t><strong>Rate-limited</strong>: Yes.</t>
          <t><strong>Authentication required</strong>: Yes.</t>
          <t>Path parameters:</t>
          <ul spacing="normal">
            <li>
              <tt>:roomId</tt> - the room ID (<xref target="int-room-id"/>) to retrieve state in.</li>
          </ul>
          <t>Query parameters:</t>
          <ul spacing="normal">
            <li>
              <tt>event_id</tt> (string; required) - The event ID (<xref target="int-pdu"/>) to retrieve state at.</li>
          </ul>
          <t>Request body: None applicable.</t>
          <t><tt>200 OK</tt> response:</t>
          <sourcecode type="json"><![CDATA[
{
   "auth_chain": [
      {/* event */}
   ],
   "pdus": [
      {/* event */}
   ]
}
]]></sourcecode>
          <t>The returned room state is in two parts: the <tt>pdus</tt>, consisting of the events which represent "current
state" (<xref target="int-state-events"/>) prior to considering state changes induced by the event in the original
request, and <tt>auth_chain</tt>, consisting of the events which make up the <tt>auth_events</tt> (<xref target="int-auth-selection"/>)
for the <tt>pdus</tt> and the <tt>auth_events</tt> of those events, recursively.</t>
          <t>The <tt>auth_chain</tt> will eventually stop recursing when it reaches the <tt>m.room.create</tt> event, as it cannot
have any <tt>auth_events</tt>.</t>
          <t><strong>TODO</strong>: Do we actually need to recurse auth events to get the full auth chain here? What are participant
servers expected to do with this information? (Do they even care about it?)</t>
          <t>For example, if the requested event ID was an <tt>m.room.power_levels</tt> event, the returned state would be
as if the new power levels were not applied.</t>
          <t>Both <tt>auth_chain</tt> and <tt>pdus</tt> contain event objects (<xref target="int-pdu"/>).</t>
          <t>If the requesting server does not have reasonable visibility on the room (<xref target="int-calc-event-visibility"/>),
or either the room ID or event ID don't exist, a <tt>404 Not Found</tt> HTTP status code and <tt>M_NOT_FOUND</tt>
error code (<xref target="int-transport-errors"/>) is returned. The same error is returned if the event ID doesn't
exist in the requested room ID.</t>
          <t>Note that the requesting server will generally always have visibility of the <tt>auth_chain</tt> and <tt>pdu</tt>
events, but may not be able to see their contents. In this case, they are redacted (<xref target="int-redactions"/>)
before being served.</t>
          <t>The returned events <bcp14>MUST</bcp14> be checked before being used by the requesting server (<xref target="int-receiving-events"/>).
This endpoint <bcp14>MUST NOT</bcp14> return LPDUs (<xref target="int-lpdu"/>), instead treating such events as though they didn't
exist.</t>
          <t>If the receiving server is not the hub server for the room ID, an HTTP status code of <tt>400 Bad Request</tt>
and error code <tt>M_WRONG_SERVER</tt> (<xref target="int-transport-errors"/>) is returned.</t>
        </section>
        <section anchor="get-matrixfederationv1stateidsroomid">
          <name><tt>GET /_matrix/federation/v1/state_ids/:roomId</tt></name>
          <t>This performs the same function as <xref target="int-api-get-state"/> but returns just the event IDs instead.</t>
          <t><strong>Rate-limited</strong>: Yes.</t>
          <t><strong>Authentication required</strong>: Yes.</t>
          <t>Path parameters:</t>
          <ul spacing="normal">
            <li>
              <tt>:roomId</tt> - the room ID (<xref target="int-room-id"/>) to retrieve state in.</li>
          </ul>
          <t>Query parameters:</t>
          <ul spacing="normal">
            <li>
              <tt>event_id</tt> (string; required) - The event ID (<xref target="int-pdu"/>) to retrieve state at.</li>
          </ul>
          <t>Request body: None applicable.</t>
          <t><tt>200 OK</tt> response:</t>
          <sourcecode type="json"><![CDATA[
{
   "auth_chain_ids": ["$event1", "$event2"],
   "pdu_ids": ["$event3", "$event4"]
}
]]></sourcecode>
          <t>See <xref target="int-api-get-state"/> for behaviour. Note that <tt>auth_chain</tt> becomes <tt>auth_chain_ids</tt> when using
this endpoint, and <tt>pdus</tt> becomes <tt>pdu_ids</tt>.</t>
        </section>
        <section anchor="get-matrixfederationv2backfillroomid">
          <name><tt>GET /_matrix/federation/v2/backfill/:roomId</tt></name>
          <t>Retrieves a sliding window history of previous events in a given room.</t>
          <t><strong>Implementation note</strong>: Currently this endpoint doesn't actually exist. Use
<tt>GET /_matrix/federation/unstable/org.matrix.i-d.ralston-mimi-linearized-matrix.02/backfill/:roomId</tt>
when testing against other Linearized Matrix implementations. This string may be updated later to
account for breaking changes.</t>
          <t><strong>TODO</strong>: Remove implementation notes.</t>
          <t><strong>Rate-limited</strong>: Yes.</t>
          <t><strong>Authentication required</strong>: Yes.</t>
          <t>Path parameters:</t>
          <ul spacing="normal">
            <li>
              <tt>:roomId</tt> - the room ID (<xref target="int-room-id"/>) to retrieve events from.</li>
          </ul>
          <t>Query parameters:</t>
          <ul spacing="normal">
            <li>
              <tt>v</tt> (string; required) - The event ID (<xref target="int-pdu"/>) to start backfilling from.</li>
            <li>
              <tt>limit</tt> (integer; required) - The maximum number of events to return, including <tt>v</tt>.</li>
          </ul>
          <t>Request body: None applicable.</t>
          <t><tt>200 OK</tt> response:</t>
          <sourcecode type="json"><![CDATA[
{
   "pdus": [
      {/* event */}
   ]
}
]]></sourcecode>
          <t>The number of returned <tt>pdus</tt> <bcp14>MUST NOT</bcp14> exceed the <tt>limit</tt> provided by the caller. <tt>limit</tt> <bcp14>SHOULD</bcp14> have
a maximum value imposed by the receiving server. <tt>pdus</tt> contains the events (<xref target="int-pdu"/>) preceeding
the requested event ID (<tt>v</tt>), including <tt>v</tt>. <tt>pdus</tt> is ordered from oldest to newest.</t>
          <t>If the requesting server does not have reasonable visibility on the room (<xref target="int-calc-event-visibility"/>),
or either the room ID or event ID don't exist, a <tt>404 Not Found</tt> HTTP status code and <tt>M_NOT_FOUND</tt>
error code (<xref target="int-transport-errors"/>) is returned. The same error is returned if the event ID doesn't
exist in the requested room ID.</t>
          <t>If the requesting server does have visibility on the returned events, but not their contents, they
are redacted (<xref target="int-redactions"/>) before being served.</t>
          <t>The returned events <bcp14>MUST</bcp14> be checked before being used by the requesting server (<xref target="int-receiving-events"/>).
This endpoint <bcp14>MUST NOT</bcp14> return LPDUs (<xref target="int-lpdu"/>), instead treating such events as though they didn't
exist.</t>
        </section>
      </section>
      <section anchor="int-transport-room-membership">
        <name>Room Membership</name>
        <t>When a server is already participating in a room, it can simply send <tt>m.room.member</tt> (<xref target="int-ev-member"/>)
events with the <tt>/send</tt> API (<xref target="int-api-send-txn"/>) to other servers/the hub directly. When a server is
not already participating however, it needs to be welcomed in by the hub server.</t>
        <t>A typical invite flow would be:</t>
        <artset>
          <artwork type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="720" width="584" viewBox="0 0 584 720" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
              <path d="M 8,32 L 8,64" fill="none" stroke="black"/>
              <path d="M 64,72 L 64,408" fill="none" stroke="black"/>
              <path d="M 64,424 L 64,704" fill="none" stroke="black"/>
              <path d="M 120,32 L 120,64" fill="none" stroke="black"/>
              <path d="M 232,32 L 232,64" fill="none" stroke="black"/>
              <path d="M 256,72 L 256,400" fill="none" stroke="black"/>
              <path d="M 256,432 L 256,704" fill="none" stroke="black"/>
              <path d="M 272,256 L 272,288" fill="none" stroke="black"/>
              <path d="M 280,32 L 280,64" fill="none" stroke="black"/>
              <path d="M 296,560 L 296,592" fill="none" stroke="black"/>
              <path d="M 392,32 L 392,64" fill="none" stroke="black"/>
              <path d="M 456,72 L 456,408" fill="none" stroke="black"/>
              <path d="M 456,424 L 456,704" fill="none" stroke="black"/>
              <path d="M 520,32 L 520,64" fill="none" stroke="black"/>
              <path d="M 8,32 L 120,32" fill="none" stroke="black"/>
              <path d="M 232,32 L 280,32" fill="none" stroke="black"/>
              <path d="M 392,32 L 520,32" fill="none" stroke="black"/>
              <path d="M 8,64 L 120,64" fill="none" stroke="black"/>
              <path d="M 232,64 L 280,64" fill="none" stroke="black"/>
              <path d="M 392,64 L 520,64" fill="none" stroke="black"/>
              <path d="M 64,112 L 248,112" fill="none" stroke="black"/>
              <path d="M 256,160 L 448,160" fill="none" stroke="black"/>
              <path d="M 272,256 L 456,256" fill="none" stroke="black"/>
              <path d="M 272,288 L 448,288" fill="none" stroke="black"/>
              <path d="M 264,336 L 456,336" fill="none" stroke="black"/>
              <path d="M 72,384 L 256,384" fill="none" stroke="black"/>
              <path d="M 8,416 L 160,416" fill="none" stroke="black"/>
              <path d="M 416,416 L 576,416" fill="none" stroke="black"/>
              <path d="M 264,464 L 456,464" fill="none" stroke="black"/>
              <path d="M 256,512 L 448,512" fill="none" stroke="black"/>
              <path d="M 296,560 L 456,560" fill="none" stroke="black"/>
              <path d="M 296,592 L 448,592" fill="none" stroke="black"/>
              <path d="M 264,640 L 456,640" fill="none" stroke="black"/>
              <path d="M 256,688 L 448,688" fill="none" stroke="black"/>
              <polygon class="arrowhead" points="456,688 444,682.4 444,693.6" fill="black" transform="rotate(0,448,688)"/>
              <polygon class="arrowhead" points="456,592 444,586.4 444,597.6" fill="black" transform="rotate(0,448,592)"/>
              <polygon class="arrowhead" points="456,512 444,506.4 444,517.6" fill="black" transform="rotate(0,448,512)"/>
              <polygon class="arrowhead" points="456,288 444,282.4 444,293.6" fill="black" transform="rotate(0,448,288)"/>
              <polygon class="arrowhead" points="456,160 444,154.4 444,165.6" fill="black" transform="rotate(0,448,160)"/>
              <polygon class="arrowhead" points="272,640 260,634.4 260,645.6" fill="black" transform="rotate(180,264,640)"/>
              <polygon class="arrowhead" points="272,464 260,458.4 260,469.6" fill="black" transform="rotate(180,264,464)"/>
              <polygon class="arrowhead" points="272,336 260,330.4 260,341.6" fill="black" transform="rotate(180,264,336)"/>
              <polygon class="arrowhead" points="256,112 244,106.4 244,117.6" fill="black" transform="rotate(0,248,112)"/>
              <polygon class="arrowhead" points="80,384 68,378.4 68,389.6" fill="black" transform="rotate(180,72,384)"/>
              <g class="text">
                <text x="64" y="52">Participant</text>
                <text x="256" y="52">Hub</text>
                <text x="452" y="52">TargetServer</text>
                <text x="92" y="100">POST</text>
                <text x="144" y="100">/invite</text>
                <text x="204" y="100">(LPDU)</text>
                <text x="284" y="148">POST</text>
                <text x="336" y="148">/invite</text>
                <text x="392" y="148">(PDU)</text>
                <text x="300" y="196">Decide</text>
                <text x="340" y="196">to</text>
                <text x="384" y="196">process</text>
                <text x="432" y="196">the</text>
                <text x="296" y="212">invite.</text>
                <text x="344" y="212">Can</text>
                <text x="388" y="212">reject</text>
                <text x="432" y="212">due</text>
                <text x="276" y="228">to</text>
                <text x="312" y="228">spam,</text>
                <text x="348" y="228">or</text>
                <text x="380" y="228">send</text>
                <text x="412" y="228">it</text>
                <text x="436" y="228">to</text>
                <text x="304" y="244">the</text>
                <text x="360" y="244">recipient</text>
                <text x="424" y="244">user.</text>
                <text x="316" y="324">Finish</text>
                <text x="364" y="324">POST</text>
                <text x="416" y="324">/invite</text>
                <text x="116" y="372">Finish</text>
                <text x="164" y="372">POST</text>
                <text x="216" y="372">/invite</text>
                <text x="188" y="420">User</text>
                <text x="240" y="420">decides</text>
                <text x="284" y="420">to</text>
                <text x="324" y="420">accept</text>
                <text x="380" y="420">invite</text>
                <text x="344" y="452">GET</text>
                <text x="404" y="452">/make_join</text>
                <text x="292" y="500">Finish</text>
                <text x="336" y="500">GET</text>
                <text x="396" y="500">/make_join</text>
                <text x="308" y="548">Fill</text>
                <text x="352" y="548">event</text>
                <text x="412" y="548">template</text>
                <text x="340" y="628">POST</text>
                <text x="404" y="628">/send_join</text>
                <text x="292" y="676">Finish</text>
                <text x="340" y="676">POST</text>
                <text x="404" y="676">/send_join</text>
              </g>
            </svg>
          </artwork>
          <artwork type="ascii-art"><![CDATA[
+-------------+             +-----+             +---------------+
| Participant |             | Hub |             | TargetServer  |
+-------------+             +-----+             +---------------+
       |                       |                        |
       | POST /invite (LPDU)   |                        |
       +---------------------->|                        |
       |                       |                        |
       |                       | POST /invite (PDU)     |
       |                       +----------------------->|
       |                       |                        |
       |                       |  Decide to process the |
       |                       | invite. Can reject due |
       |                       | to spam, or send it to |
       |                       |    the recipient user. |
       |                       | +----------------------+
       |                       | |                      |
       |                       | +--------------------->|
       |                       |                        |
       |                       |    Finish POST /invite |
       |                       |<-----------------------+
       |                       |                        |
       |   Finish POST /invite |                        |
       |<----------------------+                        |
       |                       |                        |
-------------------- User decides to accept invite ---------------------
       |                       |                        |
       |                       |         GET /make_join |
       |                       |<-----------------------+
       |                       |                        |
       |                       | Finish GET /make_join  |
       |                       +----------------------->|
       |                       |                        |
       |                       |    Fill event template |
       |                       |    +-------------------+
       |                       |    |                   |
       |                       |    +------------------>|
       |                       |                        |
       |                       |        POST /send_join |
       |                       |<-----------------------+
       |                       |                        |
       |                       | Finish POST /send_join |
       |                       +----------------------->|
       |                       |                        |
]]></artwork>
        </artset>
        <t><tt>POST /invite</tt> is shorthand for <xref target="int-api-invite"/>. Similarly, <tt>GET /make_join</tt> is <xref target="int-api-make-join"/>
and <tt>POST /send_join</tt> is <xref target="int-api-send-join"/>.</t>
        <t>If the user decided to reject the invite, the TargetServer would use <tt>GET /make_leave</tt> (<xref target="int-api-make-leave"/>)
and <tt>POST /send_leave</tt> (<xref target="int-api-send-leave"/>) instead of make/send_join.</t>
        <section anchor="int-transport-make-and-send">
          <name>Make and Send Handshake</name>
          <t>When a server is already participating in a room, it can use <tt>m.room.member</tt> (<xref target="int-ev-member"/>) events
and the <tt>/send</tt> API (<xref target="int-api-send-txn"/>) to directly change membership. When the server is not already
involved in the room, such as when being invited for the first time, the server needs to "make" an event
and "send" it through the hub server to append it to the room.</t>
          <t>The different processes which use this handshake are:</t>
          <ul spacing="normal">
            <li>Rejecting Invites (<xref target="int-transport-leaves"/>)</li>
            <li>Joins (<xref target="int-transport-joins"/>)</li>
            <li>Knocks (<xref target="int-transport-knocks"/>)</li>
          </ul>
          <t>The "make" portion of the endpoints take the shape of <tt>GET /_matrix/federation/v1/make_CHANGE/:roomId/:userId</tt>,
where <tt>CHANGE</tt> is <tt>leave</tt>, <tt>join</tt>, or <tt>knock</tt> (respective to the list above). This endpoint will
return a partial LPDU (<xref target="int-lpdu"/>) which needs to be turned into a full LPDU and signed before being
sent using <tt>POST /_matrix/federation/v3/send_CHANGE/:txnId</tt>.</t>
          <t>The flow for this handshake appears as such:</t>
          <artset>
            <artwork type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="656" width="568" viewBox="0 0 568 656" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
                <path d="M 8,32 L 8,64" fill="none" stroke="black"/>
                <path d="M 72,72 L 72,640" fill="none" stroke="black"/>
                <path d="M 144,32 L 144,64" fill="none" stroke="black"/>
                <path d="M 232,400 L 232,432" fill="none" stroke="black"/>
                <path d="M 232,544 L 232,576" fill="none" stroke="black"/>
                <path d="M 280,272 L 280,304" fill="none" stroke="black"/>
                <path d="M 512,32 L 512,64" fill="none" stroke="black"/>
                <path d="M 536,72 L 536,640" fill="none" stroke="black"/>
                <path d="M 560,32 L 560,64" fill="none" stroke="black"/>
                <path d="M 8,32 L 144,32" fill="none" stroke="black"/>
                <path d="M 512,32 L 560,32" fill="none" stroke="black"/>
                <path d="M 8,64 L 144,64" fill="none" stroke="black"/>
                <path d="M 512,64 L 560,64" fill="none" stroke="black"/>
                <path d="M 72,112 L 528,112" fill="none" stroke="black"/>
                <path d="M 80,176 L 536,176" fill="none" stroke="black"/>
                <path d="M 80,224 L 536,224" fill="none" stroke="black"/>
                <path d="M 72,272 L 280,272" fill="none" stroke="black"/>
                <path d="M 80,304 L 280,304" fill="none" stroke="black"/>
                <path d="M 72,352 L 528,352" fill="none" stroke="black"/>
                <path d="M 232,400 L 536,400" fill="none" stroke="black"/>
                <path d="M 232,432 L 528,432" fill="none" stroke="black"/>
                <path d="M 80,480 L 536,480" fill="none" stroke="black"/>
                <path d="M 232,544 L 536,544" fill="none" stroke="black"/>
                <path d="M 232,576 L 528,576" fill="none" stroke="black"/>
                <path d="M 80,624 L 536,624" fill="none" stroke="black"/>
                <polygon class="arrowhead" points="536,576 524,570.4 524,581.6" fill="black" transform="rotate(0,528,576)"/>
                <polygon class="arrowhead" points="536,432 524,426.4 524,437.6" fill="black" transform="rotate(0,528,432)"/>
                <polygon class="arrowhead" points="536,352 524,346.4 524,357.6" fill="black" transform="rotate(0,528,352)"/>
                <polygon class="arrowhead" points="536,112 524,106.4 524,117.6" fill="black" transform="rotate(0,528,112)"/>
                <polygon class="arrowhead" points="88,624 76,618.4 76,629.6" fill="black" transform="rotate(180,80,624)"/>
                <polygon class="arrowhead" points="88,480 76,474.4 76,485.6" fill="black" transform="rotate(180,80,480)"/>
                <polygon class="arrowhead" points="88,304 76,298.4 76,309.6" fill="black" transform="rotate(180,80,304)"/>
                <polygon class="arrowhead" points="88,224 76,218.4 76,229.6" fill="black" transform="rotate(180,80,224)"/>
                <polygon class="arrowhead" points="88,176 76,170.4 76,181.6" fill="black" transform="rotate(180,80,176)"/>
                <g class="text">
                  <text x="76" y="52">ExternalServer</text>
                  <text x="536" y="52">Hub</text>
                  <text x="96" y="100">GET</text>
                  <text x="316" y="100">/_matrix/federation/v1/make_CHANGE/:roomId/:userId</text>
                  <text x="324" y="148">Reject</text>
                  <text x="364" y="148">if</text>
                  <text x="400" y="148">event</text>
                  <text x="452" y="148">future</text>
                  <text x="504" y="148">event</text>
                  <text x="272" y="164">would</text>
                  <text x="312" y="164">not</text>
                  <text x="340" y="164">be</text>
                  <text x="384" y="164">allowed</text>
                  <text x="428" y="164">by</text>
                  <text x="460" y="164">auth</text>
                  <text x="504" y="164">rules</text>
                  <text x="352" y="212">Respond</text>
                  <text x="404" y="212">with</text>
                  <text x="456" y="212">partial</text>
                  <text x="508" y="212">LPDU</text>
                  <text x="116" y="260">Populate</text>
                  <text x="172" y="260">LPDU</text>
                  <text x="208" y="260">and</text>
                  <text x="244" y="260">sign</text>
                  <text x="276" y="260">it</text>
                  <text x="100" y="340">POST</text>
                  <text x="288" y="340">/_matrix/federation/v3/send_CHANGE/:txnId</text>
                  <text x="260" y="388">Validate</text>
                  <text x="320" y="388">event</text>
                  <text x="360" y="388">and</text>
                  <text x="404" y="388">append</text>
                  <text x="444" y="388">to</text>
                  <text x="472" y="388">the</text>
                  <text x="508" y="388">room</text>
                  <text x="220" y="468">Reject</text>
                  <text x="260" y="468">if</text>
                  <text x="296" y="468">event</text>
                  <text x="336" y="468">not</text>
                  <text x="384" y="468">allowed</text>
                  <text x="428" y="468">by</text>
                  <text x="460" y="468">auth</text>
                  <text x="504" y="468">rules</text>
                  <text x="324" y="516">Send</text>
                  <text x="360" y="516">new</text>
                  <text x="400" y="516">event</text>
                  <text x="436" y="516">to</text>
                  <text x="464" y="516">all</text>
                  <text x="504" y="516">other</text>
                  <text x="316" y="532">participants</text>
                  <text x="380" y="532">in</text>
                  <text x="408" y="532">the</text>
                  <text x="444" y="532">room</text>
                  <text x="496" y="532">(async)</text>
                  <text x="488" y="612">200</text>
                  <text x="516" y="612">OK</text>
                </g>
              </svg>
            </artwork>
            <artwork type="ascii-art"><![CDATA[
+----------------+                                             +-----+
| ExternalServer |                                             | Hub |
+----------------+                                             +-----+
        |                                                         |
        | GET /_matrix/federation/v1/make_CHANGE/:roomId/:userId  |
        +-------------------------------------------------------->|
        |                                                         |
        |                            Reject if event future event |
        |                      would not be allowed by auth rules |
        |<--------------------------------------------------------+
        |                                                         |
        |                               Respond with partial LPDU |
        |<--------------------------------------------------------+
        |                                                         |
        | Populate LPDU and sign it                               |
        +-------------------------+                               |
        |                         |                               |
        |<------------------------+                               |
        |                                                         |
        | POST /_matrix/federation/v3/send_CHANGE/:txnId          |
        +-------------------------------------------------------->|
        |                                                         |
        |                   Validate event and append to the room |
        |                   +-------------------------------------+
        |                   |                                     |
        |                   +------------------------------------>|
        |                                                         |
        |               Reject if event not allowed by auth rules |
        |<--------------------------------------------------------+
        |                                                         |
        |                             Send new event to all other |
        |                        participants in the room (async) |
        |                   +-------------------------------------+
        |                   |                                     |
        |                   +------------------------------------>|
        |                                                         |
        |                                                  200 OK |
        |<--------------------------------------------------------+
        |                                                         |
]]></artwork>
          </artset>
          <t>Note that the <tt>send_CHANGE</tt> step re-checks the event against the auth rules: any amount of time
could have passed between the <tt>make_CHANGE</tt> and <tt>send_CHANGE</tt> calls.</t>
          <t><strong>TODO</strong>: Describe how the external server is meant to find the hub. Invites work by (usually) trying
to contact the server which sent the invite, but knocking is a guess.</t>
        </section>
        <section anchor="int-transport-invites">
          <name>Invites</name>
          <t>When inviting a user belonging to a server already in the room, senders <bcp14>SHOULD</bcp14> use <tt>m.room.member</tt>
(<xref target="int-ev-member"/>) events and the <tt>/send</tt> API (<xref target="int-api-send-txn"/>). This section's endpoints <bcp14>SHOULD</bcp14>
only be used when the target server is <em>not</em> participating in the room already.</t>
          <t>Note that being invited does not count as the server "participating" in the room. This can mean that
while a server has a user with a pending invite in the room, this section's endpoints are needed to
send additional invites to other users on the same server.</t>
          <t>The full invite sequence is:</t>
          <artset>
            <artwork type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="784" width="520" viewBox="0 0 520 784" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
                <path d="M 8,32 L 8,64" fill="none" stroke="black"/>
                <path d="M 64,72 L 64,768" fill="none" stroke="black"/>
                <path d="M 120,32 L 120,64" fill="none" stroke="black"/>
                <path d="M 224,32 L 224,64" fill="none" stroke="black"/>
                <path d="M 248,72 L 248,768" fill="none" stroke="black"/>
                <path d="M 272,32 L 272,64" fill="none" stroke="black"/>
                <path d="M 272,624 L 272,656" fill="none" stroke="black"/>
                <path d="M 384,32 L 384,64" fill="none" stroke="black"/>
                <path d="M 400,256 L 400,288" fill="none" stroke="black"/>
                <path d="M 448,72 L 448,768" fill="none" stroke="black"/>
                <path d="M 512,32 L 512,64" fill="none" stroke="black"/>
                <path d="M 8,32 L 120,32" fill="none" stroke="black"/>
                <path d="M 224,32 L 272,32" fill="none" stroke="black"/>
                <path d="M 384,32 L 512,32" fill="none" stroke="black"/>
                <path d="M 8,64 L 120,64" fill="none" stroke="black"/>
                <path d="M 224,64 L 272,64" fill="none" stroke="black"/>
                <path d="M 384,64 L 512,64" fill="none" stroke="black"/>
                <path d="M 64,112 L 240,112" fill="none" stroke="black"/>
                <path d="M 72,192 L 248,192" fill="none" stroke="black"/>
                <path d="M 248,256 L 400,256" fill="none" stroke="black"/>
                <path d="M 256,288 L 400,288" fill="none" stroke="black"/>
                <path d="M 248,336 L 440,336" fill="none" stroke="black"/>
                <path d="M 256,400 L 448,400" fill="none" stroke="black"/>
                <path d="M 256,480 L 448,480" fill="none" stroke="black"/>
                <path d="M 72,544 L 248,544" fill="none" stroke="black"/>
                <path d="M 272,624 L 448,624" fill="none" stroke="black"/>
                <path d="M 272,656 L 440,656" fill="none" stroke="black"/>
                <path d="M 256,704 L 448,704" fill="none" stroke="black"/>
                <path d="M 72,752 L 248,752" fill="none" stroke="black"/>
                <polygon class="arrowhead" points="448,656 436,650.4 436,661.6" fill="black" transform="rotate(0,440,656)"/>
                <polygon class="arrowhead" points="448,336 436,330.4 436,341.6" fill="black" transform="rotate(0,440,336)"/>
                <polygon class="arrowhead" points="264,704 252,698.4 252,709.6" fill="black" transform="rotate(180,256,704)"/>
                <polygon class="arrowhead" points="264,480 252,474.4 252,485.6" fill="black" transform="rotate(180,256,480)"/>
                <polygon class="arrowhead" points="264,400 252,394.4 252,405.6" fill="black" transform="rotate(180,256,400)"/>
                <polygon class="arrowhead" points="264,288 252,282.4 252,293.6" fill="black" transform="rotate(180,256,288)"/>
                <polygon class="arrowhead" points="248,112 236,106.4 236,117.6" fill="black" transform="rotate(0,240,112)"/>
                <polygon class="arrowhead" points="80,752 68,746.4 68,757.6" fill="black" transform="rotate(180,72,752)"/>
                <polygon class="arrowhead" points="80,544 68,538.4 68,549.6" fill="black" transform="rotate(180,72,544)"/>
                <polygon class="arrowhead" points="80,192 68,186.4 68,197.6" fill="black" transform="rotate(180,72,192)"/>
                <g class="text">
                  <text x="64" y="52">Participant</text>
                  <text x="248" y="52">Hub</text>
                  <text x="444" y="52">TargetServer</text>
                  <text x="92" y="100">POST</text>
                  <text x="144" y="100">/invite</text>
                  <text x="132" y="148">Reject</text>
                  <text x="172" y="148">if</text>
                  <text x="212" y="148">sender</text>
                  <text x="108" y="164">cannot</text>
                  <text x="164" y="164">invite</text>
                  <text x="216" y="164">other</text>
                  <text x="216" y="180">users</text>
                  <text x="300" y="228">Otherwise,</text>
                  <text x="372" y="228">append</text>
                  <text x="272" y="244">PDU</text>
                  <text x="316" y="244">fields</text>
                  <text x="276" y="324">POST</text>
                  <text x="328" y="324">/invite</text>
                  <text x="348" y="372">Reject</text>
                  <text x="388" y="372">if</text>
                  <text x="420" y="372">room</text>
                  <text x="296" y="388">version</text>
                  <text x="344" y="388">not</text>
                  <text x="400" y="388">supported</text>
                  <text x="292" y="436">Reject</text>
                  <text x="332" y="436">if</text>
                  <text x="372" y="436">target</text>
                  <text x="420" y="436">user</text>
                  <text x="308" y="452">is</text>
                  <text x="364" y="452">ineligible</text>
                  <text x="424" y="452">for</text>
                  <text x="408" y="468">invites</text>
                  <text x="112" y="516">Proxy</text>
                  <text x="188" y="516">TargetServer</text>
                  <text x="200" y="532">rejection</text>
                  <text x="348" y="580">Otherwise,</text>
                  <text x="416" y="580">queue</text>
                  <text x="296" y="596">sending</text>
                  <text x="344" y="596">the</text>
                  <text x="388" y="596">invite</text>
                  <text x="428" y="596">to</text>
                  <text x="372" y="612">target</text>
                  <text x="420" y="612">user</text>
                  <text x="400" y="692">200</text>
                  <text x="428" y="692">OK</text>
                  <text x="200" y="740">200</text>
                  <text x="228" y="740">OK</text>
                </g>
              </svg>
            </artwork>
            <artwork type="ascii-art"><![CDATA[
+-------------+            +-----+             +---------------+
| Participant |            | Hub |             | TargetServer  |
+-------------+            +-----+             +---------------+
       |                      |                        |
       | POST /invite         |                        |
       +--------------------->|                        |
       |                      |                        |
       |     Reject if sender |                        |
       |  cannot invite other |                        |
       |                users |                        |
       |<---------------------+                        |
       |                      |                        |
       |                      | Otherwise, append      |
       |                      | PDU fields             |
       |                      +------------------+     |
       |                      |                  |     |
       |                      |<-----------------+     |
       |                      |                        |
       |                      | POST /invite           |
       |                      +----------------------->|
       |                      |                        |
       |                      |         Reject if room |
       |                      |  version not supported |
       |                      |<-----------------------+
       |                      |                        |
       |                      |  Reject if target user |
       |                      |      is ineligible for |
       |                      |                invites |
       |                      |<-----------------------+
       |                      |                        |
       |   Proxy TargetServer |                        |
       |            rejection |                        |
       |<---------------------+                        |
       |                      |                        |
       |                      |       Otherwise, queue |
       |                      |  sending the invite to |
       |                      |            target user |
       |                      |  +---------------------+
       |                      |  |                     |
       |                      |  +-------------------->|
       |                      |                        |
       |                      |                 200 OK |
       |                      |<-----------------------+
       |                      |                        |
       |               200 OK |                        |
       |<---------------------+                        |
       |                      |                        |
]]></artwork>
          </artset>
          <t><tt>POST /invite</tt> is shorthand for <xref target="int-api-invite"/>.</t>
          <t>What causes a user to be considered "ineligible" for an invite is left as an implementation detail.
See <xref target="int-user-privacy"/> and <xref target="int-spam"/> for suggestions on handling user-level privacy controls and
spam invites.</t>
          <section anchor="int-api-invite">
            <name><tt>POST /_matrix/federation/v3/invite/:txnId</tt></name>
            <t>Sends an invite event to a server. If the sender is a participant server, the receiving server (the
hub) will convert the contained LPDU (<xref target="int-lpdu"/>) to a fully-formed event (<xref target="int-pdu"/>) before sending
that event to the intended server.</t>
            <t><strong>Implementation note</strong>: Currently this endpoint doesn't actually exist. Use
<tt>POST /_matrix/federation/unstable/org.matrix.i-d.ralston-mimi-linearized-matrix.02/invite/:txnId</tt>
when testing against other Linearized Matrix implementations. This string may be updated later to
account for breaking changes.</t>
            <t><strong>TODO</strong>: Remove implementation notes.</t>
            <t><strong>Rate-limited</strong>: Yes.</t>
            <t><strong>Authentication required</strong>: Yes.</t>
            <t>Path parameters:</t>
            <ul spacing="normal">
              <li>
                <tt>:txnId</tt> - the transaction ID (<xref target="int-txn-ids"/>) for the request. The event ID (<xref target="int-pdu"/>) of the
contained event may be a good option as a readily-available transaction ID.</li>
            </ul>
            <t>Query parameters: None applicable.</t>
            <t>Request body:</t>
            <sourcecode type="json"><![CDATA[
{
   "event": {/* the event */},
   "invite_room_state": [/* stripped state events */],
   "room_version": "I.1"
}
]]></sourcecode>
            <t><tt>invite_room_state</tt> are the stripped state events (<xref target="int-stripped-state"/>) for the room's current
state. <tt>invite_room_state</tt> <bcp14>MAY</bcp14> be excluded from the request body.</t>
            <t><tt>room_version</tt> is the room version identifier (<xref target="int-room-versions"/>) the room is currently using. This
will be retrieved from the <tt>m.room.create</tt> (<xref target="int-ev-create"/>) state event.</t>
            <t><tt>event</tt> is the event (LPDU or PDU; <xref target="int-pdu"/>) representing the invite for the user. It <bcp14>MUST</bcp14> meet
the following criteria, in addition to the requirements of an event:</t>
            <ul spacing="normal">
              <li>
                <tt>type</tt> <bcp14>MUST</bcp14> be <tt>m.room.member</tt>.</li>
              <li>
                <tt>membership</tt> in <tt>content</tt> <bcp14>MUST</bcp14> be <tt>invite</tt>.</li>
            </ul>
            <t>When the hub server receives a request from a participant server, it <bcp14>MUST</bcp14> populate the event fields
before sending the event to the intended recipient. This means running the event through the normal
event authorization steps (<xref target="int-auth-rules"/>). If the invite is not allowed under the auth rules,
the server responds with a <tt>403 Forbidden</tt> HTTP status code and <tt>M_FORBIDDEN</tt> error code (<xref target="int-transport-errors"/>).</t>
            <t>The intended recipient of the invite can be identified by the <tt>state_key</tt> on the event.</t>
            <t>If the invite event is valid, the hub server sends its own <tt>POST /_matrix/federation/v3/invite/:txnId</tt>
request to the target server (if the target server is not itself) with the fully-formed event. The
transaction ID does not need to be the same as the original inbound request.</t>
            <t>All responses from the target server <bcp14>SHOULD</bcp14> be proxied verbatim to the original requesting server
through the hub. The hub <bcp14>SHOULD</bcp14> discard what appears to be excess data before sending a response
to the requesting server, such as extra or large fields. If the target server does not respond with
JSON, an error response (<xref target="int-transport-errors"/>) <bcp14>SHOULD</bcp14> be sent by the hub instead.</t>
            <t>The target server then ensures it can support the room version. If it can't, it responds with an HTTP
status code of <tt>400 Bad Request</tt> and error code of <tt>M_INCOMPATIBLE_ROOM_VERSION</tt> (<xref target="int-transport-errors"/>).</t>
            <t>Then, the target server runs any implementation-specific checks as needed, such as those implied by
<xref target="int-user-privacy"/> and <xref target="int-spam"/>, rejecting/erroring the request as needed.</t>
            <t>Finally, the target server signs the event and returns it to the hub. The hub server appends this signed
event to the room and sends it out to all participants in the room. The signed event is additionally
returned to the originating participant server, though it also receives the event through the <tt>/send</tt>
API (<xref target="int-api-send-txn"/>).</t>
            <t><tt>200 OK</tt> response:</t>
            <sourcecode type="json"><![CDATA[
{
   "pdu": {/* signed fully-formed event */}
}
]]></sourcecode>
            <t>Note that by the time a response is received, the event is signed 2-3 times:</t>
            <ol spacing="normal" type="1"><li>The LPDU signature from the participant server (<xref target="int-lpdu"/>).</li>
              <li>The hub's signature on the PDU (<xref target="int-pdu"/>).</li>
              <li>The target server's signature on the PDU.</li>
            </ol>
            <t>These signatures are to satisfy the auth rules (<xref target="int-auth-rules"/>).</t>
            <t><strong>TODO</strong>: Do we ever validate the target server's signature? Do we need to?</t>
          </section>
          <section anchor="int-transport-leaves">
            <name>Rejecting Invites and Leaves</name>
            <t>Rejecting an invite is done by making a membership transition of <tt>invite</tt> to <tt>leave</tt> through the user's
<tt>m.room.member</tt> (<xref target="int-ev-member"/>) event. The membership event <bcp14>SHOULD</bcp14> be sent directly when it can and
use the "make and send" handshake (<xref target="int-transport-make-and-send"/>) described here otherwise.</t>
            <t>This same approach is additionally used to retract a knock (<xref target="int-transport-knocks"/>).</t>
            <section anchor="int-api-make-leave">
              <name><tt>GET /_matrix/federation/v1/make_leave/:roomId/:userId</tt></name>
              <t>Requests an event template from the hub server for a room. The requesting server will have already
been checked to ensure it supports the room version as part of the invite process prior to making a
call to this endpoint.</t>
              <t><strong>Rate-limited</strong>: Yes.</t>
              <t><strong>Authentication required</strong>: Yes.</t>
              <t>Path parameters:</t>
              <ul spacing="normal">
                <li>
                  <tt>:roomId</tt> - the room ID (<xref target="int-room-id"/>) to get a template for.</li>
                <li>
                  <tt>:userId</tt> - the user ID (<xref target="int-user-id"/>) attempting to leave.</li>
              </ul>
              <t>Query parameters: None applicable.</t>
              <t>Request body: None applicable.</t>
              <t><tt>200 OK</tt> response:</t>
              <sourcecode type="json"><![CDATA[
{
   "event": {/* partial LPDU */},
   "room_version": "I.1"
}
]]></sourcecode>
              <t>The response body's <tt>event</tt> <bcp14>MUST</bcp14> be a partial LPDU (<xref target="int-lpdu"/>) with at least the following fields:</t>
              <ul spacing="normal">
                <li>
                  <tt>type</tt> of <tt>m.room.member</tt>.</li>
                <li>
                  <tt>state_key</tt> of <tt>:userId</tt> from the path parameters.</li>
                <li>
                  <tt>sender</tt> of <tt>:userId</tt> from the path parameters.</li>
                <li>
                  <tt>content</tt> of <tt>{"membership": "leave"}</tt>.</li>
              </ul>
              <t>The sending server <bcp14>SHOULD</bcp14> remove all other fields before using the event in a <tt>send_leave</tt> (<xref target="int-api-send-leave"/>).</t>
              <t>If the receiving server is not the hub server for the room ID, an HTTP status code of <tt>400 Bad Request</tt>
and error code <tt>M_WRONG_SERVER</tt> (<xref target="int-transport-errors"/>) is returned. If the room ID is not known,
<tt>404 Not Found</tt> is used as an HTTP status code and <tt>M_NOT_FOUND</tt> as an error code (<xref target="int-transport-errors"/>).</t>
              <t>If the user does not have permission to leave under the auth rules (<xref target="int-auth-rules"/>), a <tt>403 Forbidden</tt>
HTTP status code is returned alongside an error code of <tt>M_FORBIDDEN</tt> (<xref target="int-transport-errors"/>). For example,
if the user does not have a pending invite, is not a member of the room, or is banned.</t>
              <t>If the sending server does not recognize the returned <tt>room_version</tt>, it <bcp14>SHOULD NOT</bcp14> attempt to populate
the template or use the <tt>send_leave</tt> (<xref target="int-api-send-leave"/>) endpoint.</t>
            </section>
            <section anchor="int-api-send-leave">
              <name><tt>POST /_matrix/federation/v3/send_leave/:txnId</tt></name>
              <t>Sends a leave membership event to the room through a hub server.</t>
              <t><strong>Implementation note</strong>: Currently this endpoint doesn't actually exist. Use
<tt>POST /_matrix/federation/unstable/org.matrix.i-d.ralston-mimi-linearized-matrix.02/send_leave/:txnId</tt>
when testing against other Linearized Matrix implementations. This string may be updated later to
account for breaking changes.</t>
              <t><strong>TODO</strong>: Remove implementation notes.</t>
              <t><strong>Rate-limited</strong>: Yes.</t>
              <t><strong>Authentication required</strong>: Yes.</t>
              <t>Path parameters:</t>
              <ul spacing="normal">
                <li>
                  <tt>:txnId</tt> - the transaction ID (<xref target="int-txn-ids"/>) for the request. The event ID (<xref target="int-pdu"/>) of the
contained event may be a good option as a readily-available transaction ID.</li>
              </ul>
              <t>Query parameters: None applicable.</t>
              <t>Request body:</t>
              <sourcecode type="json"><![CDATA[
{
   /* LPDU created from make_leave template */
}
]]></sourcecode>
              <t><tt>200 OK</tt> response:</t>
              <sourcecode type="json"><![CDATA[
{/* deliberately empty object */}
]]></sourcecode>
              <t>The errors responses from <tt>/make_leave</tt> (<xref target="int-api-make-leave"/>) are copied here. Servers should note
that room state <bcp14>MAY</bcp14> change between a <tt>/make_leave</tt> and <tt>/send_leave</tt>, potentially in a way which
prevents the user from leaving the room suddenly. For example, the invited user may have been banned
from the room.</t>
            </section>
          </section>
        </section>
        <section anchor="int-transport-joins">
          <name>Joins</name>
          <t>Joins for users <bcp14>SHOULD</bcp14> be sent directly whenever possible, and otherwise use the "make and send" handshake
(<xref target="int-transport-make-and-send"/>) approach described here.</t>
          <section anchor="int-api-make-join">
            <name><tt>GET /_matrix/federation/v1/make_join/:roomId/:userId</tt></name>
            <t>Requests an event template from the hub server for a room. This is done to ensure the requesting
server supports the room's version (<xref target="int-room-versions"/>), as well as hint at the event format
needed to participate.</t>
            <t>Note that this endpoint is extremely similar to <tt>/make_leave</tt> (<xref target="int-api-make-leave"/>).</t>
            <t><strong>Rate-limited</strong>: Yes.</t>
            <t><strong>Authentication required</strong>: Yes.</t>
            <t>Path parameters:</t>
            <ul spacing="normal">
              <li>
                <tt>:roomId</tt> - the room ID (<xref target="int-room-id"/>) to get a template for.</li>
              <li>
                <tt>:userId</tt> - the user ID (<xref target="int-user-id"/>) attempting to join.</li>
            </ul>
            <t>Query parameters:</t>
            <ul spacing="normal">
              <li>
                <tt>ver</tt> (string; required; repeated) - The room versions (<xref target="int-room-versions"/>) the sending server
supports.</li>
            </ul>
            <t>Request body: None applicable.</t>
            <t><tt>200 OK</tt> response:</t>
            <sourcecode type="json"><![CDATA[
{
   /* partial LPDU */
}
]]></sourcecode>
            <t>The response body <bcp14>MUST</bcp14> be a partial LPDU (<xref target="int-lpdu"/>) with at least the following fields:</t>
            <ul spacing="normal">
              <li>
                <tt>type</tt> of <tt>m.room.member</tt>.</li>
              <li>
                <tt>state_key</tt> of <tt>:userId</tt> from the path parameters.</li>
              <li>
                <tt>sender</tt> of <tt>:userId</tt> from the path parameters.</li>
              <li>
                <tt>content</tt> of <tt>{"membership": "join"}</tt>.</li>
            </ul>
            <t>The sending server <bcp14>SHOULD</bcp14> remove all other fields before using the event in a <tt>send_join</tt> (<xref target="int-api-send-join"/>).</t>
            <t>If the receiving server is not the hub server for the room ID, an HTTP status code of <tt>400 Bad Request</tt>
and error code <tt>M_WRONG_SERVER</tt> (<xref target="int-transport-errors"/>) is returned. If the room ID is not known,
<tt>404 Not Found</tt> is used as an HTTP status code and <tt>M_NOT_FOUND</tt> as an error code (<xref target="int-transport-errors"/>).</t>
            <t>If the user does not have permission to join under the auth rules (<xref target="int-auth-rules"/>), a <tt>403 Forbidden</tt>
HTTP status code is returned alongside an error code of <tt>M_FORBIDDEN</tt> (<xref target="int-transport-errors"/>).</t>
            <t>If the room version is not one of the <tt>ver</tt> strings the sender supplied, a <tt>400 Bad Request</tt> HTTP status
code is returned alongside <tt>M_INCOMPATIBLE_ROOM_VERSION</tt> error code (<xref target="int-transport-errors"/>).</t>
          </section>
          <section anchor="int-api-send-join">
            <name><tt>POST /_matrix/federation/v3/send_join/:txnId</tt></name>
            <t>Sends a join membership event to the room through a hub server.</t>
            <t>Note that this endpoint is extremely similar to <tt>/send_leave</tt> (<xref target="int-api-send-leave"/>).</t>
            <t><strong>Implementation note</strong>: Currently this endpoint doesn't actually exist. Use
<tt>POST /_matrix/federation/unstable/org.matrix.i-d.ralston-mimi-linearized-matrix.02/send_join/:txnId</tt>
when testing against other Linearized Matrix implementations. This string may be updated later to
account for breaking changes.</t>
            <t><strong>TODO</strong>: Remove implementation notes.</t>
            <t><strong>Rate-limited</strong>: Yes.</t>
            <t><strong>Authentication required</strong>: Yes.</t>
            <t>Path parameters:</t>
            <ul spacing="normal">
              <li>
                <tt>:txnId</tt> - the transaction ID (<xref target="int-txn-ids"/>) for the request. The event ID (<xref target="int-pdu"/>) of the
contained event may be a good option as a readily-available transaction ID.</li>
            </ul>
            <t>Query parameters: None applicable.</t>
            <t><strong>TODO</strong>: Incorporate faster joins work.</t>
            <t>Request body:</t>
            <sourcecode type="json"><![CDATA[
{
   /* LPDU created from make_join template */
}
]]></sourcecode>
            <t><tt>200 OK</tt> response:</t>
            <sourcecode type="json"><![CDATA[
{
   "state": [/* events */],
   "auth_chain": [/* events */],
   "event": {/* fully-formed event */}
}
]]></sourcecode>
            <t><tt>state</tt> is the current room state, consisting of the events which represent "current state" (<xref target="int-state-events"/>)
prior to considering the membership state change. <tt>auth_chain</tt> consists of the events which make up
the <tt>auth_events</tt> (<xref target="int-auth-selection"/>) for the <tt>state</tt> events, and the <tt>auth_events</tt> of those events,
recursively. <tt>event</tt> will be the fully-formed PDU (<xref target="int-pdu"/>) that is sent by the hub to all other
participants in the room.</t>
            <t>The errors responses from <tt>/make_join</tt> (<xref target="int-api-make-join"/>) are copied here (with the exception
of <tt>M_INCOMPATIBLE_ROOM_VERSION</tt>, as the server already checked for support). Servers should note
that room state <bcp14>MAY</bcp14> change between a <tt>/make_join</tt> and <tt>/send_join</tt>, potentially in a way which
prevents the user from joining the room suddenly.</t>
          </section>
        </section>
        <section anchor="int-transport-knocks">
          <name>Knocks</name>
          <t>To knock on a room is to request an invite to that room. It is not a join, nor is it an invite itself.
"Approving" the knock is done by inviting the user, which is typically only allowed by moderators in
these rooms. "Denying" the knock is done through kicking (sending a <tt>leave</tt> membership) or banning the
user. If the user is kicked, they may re-send their knock.</t>
          <t>Senders should note the <tt>reason</tt> field on <tt>m.room.member</tt> events (<xref target="int-ev-member"/>) to provide context
for their knock.</t>
          <t>To retract a knock, the sending server uses the same APIs as rejecting an invite (<xref target="int-transport-leaves"/>).</t>
          <t>Where possible, knocks from users <bcp14>SHOULD</bcp14> be sent directly, otherwise using the "make and send" handshake
(<xref target="int-transport-make-and-send"/>) approach described here.</t>
          <section anchor="int-api-make-knock">
            <name><tt>GET /_matrix/federation/v1/make_knock/:roomId/:userId</tt></name>
            <t>Requests an event template from the hub server for a room. This is done to ensure the requesting
server supports the room's version (<xref target="int-room-versions"/>), as well as hint at the event format
needed to participate.</t>
            <t>Note that this endpoint is almost exactly the same as <tt>/make_join</tt> (<xref target="int-api-make-join"/>).</t>
            <t><strong>TODO</strong>: It's so similar to make_join that we should probably just combine the two endpoints.</t>
            <t><strong>Rate-limited</strong>: Yes.</t>
            <t><strong>Authentication required</strong>: Yes.</t>
            <t>Path parameters:</t>
            <ul spacing="normal">
              <li>
                <tt>:roomId</tt> - the room ID (<xref target="int-room-id"/>) to get a template for.</li>
              <li>
                <tt>:userId</tt> - the user ID (<xref target="int-user-id"/>) attempting to knock.</li>
            </ul>
            <t>Query parameters:</t>
            <ul spacing="normal">
              <li>
                <tt>ver</tt> (string; required; repeated) - The room versions (<xref target="int-room-versions"/>) the sending server
supports.</li>
            </ul>
            <t>Request body: None applicable.</t>
            <t><tt>200 OK</tt> response:</t>
            <sourcecode type="json"><![CDATA[
{
   /* partial LPDU */
}
]]></sourcecode>
            <t>The response body <bcp14>MUST</bcp14> be a partial LPDU (<xref target="int-lpdu"/>) with at least the following fields:</t>
            <ul spacing="normal">
              <li>
                <tt>type</tt> of <tt>m.room.member</tt>.</li>
              <li>
                <tt>state_key</tt> of <tt>:userId</tt> from the path parameters.</li>
              <li>
                <tt>sender</tt> of <tt>:userId</tt> from the path parameters.</li>
              <li>
                <tt>content</tt> of <tt>{"membership": "knock"}</tt>.</li>
            </ul>
            <t>The sending server <bcp14>SHOULD</bcp14> remove all other fields before using the event in a <tt>send_knock</tt> (<xref target="int-api-send-knock"/>).</t>
            <t>If the receiving server is not the hub server for the room ID, an HTTP status code of <tt>400 Bad Request</tt>
and error code <tt>M_WRONG_SERVER</tt> (<xref target="int-transport-errors"/>) is returned. If the room ID is not known,
<tt>404 Not Found</tt> is used as an HTTP status code and <tt>M_NOT_FOUND</tt> as an error code (<xref target="int-transport-errors"/>).</t>
            <t>If the user does not have permission to knock under the auth rules (<xref target="int-auth-rules"/>), a <tt>403 Forbidden</tt>
HTTP status code is returned alongside an error code of <tt>M_FORBIDDEN</tt> (<xref target="int-transport-errors"/>).</t>
            <t>If the room version is not one of the <tt>ver</tt> strings the sender supplied, a <tt>400 Bad Request</tt> HTTP status
code is returned alongside <tt>M_INCOMPATIBLE_ROOM_VERSION</tt> error code (<xref target="int-transport-errors"/>).</t>
          </section>
          <section anchor="int-api-send-knock">
            <name><tt>POST /_matrix/federation/v3/send_knock/:txnId</tt></name>
            <t>Sends a knock membership event to the room through a hub server.</t>
            <t><strong>Implementation note</strong>: Currently this endpoint doesn't actually exist. Use
<tt>POST /_matrix/federation/unstable/org.matrix.i-d.ralston-mimi-linearized-matrix.02/send_knock/:txnId</tt>
when testing against other Linearized Matrix implementations. This string may be updated later to
account for breaking changes.</t>
            <t><strong>TODO</strong>: Remove implementation notes.</t>
            <t><strong>Rate-limited</strong>: Yes.</t>
            <t><strong>Authentication required</strong>: Yes.</t>
            <t>Path parameters:</t>
            <ul spacing="normal">
              <li>
                <tt>:txnId</tt> - the transaction ID (<xref target="int-txn-ids"/>) for the request. The event ID (<xref target="int-pdu"/>) of the
contained event may be a good option as a readily-available transaction ID.</li>
            </ul>
            <t>Query parameters: None applicable.</t>
            <t>Request body:</t>
            <sourcecode type="json"><![CDATA[
{
   /* LPDU created from make_knock template */
}
]]></sourcecode>
            <t><tt>200 OK</tt> response:</t>
            <sourcecode type="json"><![CDATA[
{
   "stripped_state": [
      /* stripped state events */
   ]
}
]]></sourcecode>
            <t><tt>stripped_state</tt> are the stripped state events (<xref target="int-stripped-state"/>) for the room.</t>
            <t>The errors responses from <tt>/make_knock</tt> (<xref target="int-api-make-knock"/>) are copied here (with the exception
of <tt>M_INCOMPATIBLE_ROOM_VERSION</tt>, as the server already checked for support). Servers should note
that room state <bcp14>MAY</bcp14> change between a <tt>/make_knock</tt> and <tt>/send_knock</tt>, potentially in a way which
prevents the user from knocking upon the room suddenly.</t>
          </section>
        </section>
      </section>
      <section anchor="content-repository">
        <name>Content Repository</name>
        <t>The content repository, sometimes called the "media repo", is where user-generated content is stored
for referencing within an encrypted message.</t>
        <t><strong>TODO</strong>: Complete this section. We want auth/event linking from MSC3911 and MSC3916.</t>
        <t><strong>TODO</strong>: Spell out that content is images, videos, files, etc.</t>
      </section>
      <section anchor="int-transport-edus">
        <name>Ephemeral Data Units (EDUs)</name>
        <t>EDUs are sent out of band from rooms and are only persisted for exactly as long as they are needed.
For example, once a to-device (<xref target="int-transport-to-device"/>) message is delivered to a client, the
server may easily be able to delete its copy of the message.</t>
        <t>EDUs contain the following mandatory fields:</t>
        <sourcecode type="json"><![CDATA[
{
   "type": "m.room.encrypted",
   "sender": "@alice:example.org",
   "content": {
      /* type-specific content */
   }
}
]]></sourcecode>
        <t>The <tt>type</tt> is similar to an event type (<xref target="int-pdu"/>) and ultimately describes the schema for the
<tt>content</tt>.</t>
        <t><tt>sender_id</tt> is the user ID (<xref target="int-user-id"/>) which is sending the EDU. Typically, clients will not
generate EDUs directly. Instead, the server will convert a client's request into an EDU for sending
to a remote server, where that server then unpacks the EDU before delivering it to local devices.</t>
        <t>Because EDUs are not sent in the context of a room, even if an MLS <tt>Welcome</tt> message is being sent
for a room, servers <bcp14>MUST</bcp14> send the EDUs directly to the target server with the send API (<xref target="int-api-send-txn"/>).</t>
        <t>In this document, EDUs are only used for to-device messages (<xref target="int-transport-to-device"/>) and device
list changes (<xref target="int-transport-devices"/>), but could be used for read/delivery receipts, typing notifications,
and more in future. This may necessitate routing EDUs through the hub rather than using full-mesh fanout.</t>
        <t><strong>TODO</strong>: Address EDU fanout; Document the implied missing features (receipts, typing notifs).</t>
      </section>
      <section anchor="int-transport-mls">
        <name>MLS</name>
        <t><strong>TODO</strong>: This section. Talk about to-device messaging, device management/querying/key claiming, etc.</t>
        <t>There are several endpoints required by this document's MLS implementation (<xref target="int-mls-considerations"/>),
largely around device management for each device's signing key, claiming key packages for those devices,
and sending messages (<tt>Welcome</tt> in particular) after using a key package.</t>
        <section anchor="int-transport-devices">
          <name>Device Info Publishing</name>
          <t>When a user creates a new encryption-capable device, or removes one, a "device list update" is sent
to all servers the user shares a room with. The receiving servers then determine which local clients
need to be made aware of the device list change and sends the information to them. This is primarily
used by this document's MLS implementation (<xref target="int-mls-considerations"/>) to indicate to other devices
that either a new possible device has come online or that another needs to be removed from some MLS
groups due to being deleted.</t>
          <t>Typically, a device is created by a user when they log in to a new session. Similarly, a device is
deleted/removed when they log out of that client.</t>
          <t>The device list update takes the shape of an EDU (<xref target="int-transport-edus"/>), as such:</t>
          <sourcecode type="json"><![CDATA[
{
   "type": "m.device_list_update",
   "sender_id": "@alice:example.org",
   "content": {
      "changed": [/* Device Objects */],
      "removed": [/* Device IDs */]
   }
}
]]></sourcecode>
          <t>The device objects are the same as in the response for <tt>/user/:userId/device/:deviceId</tt> (<xref target="int-api-get-device"/>),
indicating that either a new device was created or that information about a previous device has changed.</t>
          <t><strong>TODO</strong>: Matrix's <tt>m.device_list_update</tt> EDU is <em>very</em> different from this, and relatively complicated.
Do we actually need a <tt>stream_id</tt>, like in Matrix? Do we then need the <tt>/devices</tt> endpoint?</t>
          <section anchor="int-api-get-device">
            <name><tt>GET /_matrix/federation/v1/user/:userId/device/:deviceId</tt></name>
            <t>Retrieves information about a specific device for a user. This request does not go via a hub, instead
going directly to the server which owns the <tt>:userId</tt>.</t>
            <t><strong>Implementation note</strong>: Currently this endpoint doesn't actually exist. Use
<tt>PUT /_matrix/federation/unstable/org.matrix.i-d.ralston-mimi-linearized-matrix.02/user/:userId/device/:deviceId</tt>
when testing against other Linearized Matrix implementations. This string may be updated later to
account for breaking changes.</t>
            <t><strong>TODO</strong>: Remove implementation notes.</t>
            <t><strong>Rate-limited</strong>: Yes.</t>
            <t><strong>Authentication required</strong>: Yes.</t>
            <t>Path parameters:</t>
            <ul spacing="normal">
              <li>
                <tt>:userId</tt> - the user ID (<xref target="int-user-id"/>) who owns the device.</li>
              <li>
                <tt>:deviceId</tt> - the device ID (<xref target="int-device-id"/>) to get information about.</li>
            </ul>
            <t>Query parameters: None applicable.</t>
            <t>Request body: None applicable.</t>
            <t><tt>200 OK</tt> response:</t>
            <sourcecode type="json"><![CDATA[
{
   "device_id": "ABCDEF",
   "user_id": "@alice:example.org",
   "algorithms": [
      "m.mls.v1.dhkemx25519-aes128gcm-sha256-ed25519"
   ],
   "keys": {
      "m.mls.v1.credential.ed25519:ABCDEF":
         "<unpadded base64 BasicCredential>"
   },
   "signatures": {
      "@alice:example.org": {
         "m.mls.v1.credential.ed25519:ABCDEF":
            "<unpadded base64 signature>"
      }
   }
}
]]></sourcecode>
            <t>Note that the response is the same object the device itself signed/created in <xref target="int-mls-credentials"/>.</t>
            <t>If the user ID does not belong the receiving server, a <tt>404 Not Found</tt> HTTP status code is returned
with error code <tt>M_NOT_FOUND</tt> (<xref target="int-transport-errors"/>). The same applies if the user ID does not
exist, or the user does not have the device ID requested.</t>
          </section>
        </section>
        <section anchor="int-transport-to-device">
          <name>To-Device Messaging</name>
          <t>To-device messaging is an ability to send information directly to another device, typically to carry
MLS <tt>Welcome</tt> messages and similar. They are sent as EDUs (<xref target="int-transport-edus"/>), one per receipient
device and payload:</t>
          <sourcecode type="json"><![CDATA[
{
   "type": "m.direct_to_device",
   "sender": "@alice:example.org",
   "content": {
      "target": "@bob:example.org",
      "target_device": "ABCD",
      "message_type": "m.room.encrypted",
      "message": {
         /* message_type-specific schema */
      }
   }
}
]]></sourcecode>
          <t><tt>target</tt> and <tt>target_device</tt> denote the destination user ID (<xref target="int-user-id"/>) and device ID (<xref target="int-device-id"/>)
for that user. This EDU <bcp14>MUST</bcp14> be sent to the server denoted by the target user ID. If the target user
doesn't exist or doesn't have a device with the ID described, the receiving server drops/ignores the
EDU.</t>
          <t>See <xref target="int-mls-add-remove"/> for an example of a to-device message being used.</t>
        </section>
        <section anchor="int-transport-key-claim">
          <name>One Time Key Claiming</name>
          <t>To enable two devices to communicate, they need to claim a key package (<xref target="int-mls-key-packages"/>)
for the other device. These key packages are also called "one time keys". This is done through the
following endpoint.</t>
          <section anchor="post-matrixfederationv1userkeysclaim">
            <name><tt>POST /_matrix/federation/v1/user/keys/claim</tt></name>
            <t>Claims one time keys for devices. This request does not go via a hub, instead going directly to the
server which owns the given user IDs.</t>
            <t><strong>Rate-limited</strong>: Yes.</t>
            <t><strong>Authentication required</strong>: Yes.</t>
            <t>Path parameters: None applicable.</t>
            <t>Query parameters: None applicable.</t>
            <t>Request body:</t>
            <sourcecode type="json"><![CDATA[
{
  "one_time_keys": {
    "@alice:example.org": {
      "ABCD":
        "m.mls.v1.key_package.dhkemx25519-aes128gcm-sha256-ed25519"
    }
  }
}
]]></sourcecode>
            <t><tt>one_time_keys</tt> <bcp14>MUST</bcp14> be specified and is a map of user ID (<xref target="int-user-id"/>) to device ID (<xref target="int-device-id"/>)
to algorithm for the key package to claim. Currently the only expected algorithm is defined by <xref target="int-mls-key-packages"/>.</t>
            <t>Any user IDs which don't belong to the receiving server, or which don't exist, are ignored. The same
applies for device IDs for which the user doesn't have.</t>
            <t><tt>200 OK</tt> response:</t>
            <sourcecode type="json"><![CDATA[
{
  "one_time_keys": {
    "@alice:example.org": {
      "ABCD": {
        "m.mls.v1.key_package.dhkemx25519-aes128gcm-sha256-ed25519":
          "<unpadded base64 encoded key package>"
      }
    }
  }
}
]]></sourcecode>
            <t>Like the request body, <tt>one_time_keys</tt> <bcp14>MUST</bcp14> be specified (but <bcp14>MAY</bcp14> be empty) and is a map of requested
user ID to requested device ID to algorithm name. The value for the algorithm name is dependent on the
algorithm itself. For <tt>m.mls.v1.key_package.dhkemx25519-aes128gcm-sha256-ed25519</tt>, this is an unpadded
base64 (<xref target="int-unpadded-base64"/>) string representing the key package itself.</t>
            <t>Servers <bcp14>MUST NOT</bcp14> reuse a device's one time key, unless that key permits it. For example, MLS's "last
resort" key <bcp14>MAY</bcp14> be used multiple times, but <bcp14>SHOULD</bcp14> only be used if no other one time keys remain for
the device. Servers <bcp14>MUST NOT</bcp14> use an expired key.</t>
            <t>Typically, the server will inform the device that a key was used so the device can upload additional
keys. See <xref target="int-mls-key-packages"/> for further implementation-related concerns.</t>
          </section>
        </section>
      </section>
      <section anchor="todo-remainder-of-transport">
        <name>TODO: Remainder of Transport</name>
        <t><strong>TODO</strong>: This section.</t>
        <t>Topics:</t>
        <ul spacing="normal">
          <li>More EDUs (typing notifications, receipts, presence)</li>
          <li>Query APIs (alias resolution, profiles)</li>
          <li>Other Encryption APIs??</li>
          <li>Server ACLs? (this probably should become part of the auth rules)</li>
        </ul>
        <t>Notably/deliberately missing APIs are:</t>
        <ul spacing="normal">
          <li>
            <tt>get_missing_events</tt> - this is used by DAG servers only</li>
          <li>Public room directory</li>
          <li>Timestamp-to-event API</li>
          <li>All of 3rd party invites</li>
          <li>All of Spaces</li>
          <li>OpenID API</li>
        </ul>
        <section anchor="open-questions">
          <name>Open Questions</name>
          <ul spacing="normal">
            <li>Should we include <tt>/_matrix/federation/v1/version</tt> in here? It's used by federation testers, but not
really anything else.</li>
          </ul>
        </section>
      </section>
    </section>
    <section anchor="int-user-privacy">
      <name>User Privacy</name>
      <t><strong>TODO</strong>: Fully complete this section.</t>
      <t>Messaging providers may have user-level settings to prevent unexpected or unwarranted invites, such
as automatically blocking invites from non-contacts. This setting can be upheld by returning an error
on <tt>POST /_matrix/federation/v3/invite/:txnId</tt> (<xref target="int-api-invite"/>), and by having the server (optionally)
auto-decline any invites received directly through <tt>PUT /_matrix/federation/v2/send/:txnId</tt> (<xref target="int-api-send-txn"/>).
See <xref target="int-transport-leaves"/> for more information on rejecting invites.</t>
    </section>
    <section anchor="int-spam">
      <name>Spam Prevention</name>
      <t><strong>TODO</strong>: Fully complete this section.</t>
      <t><strong>TODO</strong>: Talk about how to deal with spammy/unwanted invites.</t>
      <t>Servers <bcp14>MAY</bcp14> temporarily or permanently block a room entirely by using the room ID. Typically, when a
room becomes blocked, all local users will be removed from the room using <tt>m.room.member</tt> events with
<tt>membership</tt> of <tt>leave</tt> (<xref target="int-ev-member"/>). Then, any time the server receives a request for that
room ID it can reject it with an error response (<xref target="int-transport-errors"/>).</t>
      <t>Blocking a room does not block it from all servers, but does prevent users on a server from accessing
the content within. This is primarily useful to remove a server from rooms where abusive/illegal content
is shared.</t>
    </section>
    <section anchor="security-considerations">
      <name>Security Considerations</name>
      <t><strong>TODO</strong>: Expand upon this section.</t>
      <t>With the combined use of MLS and server-side enforcement, the server theoretically has an ability to
add a malicious device to the MLS group and receive decryptable messages. Authenticity of devices needs
to be established to ensure a user's devices are actually a user's devices.</t>
      <t><strong>TODO</strong>: Should we bring Matrix's cross-signing here?</t>
      <t>Servers retain the ability to control/puppet their own users due to no strong cryptographic link between
the sending device and the event which gets emitted.</t>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <t>The <tt>m.*</tt> namespace likely needs formal registration in some capacity.</t>
      <t>The <tt>I.*</tt> namespace likely needs formal registration in some capacity.</t>
      <t>Port 8448 may need formal registration.</t>
      <t>The SRV service name <tt>matrix</tt> may need re-registering, or a new service name assigned.</t>
      <t>The <tt>.well-known/matrix</tt> namespace is already registered for use by The Matrix.org Foundation C.I.C.</t>
    </section>
  </middle>
  <back>
    <references>
      <name>References</name>
      <references>
        <name>Normative References</name>
        <reference anchor="RFC6125">
          <front>
            <title>Representation and Verification of Domain-Based Application Service Identity within Internet Public Key Infrastructure Using X.509 (PKIX) Certificates in the Context of Transport Layer Security (TLS)</title>
            <author fullname="P. Saint-Andre" initials="P." surname="Saint-Andre"/>
            <author fullname="J. Hodges" initials="J." surname="Hodges"/>
            <date month="March" year="2011"/>
            <abstract>
              <t>Many application technologies enable secure communication between two entities by means of Internet Public Key Infrastructure Using X.509 (PKIX) certificates in the context of Transport Layer Security (TLS). This document specifies procedures for representing and verifying the identity of application services in such interactions. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="6125"/>
          <seriesInfo name="DOI" value="10.17487/RFC6125"/>
        </reference>
        <reference anchor="RFC4648">
          <front>
            <title>The Base16, Base32, and Base64 Data Encodings</title>
            <author fullname="S. Josefsson" initials="S." surname="Josefsson"/>
            <date month="October" year="2006"/>
            <abstract>
              <t>This document describes the commonly used base 64, base 32, and base 16 encoding schemes. It also discusses the use of line-feeds in encoded data, use of padding in encoded data, use of non-alphabet characters in encoded data, use of different encoding alphabets, and canonical encodings. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="4648"/>
          <seriesInfo name="DOI" value="10.17487/RFC4648"/>
        </reference>
        <reference anchor="RFC1123">
          <front>
            <title>Requirements for Internet Hosts - Application and Support</title>
            <author fullname="R. Braden" initials="R." role="editor" surname="Braden"/>
            <date month="October" year="1989"/>
            <abstract>
              <t>This RFC is an official specification for the Internet community. It incorporates by reference, amends, corrects, and supplements the primary protocol standards documents relating to hosts. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="STD" value="3"/>
          <seriesInfo name="RFC" value="1123"/>
          <seriesInfo name="DOI" value="10.17487/RFC1123"/>
        </reference>
        <reference anchor="I-D.ietf-mls-protocol">
          <front>
            <title>The Messaging Layer Security (MLS) Protocol</title>
            <author fullname="Richard Barnes" initials="R." surname="Barnes">
              <organization>Cisco</organization>
            </author>
            <author fullname="Benjamin Beurdouche" initials="B." surname="Beurdouche">
              <organization>Inria &amp; Mozilla</organization>
            </author>
            <author fullname="Raphael Robert" initials="R." surname="Robert">
              <organization>Phoenix R&amp;D</organization>
            </author>
            <author fullname="Jon Millican" initials="J." surname="Millican">
              <organization>Meta Platforms</organization>
            </author>
            <author fullname="Emad Omara" initials="E." surname="Omara">
              <organization>Google</organization>
            </author>
            <author fullname="Katriel Cohn-Gordon" initials="K." surname="Cohn-Gordon">
              <organization>University of Oxford</organization>
            </author>
            <date day="27" month="March" year="2023"/>
            <abstract>
              <t>   Messaging applications are increasingly making use of end-to-end
   security mechanisms to ensure that messages are only accessible to
   the communicating endpoints, and not to any servers involved in
   delivering messages.  Establishing keys to provide such protections
   is challenging for group chat settings, in which more than two
   clients need to agree on a key but may not be online at the same
   time.  In this document, we specify a key establishment protocol that
   provides efficient asynchronous group key establishment with forward
   secrecy and post-compromise security for groups in size ranging from
   two to thousands.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ietf-mls-protocol-20"/>
        </reference>
        <reference anchor="I-D.ietf-mls-architecture">
          <front>
            <title>The Messaging Layer Security (MLS) Architecture</title>
            <author fullname="Benjamin Beurdouche" initials="B." surname="Beurdouche">
              <organization>Inria &amp; Mozilla</organization>
            </author>
            <author fullname="Eric Rescorla" initials="E." surname="Rescorla">
              <organization>Mozilla</organization>
            </author>
            <author fullname="Emad Omara" initials="E." surname="Omara">
              <organization>Google</organization>
            </author>
            <author fullname="Srinivas Inguva" initials="S." surname="Inguva">
              <organization>Twitter</organization>
            </author>
            <author fullname="Alan Duric" initials="A." surname="Duric">
              <organization>Wire</organization>
            </author>
            <date day="16" month="December" year="2022"/>
            <abstract>
              <t>   The Messaging Layer Security (MLS) protocol (I-D.ietf-mls-protocol)
   specification has the role of defining a Group Key Agreement
   protocol, including all the cryptographic operations and
   serialization/deserialization functions necessary for scalable and
   secure group messaging.  The MLS protocol is meant to protect against
   eavesdropping, tampering, message forgery, and provide further
   properties such as Forward Secrecy (FS) and Post-Compromise Security
   (PCS) in the case of past or future device compromises.

   This document describes a general secure group messaging
   infrastructure and its security goals.  It provides guidance on
   building a group messaging system and discusses security and privacy
   tradeoffs offered by multiple security mechanisms that are part of
   the MLS protocol (e.g., frequency of public encryption key rotation).

   The document also provides guidance for parts of the infrastructure
   that are not standardized by the MLS Protocol document and left to
   the application or the infrastructure architects to design.

   While the recommendations of this document are not mandatory to
   follow in order to interoperate at the protocol level, they affect
   the overall security guarantees that are achieved by a messaging
   application.  This is especially true in case of active adversaries
   that are able to compromise clients, the delivery service, or the
   authentication service.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ietf-mls-architecture-10"/>
        </reference>
        <reference anchor="RFC2119">
          <front>
            <title>Key words for use in RFCs to Indicate Requirement Levels</title>
            <author fullname="S. Bradner" initials="S." surname="Bradner"/>
            <date month="March" year="1997"/>
            <abstract>
              <t>In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="2119"/>
          <seriesInfo name="DOI" value="10.17487/RFC2119"/>
        </reference>
        <reference anchor="RFC8174">
          <front>
            <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
            <author fullname="B. Leiba" initials="B." surname="Leiba"/>
            <date month="May" year="2017"/>
            <abstract>
              <t>RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="8174"/>
          <seriesInfo name="DOI" value="10.17487/RFC8174"/>
        </reference>
        <reference anchor="I-D.ralston-mimi-terminology">
          <front>
            <title>MIMI Terminology</title>
            <author fullname="Travis Ralston" initials="T." surname="Ralston">
              <organization>The Matrix.org Foundation C.I.C.</organization>
            </author>
            <date day="10" month="July" year="2023"/>
            <abstract>
              <t>   This document introduces a set of terminology to use when discussing
   or describing concepts within MIMI.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ralston-mimi-terminology-02"/>
        </reference>
        <reference anchor="RFC5234">
          <front>
            <title>Augmented BNF for Syntax Specifications: ABNF</title>
            <author fullname="D. Crocker" initials="D." role="editor" surname="Crocker"/>
            <author fullname="P. Overell" initials="P." surname="Overell"/>
            <date month="January" year="2008"/>
            <abstract>
              <t>Internet technical specifications often need to define a formal syntax. Over the years, a modified version of Backus-Naur Form (BNF), called Augmented BNF (ABNF), has been popular among many Internet specifications. The current specification documents ABNF. It balances compactness and simplicity with reasonable representational power. The differences between standard BNF and ABNF involve naming rules, repetition, alternatives, order-independence, and value ranges. This specification also supplies additional rule definitions and encoding for a core lexical analyzer of the type common to several Internet specifications. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="STD" value="68"/>
          <seriesInfo name="RFC" value="5234"/>
          <seriesInfo name="DOI" value="10.17487/RFC5234"/>
        </reference>
        <reference anchor="RFC3629">
          <front>
            <title>UTF-8, a transformation format of ISO 10646</title>
            <author fullname="F. Yergeau" initials="F." surname="Yergeau"/>
            <date month="November" year="2003"/>
            <abstract>
              <t>ISO/IEC 10646-1 defines a large character set called the Universal Character Set (UCS) which encompasses most of the world's writing systems. The originally proposed encodings of the UCS, however, were not compatible with many current applications and protocols, and this has led to the development of UTF-8, the object of this memo. UTF-8 has the characteristic of preserving the full US-ASCII range, providing compatibility with file systems, parsers and other software that rely on US-ASCII values but are transparent to other values. This memo obsoletes and replaces RFC 2279.</t>
            </abstract>
          </front>
          <seriesInfo name="STD" value="63"/>
          <seriesInfo name="RFC" value="3629"/>
          <seriesInfo name="DOI" value="10.17487/RFC3629"/>
        </reference>
        <reference anchor="RFC8259">
          <front>
            <title>The JavaScript Object Notation (JSON) Data Interchange Format</title>
            <author fullname="T. Bray" initials="T." role="editor" surname="Bray"/>
            <date month="December" year="2017"/>
            <abstract>
              <t>JavaScript Object Notation (JSON) is a lightweight, text-based, language-independent data interchange format. It was derived from the ECMAScript Programming Language Standard. JSON defines a small set of formatting rules for the portable representation of structured data.</t>
              <t>This document removes inconsistencies with other specifications of JSON, repairs specification errors, and offers experience-based interoperability guidance.</t>
            </abstract>
          </front>
          <seriesInfo name="STD" value="90"/>
          <seriesInfo name="RFC" value="8259"/>
          <seriesInfo name="DOI" value="10.17487/RFC8259"/>
        </reference>
        <reference anchor="RFC8032">
          <front>
            <title>Edwards-Curve Digital Signature Algorithm (EdDSA)</title>
            <author fullname="S. Josefsson" initials="S." surname="Josefsson"/>
            <author fullname="I. Liusvaara" initials="I." surname="Liusvaara"/>
            <date month="January" year="2017"/>
            <abstract>
              <t>This document describes elliptic curve signature scheme Edwards-curve Digital Signature Algorithm (EdDSA). The algorithm is instantiated with recommended parameters for the edwards25519 and edwards448 curves. An example implementation and test vectors are provided.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8032"/>
          <seriesInfo name="DOI" value="10.17487/RFC8032"/>
        </reference>
        <reference anchor="RFC8785">
          <front>
            <title>JSON Canonicalization Scheme (JCS)</title>
            <author fullname="A. Rundgren" initials="A." surname="Rundgren"/>
            <author fullname="B. Jordan" initials="B." surname="Jordan"/>
            <author fullname="S. Erdtman" initials="S." surname="Erdtman"/>
            <date month="June" year="2020"/>
            <abstract>
              <t>Cryptographic operations like hashing and signing need the data to be expressed in an invariant format so that the operations are reliably repeatable. One way to address this is to create a canonical representation of the data. Canonicalization also permits data to be exchanged in its original form on the "wire" while cryptographic operations performed on the canonicalized counterpart of the data in the producer and consumer endpoints generate consistent results.</t>
              <t>This document describes the JSON Canonicalization Scheme (JCS). This specification defines how to create a canonical representation of JSON data by building on the strict serialization methods for JSON primitives defined by ECMAScript, constraining JSON data to the Internet JSON (I-JSON) subset, and by using deterministic property sorting.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8785"/>
          <seriesInfo name="DOI" value="10.17487/RFC8785"/>
        </reference>
        <reference anchor="RFC6234">
          <front>
            <title>US Secure Hash Algorithms (SHA and SHA-based HMAC and HKDF)</title>
            <author fullname="D. Eastlake 3rd" initials="D." surname="Eastlake 3rd"/>
            <author fullname="T. Hansen" initials="T." surname="Hansen"/>
            <date month="May" year="2011"/>
            <abstract>
              <t>Federal Information Processing Standard, FIPS</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="6234"/>
          <seriesInfo name="DOI" value="10.17487/RFC6234"/>
        </reference>
        <reference anchor="RFC9110">
          <front>
            <title>HTTP Semantics</title>
            <author fullname="R. Fielding" initials="R." role="editor" surname="Fielding"/>
            <author fullname="M. Nottingham" initials="M." role="editor" surname="Nottingham"/>
            <author fullname="J. Reschke" initials="J." role="editor" surname="Reschke"/>
            <date month="June" year="2022"/>
            <abstract>
              <t>The Hypertext Transfer Protocol (HTTP) is a stateless application-level protocol for distributed, collaborative, hypertext information systems. This document describes the overall architecture of HTTP, establishes common terminology, and defines aspects of the protocol that are shared by all versions. In this definition are core protocol elements, extensibility mechanisms, and the "http" and "https" Uniform Resource Identifier (URI) schemes.</t>
              <t>This document updates RFC 3864 and obsoletes RFCs 2818, 7231, 7232, 7233, 7235, 7538, 7615, 7694, and portions of 7230.</t>
            </abstract>
          </front>
          <seriesInfo name="STD" value="97"/>
          <seriesInfo name="RFC" value="9110"/>
          <seriesInfo name="DOI" value="10.17487/RFC9110"/>
        </reference>
        <reference anchor="RFC9113">
          <front>
            <title>HTTP/2</title>
            <author fullname="M. Thomson" initials="M." role="editor" surname="Thomson"/>
            <author fullname="C. Benfield" initials="C." role="editor" surname="Benfield"/>
            <date month="June" year="2022"/>
            <abstract>
              <t>This specification describes an optimized expression of the semantics of the Hypertext Transfer Protocol (HTTP), referred to as HTTP version 2 (HTTP/2). HTTP/2 enables a more efficient use of network resources and a reduced latency by introducing field compression and allowing multiple concurrent exchanges on the same connection.</t>
              <t>This document obsoletes RFCs 7540 and 8740.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="9113"/>
          <seriesInfo name="DOI" value="10.17487/RFC9113"/>
        </reference>
        <reference anchor="RFC8446">
          <front>
            <title>The Transport Layer Security (TLS) Protocol Version 1.3</title>
            <author fullname="E. Rescorla" initials="E." surname="Rescorla"/>
            <date month="August" year="2018"/>
            <abstract>
              <t>This document specifies version 1.3 of the Transport Layer Security (TLS) protocol. TLS allows client/server applications to communicate over the Internet in a way that is designed to prevent eavesdropping, tampering, and message forgery.</t>
              <t>This document updates RFCs 5705 and 6066, and obsoletes RFCs 5077, 5246, and 6961. This document also specifies new requirements for TLS 1.2 implementations.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8446"/>
          <seriesInfo name="DOI" value="10.17487/RFC8446"/>
        </reference>
        <reference anchor="RFC2782">
          <front>
            <title>A DNS RR for specifying the location of services (DNS SRV)</title>
            <author fullname="A. Gulbrandsen" initials="A." surname="Gulbrandsen"/>
            <author fullname="P. Vixie" initials="P." surname="Vixie"/>
            <author fullname="L. Esibov" initials="L." surname="Esibov"/>
            <date month="February" year="2000"/>
            <abstract>
              <t>This document describes a DNS RR which specifies the location of the server(s) for a specific protocol and domain. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="2782"/>
          <seriesInfo name="DOI" value="10.17487/RFC2782"/>
        </reference>
        <reference anchor="RFC1034">
          <front>
            <title>Domain names - concepts and facilities</title>
            <author fullname="P. Mockapetris" initials="P." surname="Mockapetris"/>
            <date month="November" year="1987"/>
            <abstract>
              <t>This RFC is the revised basic definition of The Domain Name System. It obsoletes RFC-882. This memo describes the domain style names and their used for host address look up and electronic mail forwarding. It discusses the clients and servers in the domain name system and the protocol used between them.</t>
            </abstract>
          </front>
          <seriesInfo name="STD" value="13"/>
          <seriesInfo name="RFC" value="1034"/>
          <seriesInfo name="DOI" value="10.17487/RFC1034"/>
        </reference>
        <reference anchor="RFC2181">
          <front>
            <title>Clarifications to the DNS Specification</title>
            <author fullname="R. Elz" initials="R." surname="Elz"/>
            <author fullname="R. Bush" initials="R." surname="Bush"/>
            <date month="July" year="1997"/>
            <abstract>
              <t>This document considers some areas that have been identified as problems with the specification of the Domain Name System, and proposes remedies for the defects identified. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="2181"/>
          <seriesInfo name="DOI" value="10.17487/RFC2181"/>
        </reference>
        <reference anchor="RFC3596">
          <front>
            <title>DNS Extensions to Support IP Version 6</title>
            <author fullname="S. Thomson" initials="S." surname="Thomson"/>
            <author fullname="C. Huitema" initials="C." surname="Huitema"/>
            <author fullname="V. Ksinant" initials="V." surname="Ksinant"/>
            <author fullname="M. Souissi" initials="M." surname="Souissi"/>
            <date month="October" year="2003"/>
            <abstract>
              <t>This document defines the changes that need to be made to the Domain Name System (DNS) to support hosts running IP version 6 (IPv6). The changes include a resource record type to store an IPv6 address, a domain to support lookups based on an IPv6 address, and updated definitions of existing query types that return Internet addresses as part of additional section processing. The extensions are designed to be compatible with existing applications and, in particular, DNS implementations themselves. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="STD" value="88"/>
          <seriesInfo name="RFC" value="3596"/>
          <seriesInfo name="DOI" value="10.17487/RFC3596"/>
        </reference>
        <reference anchor="RFC1035">
          <front>
            <title>Domain names - implementation and specification</title>
            <author fullname="P. Mockapetris" initials="P." surname="Mockapetris"/>
            <date month="November" year="1987"/>
            <abstract>
              <t>This RFC is the revised specification of the protocol and format used in the implementation of the Domain Name System. It obsoletes RFC-883. This memo documents the details of the domain name client - server communication.</t>
            </abstract>
          </front>
          <seriesInfo name="STD" value="13"/>
          <seriesInfo name="RFC" value="1035"/>
          <seriesInfo name="DOI" value="10.17487/RFC1035"/>
        </reference>
      </references>
      <references>
        <name>Informative References</name>
        <reference anchor="RFC6120">
          <front>
            <title>Extensible Messaging and Presence Protocol (XMPP): Core</title>
            <author fullname="P. Saint-Andre" initials="P." surname="Saint-Andre"/>
            <date month="March" year="2011"/>
            <abstract>
              <t>The Extensible Messaging and Presence Protocol (XMPP) is an application profile of the Extensible Markup Language (XML) that enables the near-real-time exchange of structured yet extensible data between any two or more network entities. This document defines XMPP's core protocol methods: setup and teardown of XML streams, channel encryption, authentication, error handling, and communication primitives for messaging, network availability ("presence"), and request-response interactions. This document obsoletes RFC 3920. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="6120"/>
          <seriesInfo name="DOI" value="10.17487/RFC6120"/>
        </reference>
        <reference anchor="MSC3995" target="https://github.com/matrix-org/matrix-spec-proposals/pull/3995">
          <front>
            <title>MSC3995: [WIP] Linearized Matrix</title>
            <author fullname="Travis Ralston">
              <organization>The Matrix.org Foundation C.I.C.</organization>
            </author>
            <date year="2023" month="April" day="12"/>
          </front>
        </reference>
        <reference anchor="DMLS" target="https://gitlab.matrix.org/matrix-org/mls-ts/-/blob/48efb972075233c3a0f3e3ca01c4d4f888342205/decentralised.org">
          <front>
            <title>Decentralised MLS</title>
            <author fullname="Hubert Chathi">
              <organization>The Matrix.org Foundation C.I.C.</organization>
            </author>
            <date year="2023" month="May" day="29"/>
          </front>
        </reference>
        <reference anchor="PerspectivesProject" target="https://web.archive.org/web/20170702024706/https://perspectives-project.org/">
          <front>
            <title>Perspectives Project</title>
            <author>
              <organization/>
            </author>
            <date year="2017" month="July" day="02"/>
          </front>
        </reference>
        <reference anchor="I-D.robert-mimi-delivery-service">
          <front>
            <title>MIMI Delivery Service</title>
            <author fullname="Raphael Robert" initials="R." surname="Robert">
              <organization>Phoenix R&amp;D</organization>
            </author>
            <author fullname="Konrad Kohbrok" initials="K." surname="Kohbrok">
              <organization>Phoenix R&amp;D</organization>
            </author>
            <date day="10" month="July" year="2023"/>
            <abstract>
              <t>   This document describes the MIMI Delivery Service.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-robert-mimi-delivery-service-03"/>
        </reference>
        <reference anchor="I-D.mahy-mimi-group-chat">
          <front>
            <title>Group Chat Framework for More Instant Messaging Interoperability (MIMI)</title>
            <author fullname="Rohan Mahy" initials="R." surname="Mahy">
              <organization>Wire</organization>
            </author>
            <date day="10" month="July" year="2023"/>
            <abstract>
              <t>   This document describes a group instant messaging ("group chat")
   semantic framework for the More Instant Messaging Interoperability
   (MIMI) Working Group.  It describes several properties and policy
   options which can be combined to model a wide range of chat and
   multimedia conference types.  It also describes how to build these
   options as an overlay to Messaging Layer Security (MLS) groups and to
   authorize MLS primitives.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-mahy-mimi-group-chat-00"/>
        </reference>
        <reference anchor="I-D.kohbrok-mimi-portability">
          <front>
            <title>MIMI Portability</title>
            <author fullname="Konrad Kohbrok" initials="K." surname="Kohbrok">
              <organization>Phoenix R&amp;D</organization>
            </author>
            <author fullname="Raphael Robert" initials="R." surname="Robert">
              <organization>Phoenix R&amp;D</organization>
            </author>
            <date day="10" month="July" year="2023"/>
            <abstract>
              <t>   This document describes MIMI Portability mechanisms.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-kohbrok-mimi-portability-00"/>
        </reference>
        <reference anchor="I-D.rosenberg-mimi-protocol">
          <front>
            <title>More Instant Messaging Interop (MIMI) Transport Protocol</title>
            <author fullname="Jonathan Rosenberg" initials="J." surname="Rosenberg">
              <organization>Five9</organization>
            </author>
            <author fullname="Cullen Fluffy Jennings" initials="C. F." surname="Jennings">
              <organization>Cisco</organization>
            </author>
            <author fullname="Suhas Nandakumar" initials="S." surname="Nandakumar">
              <organization>Cisco</organization>
            </author>
            <date day="13" month="March" year="2023"/>
            <abstract>
              <t>   This document specifies the More Instant Messaging Interop (mimi)
   Transport Protocol (MTP)- a protocol for inter-provider persistent
   group chat.  MIMI utilizes Messaging Layer Security (MLS) for end-to-
   end encryption of content.  The MIMI Transport Protocol plays the
   role of the Delivery Service (DS) defined by the MLS protocol.  MTP
   is meant to represent the minimal protocol required to enable
   provider to provider federation for messaging exchange using MLS.  It
   is not suitable for client to provider communications.  MTP is based
   on a pull architecture, wherein message delivery from provider A to
   provider B is accomplished by having provider B pull messages from
   provider A.  This provides better scalability and reliability and is
   amenable to implementation in modern cloud software architectures,
   while also reducing spam risk.  MTP serves as a transfer protocol for
   opaque message content, the format of which is specified in a
   separate document.  MTP is also designed to prevent spam, and does so
   by introducing a layer of authorization for the establishment of
   connections and addition to group chats.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-rosenberg-mimi-protocol-00"/>
        </reference>
        <reference anchor="RFC9364">
          <front>
            <title>DNS Security Extensions (DNSSEC)</title>
            <author fullname="P. Hoffman" initials="P." surname="Hoffman"/>
            <date month="February" year="2023"/>
            <abstract>
              <t>This document describes the DNS Security Extensions (commonly called "DNSSEC") that are specified in RFCs 4033, 4034, and 4035, as well as a handful of others. One purpose is to introduce all of the RFCs in one place so that the reader can understand the many aspects of DNSSEC. This document does not update any of those RFCs. A second purpose is to state that using DNSSEC for origin authentication of DNS data is the best current practice. A third purpose is to provide a single reference for other documents that want to refer to DNSSEC.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="237"/>
          <seriesInfo name="RFC" value="9364"/>
          <seriesInfo name="DOI" value="10.17487/RFC9364"/>
        </reference>
        <reference anchor="RFC5280">
          <front>
            <title>Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile</title>
            <author fullname="D. Cooper" initials="D." surname="Cooper"/>
            <author fullname="S. Santesson" initials="S." surname="Santesson"/>
            <author fullname="S. Farrell" initials="S." surname="Farrell"/>
            <author fullname="S. Boeyen" initials="S." surname="Boeyen"/>
            <author fullname="R. Housley" initials="R." surname="Housley"/>
            <author fullname="W. Polk" initials="W." surname="Polk"/>
            <date month="May" year="2008"/>
            <abstract>
              <t>This memo profiles the X.509 v3 certificate and X.509 v2 certificate revocation list (CRL) for use in the Internet. An overview of this approach and model is provided as an introduction. The X.509 v3 certificate format is described in detail, with additional information regarding the format and semantics of Internet name forms. Standard certificate extensions are described and two Internet-specific extensions are defined. A set of required certificate extensions is specified. The X.509 v2 CRL format is described in detail along with standard and Internet-specific extensions. An algorithm for X.509 certification path validation is described. An ASN.1 module and examples are provided in the appendices. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="5280"/>
          <seriesInfo name="DOI" value="10.17487/RFC5280"/>
        </reference>
      </references>
    </references>
    <?line 3239?>

<section numbered="false" anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>Thanks to the Matrix Spec Core Team (SCT) for exploring methods of linearizing Matrix's DAG room model,
especially Richard van der Hoff and Erik Johnston. Additional thanks to the Matrix core team as a whole
for general review and input on this document, especially Patrick Cloke and Jim Mackenzie.</t>
      <t>Matrix's crypto team graciously allowed their work-in-progress MLS considerations to be incorporated
in this document. Thanks to Hubert Chathi for reviewing the MLS work for plausibility.</t>
      <t>Thanks are also extended to the wider MIMI working group for continous review and input on this document.</t>
    </section>
  </back>
  <!-- ##markdown-source:
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
qVdQHDESDgxBZhaJ2CHXh4FY7aIwBG9W9i9pVzOG3ojMGl1agd2Jj2/BIqAl
Rk2u+rIiSbbRDlptiR2dzbSQZjdnfKlZVPBV3iTIab0KXFItg5ZJjjcaBem7
LH3V5/DsGU9Ra7EuwG8pzxyNXdSxM0mH3dxM7PDvqVxsDXKiie4pwtoCBcOu
XWev+f7xK42WlKSQCSvWiSXPwE58kS0seNpE/Udynj5lqY2VtcgmYk9h3jg8
ehA+O2XLa+eJ2T163OT76f/6cP9w+KUP9PhDmg3/0ftmy2Ybmw0Px/hf0AL+
i101Q8XyKtJux22FCWTJRzymSn8mnEYl3l8YGtiL7V0vaEPiphNTIiD+lKK+
OzvF6PqBuZxl/tlEXPEkvWMToejqxj85nanle/6EnZLYq9w48PdcrdX2m4md
QGUsjrAnOk0ydSETrwLD4e+E0Tj/sN5eo5sRlb7t6QkP1Mb2nzup/usaG1v3
DRChPWXiC//RT3ddkvN/eoivZaP7Zqfz8yn/sM//+/tfabzT4f/Wxjs9JP8J
Q1gemfD48SVUi33apP16wTlY8StuWH7hx8H5iI1MPDScB/gO3CzsPiAFPa94
lKTcNMrBo7UiManU0I3oiO32Ldme0iw8D9NMuCPxuSeskQhbtJ8S+UUVKKFF
GCeRgydqJt1NyDNiOa0hVnBFoulSlrrn6mn51KChniNpS4BuRGd1ywVLgDAF
fknRcHSE0Dc0RwDc3E6jnMOyIgVRFXP10UX9sNcWUt8t0u6hYjq3QSJv89xU
u9fY2nUJmbsQv0+cjIPICnkRiwQZ2ObTtUSNEp8+KNuAdQhH5xZJcoVcm54R
WKqQ9DnJYV11IrhzJiTEvVhTwYeka3hzL0tJoCdwth/eUZu7HG/vgm11+32k
zx6LIytnAeFhJBWyDZYSpssszm3dQNxaaED8NNCFRCzv2Q6IblCaaCvcmneM
XS5/WPRxzR8MFkX9vzOGZ+AsONMFGSFgpcpEcxUb7hLxVkmKQUHykCROIySj
XHCUCmOmeB/0IN6tgVxVGn3P5iasCt31pC9UBVJdSqew0Kze6V8lxAiG4AJe
TA1KA3WxkQKpSryqO8//TG/vDGBQVivdjgpA1tSOXHdPWCOwC8/rByr78hig
H7EE/o+8Kl2upLxb72eMM2JBUGzjr92vFmDtwrInLsEtUXu7T5ATJXujvijZ
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
UVCyQWp3rulB8v+YSdYqYDECAA==

-->

</rfc>
