<?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.35 (Ruby 3.2.2) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-ralston-mimi-linearized-matrix-02" category="std" consensus="true" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.17.3 -->
  <front>
    <title abbrev="Linearized Matrix">Linearized Matrix</title>
    <seriesInfo name="Internet-Draft" value="draft-ralston-mimi-linearized-matrix-02"/>
    <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="June" day="27"/>
    <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>
    <abstract>
      <?line 74?>

<t>This document specifies Linearized Matrix for use in messaging interoperability.</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 78?>

<section anchor="introduction">
      <name>Introduction</name>
      <t>Alongside messaging, Matrix operates as an openly federated communications protocol for
VoIP, IoT, and more. The existing Matrix network uses fully decentralized access control
within rooms (conversations) and is highly extensible in its structure. These features
are not critically important to a strict focus on messaging interoperability, however.</t>
      <t>This document specifies "Linearized Matrix": a modified room model based upon Matrix's
existing room model. This document does <em>not</em> explore how to interconnect Linearized
Matrix with the existing Matrix room model - interested readers may wish to review
<xref target="MSC3995"/> within the Matrix Specification process.</t>
      <t>At a high level, a central server is designated as the "hub" server, responsible for
ensuring events in a given room are provided to all other participants equally. Servers
communicate with each other over HTTPS and JSON, using the specified API endpoints.</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"/> where possible.</t>
      <t>This document additionally uses the following definitions:</t>
      <ul spacing="normal">
        <li>
          <strong>Room</strong>: Synonymous with "conversation" from I-D.ralston-mimi-terminology.</li>
        <li>
          <strong>Room Member</strong>: Synonymous with "conversation member" from I-D.ralston-mimi-terminology.</li>
        <li>
          <strong>State Event</strong>: Synonymous with "conversation property" from I-D.ralston-mimi-terminology.
A state event is a subclass of an event.</li>
      </ul>
      <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">
            <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="256" y="196">Server-Server</text>
              <text x="328" y="196">API</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 API      +------------------+
      |     ^
      |     |                      +------------------+
      |     +----( events )--------+                  |
      |                            | Provider/Server  |
      +----------( events )------->|        C         |
                                   +------------+-----+
                                         ^      |
                                         |      |
                                         |      V
                                      .--+---------.
                                     |   Client C   |
                                      '------------'
]]></artwork>
      </artset>
      <t>In this diagram, Server A is acting as a hub for the other two servers. 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.</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 is not required to persist
conversation history as it can fetch it from the hub if needed.</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>
      <section anchor="int-server-names">
        <name>Server Names</name>
        <t>Each server 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"/> and, when an IPv6 address,
encoded per <xref section="2.2" sectionFormat="of" target="RFC4291"/> surrounded by square brackets (<tt>[]</tt>). Improper server
names <bcp14>MUST</bcp14> be considered "uncontactable" by a server.</t>
        <t>A server <bcp14>SHOULD 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 certificates 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    = IPv4address / "[" IPv6address "]" / dns-name
IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT
IPv6address = 2*45IPv6char
IPv6char    = DIGIT / %x41-46 / %x61-66 / ":" / "."
                  ; 0-9, A-F, a-f, :, .
dns-name    = 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>
          <li>
            <tt>127.0.0.1</tt> (literal IPv4 address)</li>
          <li>
            <tt>127.0.0.1:5678</tt> (literal IPv4 address with explicit port)</li>
          <li>
            <tt>[2001:DB8:0:0:8:800:200C:417A]</tt> (literal IPv6 address)</li>
          <li>
            <tt>[2001:DB8:0:0:8:800:200C:417A]:5678</tt> (literal IPv6 address 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>A room version is a set of algorithms which define how the room operates, identified by a single
string. Room versions are immutable once specified, as otherwise a change in algorithms could
cause a split-brain between participating servers.</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>There is no implicit ordering or hierarchy to room versions. Although there is a recommended
default room version, some rooms might benefit from features of a different room version.</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.</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.</li>
            <li>Event format - Which fields are expected to be present on an event, and the schema for each.</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.</li>
            <li>Hub selection - Rules around picking the hub server and transferring to a new hub.</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.</li>
          </ul>
          <t>A server is capable of supporting multiple room versions at a time. The transport API decouples
specific details regarding room versions from the wire formats. For example, events are treated
as JSON blobs in this document's Server-Server API (<xref target="int-transport"/>).</t>
          <t>Room versions are normally specified using a dedicated document. An example of this can be found
in the existing Matrix Spec Change process as <xref target="MSC3820"/>.</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><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, as the
localpart for a user ID is unchangeable. In these cases, a GUID (scoped to the allocating server)
is recommended so the associated human can 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="devices">
        <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><strong>TODO</strong>: Do we need to define grammar and such for device IDs, or is that covered by MLS already?</t>
      </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>
            <tt>state_key</tt> (string; optional) - A UTF-8 <xref target="RFC3629"/> string to further distinguish an event
type from other related events. Only specified on State Events (<xref target="int-state-events"/>). Can be
empty. This <bcp14>MUST NOT</bcp14> exceed 255 characters.</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> (integer; required) - The milliseconds since the unix epoch for when this
event was created.</li>
          <li>
            <tt>hub_server</tt> (string; technically optional) - The domain name of the hub server which is
sending this event to the remainder of the room. All events created within Linearized Matrix
<bcp14>MUST</bcp14> have this field set, however events created externally <bcp14>MUST NOT</bcp14> set this field. This
<bcp14>MUST</bcp14> be a valid server name (<xref target="int-server-names"/>).</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>
            <tt>hashes</tt> (object; required) - The <em>content hashes</em> for the event. The <tt>lpdu</tt> key within this
object is an object itself, keyed by hash algorithm with value being the encoded hash. Similarly,
outside of <tt>lpdu</tt>, <tt>hashes</tt> is keyed by hash algorithm with value being the encoded hash.
Events created within Linearized Matrix <bcp14>MUST</bcp14> specify an LPDU hash, however events created
externally <bcp14>MUST NOT</bcp14> set such a hash.</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) - The event IDs which precede the event. Events
created within Linearized Matrix <bcp14>MUST</bcp14> only ever have a single event ID here, however events
created externally <bcp14>MAY</bcp14> have one or more referenced event IDs.</li>
          <li>
            <tt>unsigned</tt> (object; optional) - Additional metadata not covered by the signing algorithm. Like
<tt>content</tt>, a receiver <bcp14>MUST NOT</bcp14> trust the values to match any particular schema.</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>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"],
  "unsigned": {
    "arbitrary": "fields"
  }
}
]]></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>The hub server is responsible for ensuring events are linearly added to the room from all participants,
which means participants cannot set fields such as <tt>prev_events</tt> on their events. Additionally,
participant servers are not expected to store past conversation history or even "current state" for
the room, further making participants unable to reliably populate <tt>auth_events</tt> and <tt>prev_events</tt>.</t>
          <t>To avoid these problems, the participant server <bcp14>MUST NOT</bcp14> populate the following fields on events
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>, noting that an empty string is a valid state key. State in the
room with the same key-tuple will be overwritten as "current state".</t>
          <t>State events are otherwise processed like regular events in the room: they're appended to the
room history and can be referenced by that room history.</t>
          <t>"Current state" is the state at the time being considered (which is often the implied <tt>HEAD</tt> of
the room). In Linearized Matrix, a simple approach to calculating current state is to iterate
over all events in order, overwriting the key-tuple for state events in an adjacent map. That
map becomes "current state" when the loop is finished.</t>
          <section anchor="int-stripped-state">
            <name>Stripped State</name>
            <t>Stripped state event are extremely simplified state events to provide context to an invite or knock.
Servers <bcp14>MUST NOT</bcp14> rely on stripped state events being accurate, only using them if the server doesn't
have access to the room's real state.</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>
              <li>
                <tt>m.room.encryption</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="mroompowerlevels">
            <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 anchor="int-calc-power-levels">
              <name>Calculating Power Levels</name>
              <t>All power levels are calculated with reference to the <tt>content</tt> of an <tt>m.room.power_levels</tt>
state event.</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>
          <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?)</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.encryption</tt>, <tt>m.room.canonical_alias</tt></t>
            <t><strong>TODO</strong>: Drop <tt>m.room.encryption</tt> and pack it into the create event instead?</t>
          </section>
        </section>
      </section>
    </section>
    <section anchor="initial-room-version">
      <name>Initial Room Version</name>
      <t>Room versions are described by <xref target="int-room-versions"/>.</t>
      <t>As a whole, this document describes the <tt>I.1</tt> room version. Future room versions can build
upon this version's principles (or entirely replace them) through dedicated documents.</t>
      <t>Servers <bcp14>MUST</bcp14> implement support for <tt>I.1</tt>, and <bcp14>SHOULD</bcp14> implement other specified room versions
as needed. Servers <bcp14>SHOULD</bcp14> use <tt>I.1</tt> when creating new rooms. <tt>I.1</tt> shall be considered "stable".</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>The hub server <bcp14>MUST</bcp14> enforce the room version's algorithms upon the room. Participant servers
<bcp14>SHOULD</bcp14> enforce the room version's algorithm, but can opt to believe the hub server if they
wish.</t>
    </section>
    <section anchor="mls-considerations">
      <name>MLS Considerations</name>
      <t>MIMI has a chartered requirement to use Messaging Layer Security (MLS) <xref target="I-D.ietf-mls-protocol"/>
        <xref target="I-D.ietf-mls-architecture"/> for encryption, and MLS requires that all group members (devices)
know of all other devices.</t>
      <t>Each room has a single MLS Group associated with it, starting with the <tt>m.room.create</tt> event.</t>
      <t><strong>TODO</strong>: Details on how key material is stored/shared within the room.</t>
      <t><strong>TODO</strong>: What does <tt>m.room.encrypted</tt> (user message) look like here?</t>
    </section>
    <section anchor="event-signing-authorization">
      <name>Event Signing &amp; Authorization</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>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 sees it for the first time. This
might be because the server specifically reached out to fetch that specific event, or because
the server was pushed that event through normal operation.</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 is in a valid shape (<xref target="int-pdu"/>). In practice, this means ensuring the
overall schema for an event is applied, without considering specific schemas for <tt>content</tt>.
For example, ensuring a <tt>type</tt> is present, a string, and less than 255 characters. 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 complete the checks to validate the hub's behaviour.</t>
        <ol spacing="normal" type="1"><li>Ensure the event is not referencing rejected (<xref target="int-rejection"/>) events. If it is, it is
rejected itself.</li>
          <li>Ensure the event passes the authorization rules (<xref target="int-auth-rules"/>) for the state identified
by the event's <tt>auth_events</tt>. If it fails, it is rejected (<xref target="int-rejection"/>).</li>
          <li>
            <t>Ensures the event passes the authorization rules (<xref target="int-auth-rules"/>) for the state of the
room immediately before where the event would be inserted. If it fails, it is rejected
(<xref target="int-rejection"/>).  </t>
            <t><strong>TODO</strong>: Clarify that this step only applies if you're on the DAG side. On LM, this is
the same as Step 6. We may need to adjust the rejection/soft-fail logic.</t>
          </li>
          <li>Ensures the event passes the authorization rules (<xref target="int-auth-rules"/>) for the current
state of the room (which may very well be the same as the step above). If it fails, it
is soft-failed (<xref target="int-soft-failure"/>).</li>
        </ol>
      </section>
      <section anchor="int-rejection">
        <name>Rejection</name>
        <t>Events which are rejected are not relayed to any local clients and are not appended to the
room in any way. Events which reference rejected events through <tt>prev_events</tt> or <tt>auth_events</tt>
are rejected themselves.</t>
        <t>Servers which utilize persistence (hub servers) <bcp14>SHOULD</bcp14> persist rejections to make this check
faster.</t>
      </section>
      <section anchor="int-soft-failure">
        <name>Soft Failure</name>
        <t>When an event is "soft-failed" it should not be relayed to any local clients nor be used
in <tt>auth_events</tt>. The event is otherwise handled as per usual.</t>
        <t><strong>TODO</strong>: With a linearized DAG, do we have a choice to not use the event in auth_events?</t>
      </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="auth-rules-algorithm">
          <name>Auth Rules Algorithm</name>
          <t>With consideration for default/calculated power levels (<xref target="int-calc-power-levels"/>), the
ordered rules which affect authorization of a given event are as follows.</t>
          <t>See <xref target="int-rejection"/> for a description of "reject".</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.</li>
            <li>If <tt>hub_server</tt> is present, events must be signed (<xref target="int-checking-signatures"/>) by that server.</li>
            <li>
              <t>If <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.</li>
                <li>If the domain of the <tt>room_id</tt> is not the same domain as the <tt>sender</tt>, reject.</li>
                <li>If <tt>content.room_version</tt> is not <tt>I.1</tt>, reject.</li>
                <li>Otherwise, allow.</li>
              </ol>
            </li>
            <li>
              <t>Considering the event's <tt>auth_events</tt>:  </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.</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.</li>
                <li>If there are entries where the referenced event was rejected during receipt (<xref target="int-rejection"/>),
reject.</li>
                <li>If there is no <tt>m.room.create</tt> event among the entries, reject.</li>
              </ol>
            </li>
            <li>
              <t>If <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.</li>
                <li>
                  <t>If <tt>membership</tt> 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.</li>
                    <li>If <tt>sender</tt> does not match <tt>state_key</tt>, reject.</li>
                    <li>If the <tt>sender</tt> is banned, reject.</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 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.</li>
                    <li>Otherwise, reject.</li>
                  </ol>
                </li>
                <li>
                  <t>If <tt>membership</tt> 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.</li>
                    <li>If the target user's (<tt>state_key</tt>) membership is <tt>join</tt> or <tt>ban</tt>, reject.</li>
                    <li>If the <tt>sender</tt>'s power level is greater than or equal to the power level needed
to send invites, allow.</li>
                    <li>Otherwise, reject.</li>
                  </ol>
                </li>
                <li>
                  <t>If <tt>membership</tt> is <tt>leave</tt>:      </t>
                  <ol spacing="normal" type="1"><li>If the <tt>sender</tt> matches the <tt>state_key</tt>, allow 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.</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.</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.</li>
                    <li>Otherwise, reject.</li>
                  </ol>
                </li>
                <li>
                  <t>If <tt>membership</tt> 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.</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.</li>
                    <li>Otherwise, reject.</li>
                  </ol>
                </li>
                <li>
                  <t>If <tt>membership</tt> 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.</li>
                    <li>If the <tt>sender</tt> does not match the <tt>state_key</tt>, reject.</li>
                    <li>If the <tt>sender</tt>'s current membership state is not <tt>ban</tt> or <tt>join</tt>, allow.</li>
                    <li>Otherwise, reject.</li>
                  </ol>
                </li>
                <li>Otherwise, the <tt>membership</tt> is unknown. Reject.</li>
              </ol>
            </li>
            <li>If the <tt>sender</tt>'s current membership state is not <tt>join</tt>, reject.</li>
            <li>If the event <tt>type</tt>'s required power level is greater than the <tt>sender</tt>'s power level,
reject.</li>
            <li>If the event has a <tt>state_key</tt> which starts with an <tt>@</tt> and does not match the <tt>sender</tt>,
reject.</li>
            <li>
              <t>If <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.</li>
                <li>If <tt>events</tt> in <tt>content</tt> is present and not an object with values that are integers,
reject.</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.</li>
                <li>If there is no previous <tt>m.room.power_levels</tt> event in the room, allow.</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.</li>
                    <li>If the new value is higher than the <tt>sender</tt>'s current power level, reject.</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.</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.</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.</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.</li>
                  </ol>
                </li>
                <li>Otherwise, allow.</li>
              </ol>
            </li>
            <li>Otherwise, allow.</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.</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> and <tt>unsigned</tt>.</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> and <tt>unsigned</tt> properties, 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>
        <ol spacing="normal" type="1"><li>
            <t>Remove any existing <tt>unsigned</tt> and <tt>signatures</tt> fields.
            </t>
            <ol spacing="normal" type="1"><li>If calculating an LPDU's 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>
        <ol spacing="normal" type="1"><li>Redact the event.</li>
          <li>Remove <tt>signatures</tt> and <tt>unsigned</tt> fields.</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="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>: Is this section better placed in the MSC for now?</t>
    </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>
      <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> is an IP literal, then that IP address is to be used together with the given port
number, or 8448 if no port is given.  </t>
            <t>
TLS certificate: <tt>&lt;hostname&gt;</tt> (always without port)  </t>
            <t>
Host header: <tt>&lt;hostname&gt;</tt> or <tt>&lt;hostname&gt;:&lt;port&gt;</tt> if a port was specified</t>
          </li>
          <li>
            <t>If <tt>&lt;hostname&gt;</tt> is not an IP literal, and 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>If <tt>&lt;hostname&gt;</tt> is not an IP literal, 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> is an IP literal, then that IP address is to be used together with the
given port number, or 8448 if no port is given.      </t>
                <t>
TLS certificate: <tt>&lt;delegated_hostname&gt;</tt> (always without port)      </t>
                <t>
Host header: <tt>&lt;delegated_hostname&gt;</tt> or <tt>&lt;delegated_hostname&gt;:&lt;delegated_port&gt;</tt> if a port was specified</t>
              </li>
              <li>
                <t>If <tt>&lt;delegated_hostname&gt;</tt> is not an IP literal, and <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>If <tt>&lt;delegated_hostname&gt;</tt> is not an IP literal and no <tt>&lt;delegated_port&gt;</tt> is present, 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>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">
              <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": [{/* TODO: Define EDUs */}],
   "pdus": [
      {/* Either an LPDU or PDU */}
   ]
}
]]></sourcecode>
          <t><strong>TODO</strong>: Describe EDUs.</t>
          <t><tt>edus</tt> are the Ephemeral Data Units 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>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>
        </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="648" viewBox="0 0 648 720" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px">
              <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 280,32 L 280,64" 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 616,560 L 616,592" fill="none" stroke="black"/>
              <path d="M 640,256 L 640,288" 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 456,256 L 640,256" fill="none" stroke="black"/>
              <path d="M 464,288 L 640,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 192,416" fill="none" stroke="black"/>
              <path d="M 448,416 L 640,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 456,560 L 616,560" fill="none" stroke="black"/>
              <path d="M 464,592 L 616,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="472,592 460,586.4 460,597.6" fill="black" transform="rotate(180,464,592)"/>
              <polygon class="arrowhead" points="472,288 460,282.4 460,293.6" fill="black" transform="rotate(180,464,288)"/>
              <polygon class="arrowhead" points="456,688 444,682.4 444,693.6" fill="black" transform="rotate(0,448,688)"/>
              <polygon class="arrowhead" points="456,512 444,506.4 444,517.6" fill="black" transform="rotate(0,448,512)"/>
              <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="492" y="196">Decide</text>
                <text x="532" y="196">to</text>
                <text x="576" y="196">process</text>
                <text x="624" y="196">the</text>
                <text x="496" y="212">invite.</text>
                <text x="544" y="212">Can</text>
                <text x="588" y="212">reject</text>
                <text x="632" y="212">due</text>
                <text x="476" y="228">to</text>
                <text x="512" y="228">spam,</text>
                <text x="548" y="228">or</text>
                <text x="580" y="228">send</text>
                <text x="612" y="228">it</text>
                <text x="636" y="228">to</text>
                <text x="480" y="244">the</text>
                <text x="536" y="244">recipient</text>
                <text x="600" 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="220" y="420">User</text>
                <text x="272" y="420">decides</text>
                <text x="316" y="420">to</text>
                <text x="356" y="420">accept</text>
                <text x="412" 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="484" y="548">Fill</text>
                <text x="528" y="548">event</text>
                <text x="588" 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">
                <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="640" viewBox="0 0 640 784" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px">
                <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 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 632,624 L 632,656" 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 448,624 L 632,624" fill="none" stroke="black"/>
                <path d="M 456,656 L 632,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="464,656 452,650.4 452,661.6" fill="black" transform="rotate(180,456,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="500" y="580">Otherwise,</text>
                  <text x="568" y="580">queue</text>
                  <text x="488" y="596">sending</text>
                  <text x="536" y="596">the</text>
                  <text x="580" y="596">invite</text>
                  <text x="620" y="596">to</text>
                  <text x="484" y="612">target</text>
                  <text x="532" 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="todo-remainder-of-transport">
        <name>TODO: Remainder of Transport</name>
        <t><strong>TODO</strong>: This section.</t>
        <t>Topics:</t>
        <ul spacing="normal">
          <li>EDUs (typing notifications, receipts, presence)</li>
          <li>Device management &amp; to-device messaging</li>
          <li>Query APIs (alias resolution, profiles)</li>
          <li>Encryption APIs</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>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="RFC4291">
          <front>
            <title>IP Version 6 Addressing Architecture</title>
            <author fullname="R. Hinden" initials="R." surname="Hinden"/>
            <author fullname="S. Deering" initials="S." surname="Deering"/>
            <date month="February" year="2006"/>
            <abstract>
              <t>This specification defines the addressing architecture of the IP Version 6 (IPv6) protocol. The document includes the IPv6 addressing model, text representations of IPv6 addresses, definition of IPv6 unicast addresses, anycast addresses, and multicast addresses, and an IPv6 node's required addresses.</t>
              <t>This document obsoletes RFC 3513, "IP Version 6 Addressing Architecture". [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="4291"/>
          <seriesInfo name="DOI" value="10.17487/RFC4291"/>
        </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="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="9" month="June" 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-01"/>
        </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="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="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="MSC3820" target="https://github.com/matrix-org/matrix-spec-proposals/pull/3820">
          <front>
            <title>MSC3820: Room Version 11</title>
            <author fullname="Travis Ralston">
              <organization>The Matrix.org Foundation C.I.C.</organization>
            </author>
            <date year="2023" month="June" day="08"/>
          </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="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 2685?>

<section numbered="false" anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>Thank you to the Matrix Spec Core Team (SCT), and in particular Richard van der Hoff, for
exploring how Matrix rooms could be represented as a linear structure, leading to this document.</t>
    </section>
  </back>
  <!-- ##markdown-source:
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

-->

</rfc>
