<?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.7.1 (Ruby 3.2.2) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-ralston-mimi-protocol-00" category="std" consensus="true" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.18.2 -->
  <front>
    <title abbrev="MIMI+MLS Protocol">More Instant Messaging Interoperability (MIMI) using HTTPS and MLS</title>
    <seriesInfo name="Internet-Draft" value="draft-ralston-mimi-protocol-00"/>
    <author fullname="Travis Ralston" role="editor">
      <organization>The Matrix.org Foundation C.I.C.</organization>
      <address>
        <email>travisr@matrix.org</email>
      </address>
    </author>
    <date year="2023" month="October" day="23"/>
    <area>Applications and Real-Time</area>
    <workgroup>More Instant Messaging Interoperability</workgroup>
    <keyword>mimi</keyword>
    <keyword>interoperable messaging</keyword>
    <keyword>chat</keyword>
    <keyword>secure messaging</keyword>
    <abstract>
      <?line 52?>

<t>The More Instant Messaging Interoperability (MIMI) working group is chartered to
use Messaging Layer Security (MLS) <xref target="RFC9420"/> for its encryption/security
layers. This document implements the architecture described by <xref target="I-D.barnes-mimi-arch"/>,
detailing the components required to achieve MLS-secured 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-protocol/draft-ralston-mimi-protocol.html"/>.
        Status information for this document may be found at <eref target="https://datatracker.ietf.org/doc/draft-ralston-mimi-protocol/"/>.
      </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-protocol"/>.</t>
    </note>
  </front>
  <middle>
    <?line 60?>

<section anchor="introduction">
      <name>Introduction</name>
      <t>The More Instant Messaging Interoperability (MIMI) working group is responsible
for specifying the set of protocols required to achieve secure, modern,
messaging interoperability using MLS <xref target="RFC9420"/>. <xref target="I-D.barnes-mimi-arch"/>
outlines an overall architecture for interoperable communications, and this
document implements those components using MLS and HTTP for the security and
specific transport details.</t>
      <t>Each MIMI room uses state events to track user-level participation and
interaction with the room, and an accompanied MLS group for client-level
membership and messaging. The MLS group's membership consists of the clients
which belong to the participating users in the MIMI room.</t>
      <t>MLS describes an abstract concept of a "Delivery Service" (DS) that is
specifically responsible for ordering handshake messages and more generally
delivering messages to the intended recipients. Collectively, all of the servers
in a MIMI room fulfill the Delivery Service role, with the hub server performing
the ordering of handshake messages. The hub server is additionally responsible
for tracking details about the room to assist clients in joining, validating
events and handshake messages, and enforcing the required policy against the
room and MLS group states.</t>
      <t>Servers communicate with each other using a mutually authenticated mode of TLS
<xref target="RFC5246"/> over HTTP <xref target="RFC9110"/>. This document does not describe a protocol
for clients to communicate with a server. Instead, clients use provider-specific
APIs to accomplish "last mile" delivery of events and messages.</t>
      <ul empty="true">
        <li>
          <t><strong>TODO</strong>: Describe notion of consent, similar to "connection KeyPackages" in
Section 6 of <xref target="I-D.robert-mimi-delivery-service"/>.</t>
        </li>
      </ul>
    </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>Terms and definitions are inherited from <xref target="I-D.barnes-mimi-arch"/>.</t>
    </section>
    <section anchor="rooms-and-events">
      <name>Rooms and Events</name>
      <t>Rooms, described by <xref target="I-D.barnes-mimi-arch"/>, contain both state events and an
associated MLS group for encryption operations. State events are used to frame
information and operations which exist outside of the MLS group, such as the
user participation list, room policy, and other metadata.</t>
      <t>Events are sent in context of a room, authenticated against the room's policy,
and ordered by the hub server. Each event additionally contains an <em>event type</em>
to differentiate its payload format from other events. A state event is an event
with a <em>state key</em>. The combination of the event type and state key form a tuple
to establish <em>current state</em>: the most recently sent state events with distinct
type and state key pairs.</t>
      <t>The hub server <bcp14>MUST</bcp14> persist at least the current room state, and <bcp14>MAY</bcp14> discard
user participation events for users who are in the <tt>leave</tt> state. The hub server
<bcp14>SHOULD</bcp14> persist all other events for the benefit of other servers in the room.</t>
      <ul empty="true">
        <li>
          <t><strong>TODO</strong>: Check that this history requirement matches agreed semantics.</t>
        </li>
      </ul>
      <ul empty="true">
        <li>
          <t><strong>TODO</strong>: Describe where room state is persisted. With this document's
transport, it's stored adjacent to the MLS group. See
<xref target="I-D.robert-mimi-delivery-service"/> for possible in-MLS persistence.</t>
        </li>
      </ul>
      <section anchor="event-schema">
        <name>Event Schema</name>
        <t>Events are authenticated against their TLS presentation language format
(<xref section="3" sectionFormat="of" target="RFC8446"/>):</t>
        <artwork><![CDATA[
// See the "MIMI Event Types" IANA registry for values.
// Example: "m.room.create"
opaque EventType;

struct {
   // The room where the event is sent to.
   opaque roomId;

   // The event type.
   EventType type;

   // If present, the event is a state event.
   opaque [[stateKey]];

   // Who or what sent this event.
   opaque sender;

   // The origin server's content hash of the event.
   // See the "Content Hashes" section for information.
   uint8 contentHash[32];

   // The origin server's signature over the event.
   // See the "Signatures" section for information.
   opaque signature<V>;

   // The event IDs which authorize this event to be sent in the room,
   // as defined by the policy.
   // See the "[Event] Authentication" section for information.
   opaque authEventIds[];

   // The event ID of the parent event. This will be an empty string if
   // the `type` is `m.room.create`.
   opaque prevEventId;

   // Additional fields may be present as dependent on event type.
} Event;
]]></artwork>
        <t>Note an "event ID" is not specified on the object. The event ID for an event is
the sigil <tt>$</tt> followed by the URL-Safe Unpadded Base64-encoded reference hash
(<xref target="reference-hash"/>) of the event.</t>
        <t>The "origin server" of an event is the server implied by the <tt>sender</tt> field.</t>
        <t>Events are immutable once sent, but may be redacted (<xref target="event-auth"/>) to remove
non-critical information.</t>
      </section>
      <section anchor="event-auth">
        <name>Authentication</name>
        <t>Events simultaneously carry information which is critical for the protocol to
operate, and other information which is less essential. The less essential
information is often user-supplied, and ideally can be removed without
"breaking" the room. MIMI supports removing non-critical information from events
through <em>redaction</em>.</t>
        <t>Redaction creates a consistent representation of an event suitable for signing.
It is not an approach for "deleting" an event. Deletions are instead handled by
the content format for application messages in MIMI.</t>
        <t>There are two scenarios where a redaction is applied:</t>
        <ol spacing="normal" type="1"><li>
            <t>When a mismatched content hash (<xref target="content-hash"/>) for an event is received.</t>
          </li>
          <li>
            <t>When an <tt>m.room.redaction</tt> (<xref target="ev-mroomredaction"/>) message event is received,
targeting an event.</t>
          </li>
        </ol>
        <t>When applying a redaction, all fields described by <xref target="event-schema"/> <bcp14>MUST NOT</bcp14> be
removed. Individual event types <bcp14>MAY</bcp14> describe additional fields to retain. All
other fields <bcp14>MUST</bcp14> be removed.</t>
        <t>Events are authenticated against their redacted form. If an event fails
authentication, it is <em>rejected</em>. Rejected events are dropped and not forwarded
any further. For example, a hub rejecting an event would not send it to follower
servers. A follower server rejecting an event sent by a hub would not forward it
to local clients.</t>
        <t>The redacted event is signed (<xref target="event-signing"/>) to verify that the event was
sent by the referenced originating server. If the signature verification fails,
the event is rejected.</t>
        <t>Each event references a set of "auth events" which permit the event to be sent.
This field is populated by the hub server upon receipt of a partial event to
send. The specific event types required to be referenced in this field are
described by the room policy, but are typically the <tt>m.room.create</tt> (<xref target="ev-mroomcreate"/>),
and <tt>m.room.user</tt> (<xref target="ev-mroomuser"/>) state events at a minimum. If an event is
missing a required auth event, or contains a reference to an unknown/rejected
event, the event is rejected.</t>
        <t>If the event's content hash does not match the calculated content hash, the
event is redacted before being sent any further. Note that if an event is
already manually redacted with a redaction event, it will in most cases fail a
content hash check.</t>
        <t>Individual event types <bcp14>MAY</bcp14> specify additional authentication requirements, such
as field validation or ordering requirements.</t>
        <section anchor="reference-hash">
          <name>Reference Hash</name>
          <t>Events are referenced by ID in relation to each other, forming the room history
and auth chain. If the event ID was a sender-generated value, any server along
the send or receive path could "replace" that event with another perfectly legal
event, both using the same ID.</t>
          <t>By using a calculated value, namely the reference hash, if a server does try to
replace the event then it would result in a completely different event ID. That
event ID becomes impossible to reference as it wouldn't be part of the proper
room history.</t>
          <t>An event's reference hash is calculated by redacting it, removing the
<tt>signature</tt> field if present, then serializing the resulting object. The
serialized binary is then hashed using SHA256 <xref target="RFC6234"/>.</t>
          <t>To further create an event ID, the resulting hash is encoded using URL-Safe
Unpadded Base64 and prefixed with the <tt>$</tt> sigil.</t>
          <ul empty="true">
            <li>
              <t><strong>TODO</strong>: Reference "URL-Safe Unpadded Base64" specification.</t>
            </li>
          </ul>
        </section>
        <section anchor="content-hash">
          <name>Content Hash</name>
          <t>An event's content hash prevents servers from modifying details of the event not
covered by the reference hash itself. For example, a room name state event
doesn't have the name itself covered by a reference hash because it's redacted,
so it's instead covered by the content hash, which is in turn covered by the
reference hash. This allows the event to later be redacted without affecting the
event ID of that event.</t>
          <t>To calculate a content hash, the following fields are removed from the event
first:</t>
          <ul spacing="normal">
            <li>
              <t><tt>contentHash</tt></t>
            </li>
            <li>
              <t><tt>signature</tt></t>
            </li>
            <li>
              <t><tt>authEventIds</tt></t>
            </li>
            <li>
              <t><tt>prevEventId</tt></t>
            </li>
          </ul>
          <t><tt>authEventIds</tt> and <tt>prevEventId</tt> are removed because they are populated by the
hub server. The content hash is to preserve the origin server's event, not the
hub server's.</t>
          <t>The resulting object is then serialized and hashed using SHA256 <xref target="RFC6234"/>.</t>
          <t>Note that the event is <em>not</em> redacted in the calculation of a content hash. This
is to ensure that <em>all</em> origin-provided fields are protected by a hash and
trigger redaction if a field changed along the send path.</t>
          <t>The content hash is additionally covered by the reference hash and event
signature.</t>
        </section>
        <section anchor="event-signing">
          <name>Signatures</name>
          <t>An event's content hash covers the unredacted contents, and it's reference hash
covers the redacted event contents (including the content hash). The hashes
alone are not authenticated and require an additional verification mechanism.
Signatures provide the needed authentication mechanism, and are applied by the
event's origin server.</t>
          <t>Signatures are computed by first redacting the event, then removing the
<tt>signature</tt>, <tt>authEventIds</tt>, and <tt>prevEventId</tt> fields if present. The resulting
object is then serialized and signed using the server's key.</t>
          <ul empty="true">
            <li>
              <t><strong>TODO</strong>: Use mTLS keys? Source drafts use Ed25519 keys, but then we need to
distribute keys all over the place.</t>
            </li>
          </ul>
          <t>Like content hashes (<xref target="content-hash"/>), <tt>authEventIds</tt> and <tt>prevEventId</tt> are
removed from the event because they are populated by the hub server.</t>
        </section>
      </section>
      <section anchor="room-creation">
        <name>Creation</name>
        <t>Rooms (and therefore MLS groups) are first created within the provider, out of
scope from MIMI. When the room is exposed to another server over the MIMI
protocol, such as with an explicit invite to another user, the creating server
<bcp14>MUST</bcp14> produce the following details:</t>
        <ul spacing="normal">
          <li>
            <t>An <tt>m.room.create</tt> (<xref target="ev-mroomcreate"/>) state event describing the encryption
and policy details for the room.</t>
          </li>
          <li>
            <t>A universally unique room ID (represented by the create event).</t>
          </li>
          <li>
            <t>An <tt>m.room.user</tt> (<xref target="ev-mroomuser"/>) state event which points to the create
event as a parent for the create event's <tt>sender</tt>.</t>
          </li>
          <li>
            <t>An MLS group with a group ID matching the room ID, and contains a device
belonging to the create event's <tt>sender</tt>.</t>
          </li>
        </ul>
        <t>This is the minimum state required by a MIMI room. Room creators <bcp14>MAY</bcp14> wish to
include additional details in the initial state, such as configuration of the
room's policy, adding the creator's other clients to the MLS group state, etc.</t>
        <section anchor="ev-mroomcreate">
          <name><tt>m.room.create</tt></name>
          <t><strong>Event type</strong>: <tt>m.room.create</tt></t>
          <t><strong>State key</strong>: Zero byte length string.</t>
          <t><strong>Additional event fields</strong>:</t>
          <artwork><![CDATA[
struct {
   // TODO
} CreateEvent;
]]></artwork>
          <ul empty="true">
            <li>
              <t><strong>TODO</strong>: Include fields for policy information (previously called a "policy
ID" in ralston-mimi-signaling). Protect this new field from redaction.</t>
            </li>
          </ul>
          <ul empty="true">
            <li>
              <t><strong>TODO</strong>: Include fields for encryption information. Possibly ciphersuite and
similar so a server can check to ensure it supports the MLS dialect? Protect
this new field from redaction.</t>
            </li>
          </ul>
          <t><strong>Additional authentication rules</strong>:</t>
          <ul spacing="normal">
            <li>
              <t>The event's <tt>prevEventId</tt> <bcp14>MUST</bcp14> be a zero byte length string.</t>
            </li>
            <li>
              <t>The event's <tt>authEventIds</tt> <bcp14>MUST</bcp14> be empty.</t>
            </li>
            <li>
              <t>The event <bcp14>MUST</bcp14> be the first event in the room.</t>
            </li>
          </ul>
        </section>
      </section>
      <section anchor="hub-server-selection">
        <name>Hub Server Selection</name>
        <t>The hub server for a room is the origin server of the <tt>m.room.create</tt>
(<xref target="ev-mroomcreate"/>) event.</t>
        <ul empty="true">
          <li>
            <t><strong>TODO</strong>: More sophisticated selection, and possibly transfer of
responsibility.</t>
          </li>
        </ul>
      </section>
      <section anchor="reinit">
        <name>ReInitialization</name>
        <ul empty="true">
          <li>
            <t><strong>TODO</strong>: This topic requires further discussion around policy and lifecycle.
See also: Section 3.11 and Section 10.15 of
<xref target="I-D.robert-mimi-delivery-service"/>.</t>
          </li>
        </ul>
      </section>
      <section anchor="ev-mroomredaction">
        <name><tt>m.room.redaction</tt></name>
        <t><strong>Event type</strong>: <tt>m.room.redaction</tt></t>
        <t><strong>State key</strong>: Not present.</t>
        <t><strong>Additional event fields</strong>:</t>
        <artwork><![CDATA[
struct {
   // The event ID to redact.
   opaque redactedEventId;
} RedactionEvent;
]]></artwork>
        <t><strong>Additional authentication rules</strong>:</t>
        <ul spacing="normal">
          <li>
            <t>The <tt>redactedEventId</tt> <bcp14>MUST</bcp14> be an event in the room.</t>
          </li>
          <li>
            <t>The affected <tt>redactedEventId</tt> is redacted (<xref target="event-auth"/>) by the server upon
receipt.</t>
          </li>
        </ul>
        <t>Redaction events are sent to the hub server for fanout with <xref target="op-send"/>.</t>
      </section>
    </section>
    <section anchor="membership">
      <name>User Participation and Client Membership</name>
      <t>In a MIMI room, users are <em>participants</em> with an associated
<em>participation state</em> whereas clients of those users are <em>members</em> of the MLS
group. In most scenarios, the user's participation state is updated first or
simultaneously with the MLS group membership to enforce membership more easily.</t>
      <t>Users will always exist in one of the following participation states:</t>
      <artwork><![CDATA[
enum {
   invite,  // "Invited" state.
   join,    // "Joined" state.
   leave,   // "Left" state (including Kicked).
   ban,     // "Banned" state.
   knock,   // "Knocking" state.
} ParticipationState;
]]></artwork>
      <t>These states allow a user to remain logically "joined" to the conversation when
they have zero MLS-capable clients available. The user will not be able to see
messages sent while they had no clients, but can perform an external join at any
time to get back into the MLS group. A user with zero clients in the MLS group
is considered to be an <em>inactive participant</em>. Users with one or more clients
in the MLS group are <em>active participants</em>.</t>
      <t>All servers with at least one user of theirs in the "joined" participation state
are considered to be "in" or "participating" in the room. By default, all events
sent to a room are distrubuted by the hub to participating servers. This is
discussed further in <xref target="fanout"/>.</t>
      <section anchor="invites">
        <name>Invites</name>
        <t>An <em>invite</em> is when a user (or more specifically, a user's client) is attempting
to introduce <em>all</em> of another user's clients to the room and MLS group. This is
first done by updating the target user's participation state through the hub
server for the room.</t>
        <t>Updating the target user's participation state is done using the following
steps, and is visualized in <xref target="fig-invites"/>.</t>
        <ol spacing="normal" type="1"><li>
            <t>The inviter's server generates an <tt>m.room.user</tt> (<xref target="ev-mroomuser"/>) state
event to invite the target user. Typically this begins with a
client-initiated request to the server using the provider-specific API.</t>
          </li>
          <li>
            <t>The inviter's server sends (<xref target="op-send"/>) the <tt>m.room.user</tt> event to the hub
server. If the inviter's server is the hub server, it does the steps
described in <xref target="op-send"/> to complete the event.</t>
          </li>
          <li>
            <t>The hub server validates the event to ensure the following:  </t>
            <ul spacing="normal">
              <li>
                <t>The target user of the invite <bcp14>MUST NOT</bcp14> already be in the banned or joined
states.</t>
              </li>
              <li>
                <t>The sender of the invite <bcp14>MUST</bcp14> already be in the joined state.</t>
              </li>
            </ul>
          </li>
          <li>
            <t>If the event is invalid, it is rejected. Otherwise, it is forwarded by the
hub to the target user's server to give it the opportunity to reject the
invite early in the process. This is described by <xref target="op-check"/>.</t>
          </li>
          <li>
            <t>If the target server rejected the event, the event is rejected by the hub as
well. Otherwise, the event is fanned out (<xref target="fanout"/>) to all participating
servers, plus the target server if not already participating.</t>
          </li>
        </ol>
        <t>At this stage, the <em>user</em> is now invited but their clients are not members of
the MLS group. The invite is delivered to the target's clients through relevant
provider-specific API where the user can then accept or decline the invite.</t>
        <t>If the user declines the invite, they are transitioned to the leave state
described by <xref target="leaves"/>. Accepting is done by joining (<xref target="joins"/>) the room.</t>
        <figure anchor="fig-invites">
          <name>Invite happy path</name>
          <artset>
            <artwork type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="496" width="568" viewBox="0 0 568 496" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
                <path d="M 8,32 L 8,64" fill="none" stroke="black"/>
                <path d="M 24,72 L 24,480" fill="none" stroke="black"/>
                <path d="M 40,32 L 40,64" fill="none" stroke="black"/>
                <path d="M 232,112 L 232,144" fill="none" stroke="black"/>
                <path d="M 272,32 L 272,64" fill="none" stroke="black"/>
                <path d="M 296,72 L 296,480" fill="none" stroke="black"/>
                <path d="M 320,32 L 320,64" fill="none" stroke="black"/>
                <path d="M 512,240 L 512,272" fill="none" stroke="black"/>
                <path d="M 528,32 L 528,64" fill="none" stroke="black"/>
                <path d="M 544,72 L 544,480" fill="none" stroke="black"/>
                <path d="M 560,32 L 560,64" fill="none" stroke="black"/>
                <path d="M 8,32 L 40,32" fill="none" stroke="black"/>
                <path d="M 272,32 L 320,32" fill="none" stroke="black"/>
                <path d="M 528,32 L 560,32" fill="none" stroke="black"/>
                <path d="M 8,64 L 40,64" fill="none" stroke="black"/>
                <path d="M 272,64 L 320,64" fill="none" stroke="black"/>
                <path d="M 528,64 L 560,64" fill="none" stroke="black"/>
                <path d="M 32,112 L 232,112" fill="none" stroke="black"/>
                <path d="M 32,144 L 232,144" fill="none" stroke="black"/>
                <path d="M 32,192 L 288,192" fill="none" stroke="black"/>
                <path d="M 304,240 L 512,240" fill="none" stroke="black"/>
                <path d="M 304,272 L 512,272" fill="none" stroke="black"/>
                <path d="M 32,320 L 288,320" fill="none" stroke="black"/>
                <path d="M 304,368 L 536,368" fill="none" stroke="black"/>
                <path d="M 304,416 L 536,416" fill="none" stroke="black"/>
                <path d="M 32,464 L 288,464" fill="none" stroke="black"/>
                <path d="M 304,464 L 536,464" fill="none" stroke="black"/>
                <polygon class="arrowhead" points="544,464 532,458.4 532,469.6" fill="black" transform="rotate(0,536,464)"/>
                <polygon class="arrowhead" points="544,368 532,362.4 532,373.6" fill="black" transform="rotate(0,536,368)"/>
                <polygon class="arrowhead" points="312,416 300,410.4 300,421.6" fill="black" transform="rotate(180,304,416)"/>
                <polygon class="arrowhead" points="312,272 300,266.4 300,277.6" fill="black" transform="rotate(180,304,272)"/>
                <polygon class="arrowhead" points="296,192 284,186.4 284,197.6" fill="black" transform="rotate(0,288,192)"/>
                <polygon class="arrowhead" points="40,464 28,458.4 28,469.6" fill="black" transform="rotate(180,32,464)"/>
                <polygon class="arrowhead" points="40,320 28,314.4 28,325.6" fill="black" transform="rotate(180,32,320)"/>
                <polygon class="arrowhead" points="40,144 28,138.4 28,149.6" fill="black" transform="rotate(180,32,144)"/>
                <g class="text">
                  <text x="24" y="52">A</text>
                  <text x="296" y="52">Hub</text>
                  <text x="544" y="52">B</text>
                  <text x="60" y="100">Create</text>
                  <text x="136" y="100">m.room.user</text>
                  <text x="212" y="100">invite</text>
                  <text x="52" y="180">Send</text>
                  <text x="96" y="180">event</text>
                  <text x="152" y="180">request</text>
                  <text x="224" y="180">initiated</text>
                  <text x="340" y="228">Validate</text>
                  <text x="424" y="228">m.room.user</text>
                  <text x="496" y="228">event</text>
                  <text x="72" y="308">200</text>
                  <text x="100" y="308">OK</text>
                  <text x="124" y="308">to</text>
                  <text x="156" y="308">send</text>
                  <text x="200" y="308">event</text>
                  <text x="256" y="308">request</text>
                  <text x="328" y="356">Check</text>
                  <text x="376" y="356">event</text>
                  <text x="432" y="356">request</text>
                  <text x="496" y="404">200</text>
                  <text x="524" y="404">OK</text>
                  <text x="136" y="452">Async</text>
                  <text x="188" y="452">fanout</text>
                  <text x="228" y="452">of</text>
                  <text x="264" y="452">event</text>
                  <text x="328" y="452">Async</text>
                  <text x="380" y="452">fanout</text>
                  <text x="420" y="452">of</text>
                  <text x="456" y="452">event</text>
                </g>
              </svg>
            </artwork>
            <artwork type="ascii-art"><![CDATA[
+---+                            +-----+                         +---+
| A |                            | Hub |                         | B |
+---+                            +-----+                         +---+
  |                                 |                              |
  | Create m.room.user invite       |                              |
  |-------------------------+       |                              |
  |                         |       |                              |
  |<------------------------+       |                              |
  |                                 |                              |
  | Send event request initiated    |                              |
  |-------------------------------->|                              |
  |                                 |                              |
  |                                 | Validate m.room.user event   |
  |                                 |--------------------------+   |
  |                                 |                          |   |
  |                                 |<-------------------------+   |
  |                                 |                              |
  |    200 OK to send event request |                              |
  |<--------------------------------|                              |
  |                                 |                              |
  |                                 | Check event request          |
  |                                 |----------------------------->|
  |                                 |                              |
  |                                 |                       200 OK |
  |                                 |<-----------------------------|
  |                                 |                              |
  |           Async fanout of event | Async fanout of event        |
  |<--------------------------------|----------------------------->|
  |                                 |                              |
]]></artwork>
          </artset>
        </figure>
      </section>
      <section anchor="joins">
        <name>Joins</name>
        <t>A user can join a room in two ways:</t>
        <ol spacing="normal" type="1"><li>
            <t>Using an external commit to Add themselves to the MLS group.</t>
          </li>
          <li>
            <t>Receiving a Welcome message from a joined member of the MLS group.</t>
          </li>
        </ol>
        <t>In both cases, a join <tt>m.room.user</tt> (<xref target="ev-mroomuser"/>) state event is also sent.</t>
        <t>Typically, a client will use the first option when joining a public room or
responding to an invite because the hub server can assist them in the join.
Option 2 is generally used as a form of invite, though skipping the explicit
<tt>m.room.user</tt> invite described by <xref target="invites"/>.</t>
        <t>The hub server <bcp14>MUST</bcp14> allow proposals and commits to add a user's own clients if
they're in the joined participation state. Similarly, the hub server <bcp14>MUST NOT</bcp14>
allow proposals or commits to add clients which are not in the joined
participation state. These conditions permit the user to add their own clients
after joining without issue, which may involve an external commit.</t>
        <section anchor="join-external">
          <name>External Commit Flow</name>
          <t>The joining user's server first updates the user's participation state (an
<tt>m.room.user</tt> state event, <xref target="ev-mroomuser"/>) and sends that to the hub
(<xref target="op-send"/>) for validation. If the joining user's server is the hub server, it
does the steps described in <xref target="op-send"/> to complete the event.</t>
          <t>The join event is then validated by the hub as follows:</t>
          <ul spacing="normal">
            <li>
              <t>The target and sending user of the event <bcp14>MUST</bcp14> be the same.</t>
            </li>
            <li>
              <t>The target user <bcp14>MUST NOT</bcp14> be banned from the room.</t>
            </li>
          </ul>
          <ul empty="true">
            <li>
              <t><strong>TODO</strong>: Does requiring the sender and state key to be the same prohibit
the Welcome flow from working? (I don't believe so because they still need
to Add themselves?)</t>
            </li>
          </ul>
          <ul empty="true">
            <li>
              <t><strong>TODO</strong>: Incorporate public and invite-only room conditions from policy.</t>
            </li>
          </ul>
          <t>If the event is valid, it is fanned out (<xref target="fanout"/>) to all participating
servers in the room, which now includes the joining server (if not already).</t>
          <ul empty="true">
            <li>
              <t><strong>TODO</strong>: It would be helpful if in response to the send request the hub
server provided information required to externally join, maybe.</t>
            </li>
          </ul>
          <t>The user's clients are then able to use external commits to join the MLS group.
This is accomplished using <xref target="op-external-join"/>.</t>
        </section>
        <section anchor="join-welcome">
          <name>Welcome Flow</name>
          <ul empty="true">
            <li>
              <t><strong>TODO</strong>: Is this better phrased as an invite rather than join?</t>
            </li>
          </ul>
          <t>This flow is more similar to an invite (<xref target="invites"/>), though provides the
receiving user's clients with enough information to join without external
commit.</t>
          <t>The inviting user's client first requests KeyPackages for all of the target
user's client through <xref target="op-claim"/>. The inviting client then uses the
KeyPackages to create Welcome MLS messages for the target user's clients.</t>
          <t>The Welcome messages are sent to the hub server alongside an <tt>m.room.user</tt>
(<xref target="ev-mroomuser"/>) invite event using <xref target="op-send"/>. If the inviting user's server
is the hub server for the room, it completes the event using the steps described
by <xref target="op-send"/> instead. The event is validated according to <xref target="invites"/> and
fanned out (<xref target="fanout"/>) to all participating servers, plus the target user's
server. The target user's server also receives the Welcome messages to deliver
to the relevant clients.</t>
          <t>The user can then join the room by sending an <tt>m.room.user</tt> join event. The
process and applied validation are the same as <xref target="join-external"/>. The user's
clients can then Add themselves to the MLS group using the Welcome messages they
received earlier. If the Welcome messages are no longer valid, the clients can
use external commits instead.</t>
          <ul empty="true">
            <li>
              <t><strong>TODO</strong>: Should we permit the join event to be accompanied by the client's
Add commits?</t>
            </li>
          </ul>
          <ul empty="true">
            <li>
              <t><strong>TODO</strong>: Is this Welcome flow correct, specifically the handling of Welcome
MLS messages?</t>
            </li>
          </ul>
        </section>
      </section>
      <section anchor="leaves">
        <name>Leaves/Kicks</name>
        <t>Leaving a room can signal a user declining an invite, voluntarily leaving the
room, or being kicked (removed) from the room. When the sender and target of
an <tt>m.room.user</tt> (<xref target="ev-mroomuser"/>) leave event are different, the target user
is being kicked. Otherwise the event represents a voluntary leave or declined
invite (if the previous participation state was "invited").</t>
        <t>Like with other participation/membership operations, a user's leave is initiated
by updating their participation state first. This is done by sending
(<xref target="op-send"/>) the relevant <tt>m.room.user</tt> (<xref target="ev-mroomuser"/>) state event to the
hub, which validates it as follows:</t>
        <ul spacing="normal">
          <li>
            <t>If the target and sender are the same, the user <bcp14>MUST</bcp14> be in the invited,
joined, or knocking participation state.</t>
          </li>
          <li>
            <t>Otherwise:  </t>
            <ul spacing="normal">
              <li>
                <t>The target user of the kick <bcp14>MUST</bcp14> be in the joined participation state.</t>
              </li>
              <li>
                <t>The sender for a kick <bcp14>MUST</bcp14> be in the joined participation state.</t>
              </li>
            </ul>
          </li>
        </ul>
        <ul empty="true">
          <li>
            <t><strong>TODO</strong>: Include special case permissions constraints.</t>
          </li>
        </ul>
        <t>If the event is valid, it is fanned out (<xref target="fanout"/>) to all particpating
servers, plus the target user's server.</t>
        <t>The next commit in the MLS group <bcp14>MUST</bcp14> remove <em>all</em> of the target user's clients.
If there are multiple users in the leave participation state, all of their
clients <bcp14>MUST</bcp14> be removed in the same commit. Other proposals <bcp14>MAY</bcp14> be committed
alongside the removals, however the commit <bcp14>MUST</bcp14> at a minimum remove the affected
clients.</t>
        <ul empty="true">
          <li>
            <t><strong>TODO</strong>: Describe how hub server generates proposals? Or do we just require
some member in the group to do it? See also: Section 3.5 of
<xref target="I-D.robert-mimi-delivery-service"/>.</t>
          </li>
        </ul>
        <t>Prior to a voluntary <tt>m.room.user</tt> leave event, the sender <bcp14>SHOULD</bcp14> send proposals
to remove their own clients from the MLS group. Where possible, those clients
<bcp14>SHOULD</bcp14> commit their removal prior to updating their participation state as well.</t>
        <t>Clients can propose to remove themselves from the MLS group at any time. The hub
server <bcp14>MUST</bcp14> allow commits at any time to honor those proposals. The hub server
<bcp14>MUST NOT</bcp14> allow a commit which contains an inline proposal to remove another
client, unless that client belongs to a user in the leave participation state.</t>
      </section>
      <section anchor="bans">
        <name>Bans</name>
        <t>Bans imply kick, and are operated the same way as <xref target="leaves"/>, though with the
<tt>m.room.user</tt> (<xref target="ev-mroomuser"/>) state event using a <tt>ban</tt> participation state.</t>
        <t>An added exception on the validation is also applied to permit preemptive bans:
the target user is not required to be in the joined state to allow the
participation state change.</t>
        <t>Unbans can be performed by transitioning a user from the banned participation
state to leave with <xref target="leaves"/>.</t>
      </section>
      <section anchor="knocks">
        <name>Knocks</name>
        <t>In this state, the sender of a knock is requesting an invite (<xref target="invites"/>) to
the room. They do not have access to the MLS group.</t>
        <ul empty="true">
          <li>
            <t><strong>TODO</strong>: Discuss if this participation state is desirable, and figure out
details for how it works. It'd likely just be an <tt>m.room.user</tt> state event
with no MLS interaction, like invites are.</t>
          </li>
        </ul>
      </section>
      <section anchor="ev-mroomuser">
        <name><tt>m.room.user</tt></name>
        <t><strong>Event type</strong>: <tt>m.room.user</tt></t>
        <t><strong>State key</strong>: ID of target user.</t>
        <t><strong>Additional event fields</strong>:</t>
        <artwork><![CDATA[
struct {
   // The new participation state for the target user.
   ParticipationState state;

   // Optional human-readable reason for the change. Typically most
   // useful on bans and knocks.
   opaque [[reason]];
} UserEvent;
]]></artwork>
        <t><strong>Additional authentication rules</strong>:</t>
        <ul spacing="normal">
          <li>
            <t>The event's <tt>authEventIds</tt> <bcp14>MUST</bcp14> include a reference to the sender's
most recent <tt>m.room.user</tt> event, if one exists, and the room's <tt>m.room.create</tt>
event.</t>
          </li>
          <li>
            <t>Rules described by <xref target="invites"/>, <xref target="joins"/>, <xref target="leaves"/>, <xref target="bans"/>, <xref target="knocks"/>.</t>
          </li>
        </ul>
        <ul empty="true">
          <li>
            <t><strong>TODO</strong>: Include auth rules for permissions.</t>
          </li>
        </ul>
        <ul empty="true">
          <li>
            <t><strong>TODO</strong>: Somehow link the event to a client identity? (or several clients)
See also: Section 3.8 of <xref target="I-D.robert-mimi-delivery-service"/>.</t>
          </li>
        </ul>
      </section>
    </section>
    <section anchor="application-messages">
      <name>Application Messages</name>
      <t>Clients engage in messaging through use of a content format
(<xref target="I-D.ietf-mimi-content"/>) and MLS Application Messages. The resulting
<tt>PrivateMessage</tt> is carried in an <tt>m.room.encrypted</tt> (<xref target="ev-mroomencrypted"/>)
event.</t>
      <t>The client's server sends the event to the hub with <xref target="op-send"/>. If the client's
server is the room's hub server, it completes the events with the steps
described by <xref target="op-send"/> instead. The event is then fanned out (<xref target="fanout"/>) by
the hub to all participating servers in the room, including the sender's.</t>
      <t>How the event goes from client to server, and server to client, is out of scope
for this document.</t>
      <section anchor="ev-mroomencrypted">
        <name><tt>m.room.encrypted</tt></name>
        <t><strong>Event type</strong>: <tt>m.room.encrypted</tt></t>
        <t><strong>State key</strong>: Not present.</t>
        <t><strong>Additional event fields</strong>:</t>
        <artwork><![CDATA[
struct {
   // The PrivateMessage
   MLSMessage message;
} EncryptedEvent;
]]></artwork>
        <t><strong>Additional authentication rules</strong>:</t>
        <ul spacing="normal">
          <li>
            <t><tt>message</tt> <bcp14>MUST</bcp14> be an MLS PrivateMessage.</t>
          </li>
        </ul>
      </section>
    </section>
    <section anchor="transport">
      <name>Transport</name>
      <t>Servers communicate with each other over HTTP <xref target="RFC9110"/>. Endpoints have the
protocol version embedded into the path for simplified routing between physical
servers.</t>
      <section anchor="authentication">
        <name>Authentication</name>
        <t>All endpoints, with the exception of <tt>.well-known</tt> endpoints use the mutually
authenticated mode of TLS <xref target="RFC5246"/>. This provides guarantees that each
server is speaking to an expected party.</t>
        <ul empty="true">
          <li>
            <t><strong>TODO</strong>: More information specific to how TLS should be used, i.e. mandate
best practices that make sense in a mutually authenticated scenario that
involves two WebPKI based certificates.</t>
          </li>
        </ul>
        <t>Individual events may transit between multiple servers. TLS provides
point-to-point security properties while <xref target="event-auth"/> provides event security
guarantees when transiting over multiple servers.</t>
      </section>
      <section anchor="endpoint-discovery">
        <name>Endpoint Discovery</name>
        <t>A messaging provider that wants to query the endpoint of another messaging
provider first has to discover the fully qualified domain name it can use to
communicate with that provider. It does so by performing a GET request to
<tt>https://example.org/.well-known/mimi/domain</tt>. example.org could, for example,
answer by providing the domain <tt>mimi.example.org</tt> (assuming that this is where
it responds to the REST endpoints defined in <xref target="rest-api"/>).</t>
        <t>The expected response format is simply a <tt>text/plain</tt> body containing the fully
qualified domain name.</t>
        <artwork><![CDATA[
GET https://example.org/.well-known/mimi/domain

Response
mimi.example.org
]]></artwork>
      </section>
      <section anchor="rest-api">
        <name>REST Endpoints</name>
        <t>The following REST endpoints can be used to communicate with a MIMI server.</t>
        <t>All operations rely on TLS-encoded structs and therefore requests and responses
<bcp14>SHOULD</bcp14> use a <tt>Content-Type</tt> of <tt>application/octet-stream</tt>.</t>
        <section anchor="op-send">
          <name>Send Event</name>
          <t>Asks the server to send an event (<xref target="event-schema"/>). Events can take two shapes
over this endpoint, depending on whether a follower or hub server is doing the
sending.</t>
          <t>When a follower server is sending an event, it <bcp14>MUST</bcp14> only be attempting to send
to the hub server for the room. Follower servers receiving an event from another
follower server <bcp14>MUST</bcp14> reject the request with a <tt>400</tt> HTTP status code. The hub
server <bcp14>MUST</bcp14> populate the <tt>authEventIds</tt> and <tt>prevEventId</tt> fields of the event,
validate the resulting event, then reply with a <tt>200</tt> HTTP status code and the
resulting event ID (<xref target="reference-hash"/>). The resulting event is then fanned out
<xref target="fanout"/> to relevant servers in the room.</t>
          <t>The hub server <bcp14>MUST</bcp14> validate events according to <xref target="event-auth"/> and any event
type-specific validation rules. If the event is malformed in any way, or the
room is unknown, the server <bcp14>MUST</bcp14> respond with a <tt>400</tt> HTTP status code.</t>
          <t>Follower servers <bcp14>SHOULD</bcp14> apply the same validation as hub servers upon receiving
a send request to identify potentially malicious hub servers.</t>
          <t>Follower servers sending an event to the hub server will not include
<tt>authEventIds</tt> or <tt>prevEventId</tt> because they are populated by the hub server.
Hub servers <bcp14>MUST</bcp14> employ locking to ensure each event has exactly one child
implied by <tt>prevEventId</tt>. This locking mechanism <bcp14>MAY</bcp14> cause another request to be
rejected because the room state was mutated. For example, if the hub receives
a ban event in one request and a message from the to-be-banned user in another,
the message may be rejected if the ban is processed first. Hub servers <bcp14>SHOULD</bcp14>
process requests in the order they were received.</t>
          <t>If an event is rejected during processing, the event <bcp14>MUST NOT</bcp14> be fanned out.</t>
          <artwork><![CDATA[
struct {
   // The resulting event ID that is about to be fanned out by the hub server.
   // Not included if the called server is a follower server.
   opaque [[eventId]];
} SendEndpointResponse;
]]></artwork>
          <artwork><![CDATA[
POST /v1/send
Content-Type: application/octet-stream

Body
TLS-serialized Event (including additional fields, such as CreateEvent)

Response
TLS-serialized SendEndpointResponse
]]></artwork>
          <t>Servers <bcp14>SHOULD</bcp14> retry this request with exponential backoff (to a limit) if they
receive timeout/network errors.</t>
          <section anchor="fanout">
            <name>Fanout</name>
            <t>A hub server fans an event out by using the send endpoint described above on all
participating servers in the room. A server is considered "participating" if it
has at least one user in the joined participation state, described by
<xref target="membership"/>.</t>
            <t>Additional servers <bcp14>MAY</bcp14> have the event sent to them if required by the steps
leading up to fanout.</t>
          </section>
        </section>
        <section anchor="op-check">
          <name>Check Invite Event</name>
          <t>Used by the hub server to ensure a follower server can (and is willing to)
process an incoming invite. The called server <bcp14>MAY</bcp14> use this opportunity to ensure
the inviting user has general consent to invite the target user. For example,
ensuring the invite does not appear spammy in nature and if the inviter already
has a connection with the invitee.</t>
          <t>If the server does not recognize the event format of the <tt>m.room.create</tt>
(<xref target="ev-mroomcreate"/>) event, or does not understand the policy/encryption
configuration contained within, it <bcp14>MUST</bcp14> reject the request.</t>
          <t>The request <bcp14>MAY</bcp14> be rejected with a <tt>400</tt> HTTP status code. If everything looks
OK to the server, it responds with a <tt>200</tt> HTTP status code.</t>
          <artwork><![CDATA[
struct {
   // The `m.room.user` invite event.
   UserEvent invite;

   // The `m.room.create` event for the room.
   CreateEvent roomCreate;
} CheckInviteRequest;
]]></artwork>
          <artwork><![CDATA[
POST /v1/check-invite
Content-Type: application/octet-stream

Body
TLS-serialized CheckInviteRequest

Response
Any meaningful information. The pass/fail is identified by the HTTP response
status code, not the response body.
]]></artwork>
          <t>The hub server <bcp14>SHOULD</bcp14> consider a network error as a rejection. It is expected
that the original sender will attempt to re-send the invite once the server is
reachable again.</t>
        </section>
        <section anchor="op-get-event">
          <name>Retrieve Event</name>
          <ul empty="true">
            <li>
              <t><strong>TODO</strong>: What specific APIs does a follower server need to operate? Some
options include:</t>
              <ul spacing="normal">
                <li>
                  <t><tt>GET /v1/event/:eventId</tt></t>
                </li>
                <li>
                  <t><tt>GET /v1/room/:roomId/state</tt> (current room state events)</t>
                </li>
                <li>
                  <t><tt>GET /v1/room/:roomId/state/:eventType/:stateKey</tt></t>
                </li>
                <li>
                  <t><tt>GET /v1/event/:eventId/child</tt></t>
                </li>
              </ul>
            </li>
          </ul>
        </section>
        <section anchor="op-claim">
          <name>Retrieve KeyPackages</name>
          <t>Asks the server for KeyPackages belonging to a user's clients. Like with
<xref target="op-check"/>, if the requesting user does not have general consent to invite the
target user, the request is rejected.</t>
          <t>To ensure requests do not fail while clients are offline or otherwise
unreachable, KeyPackages <bcp14>SHOULD</bcp14> be uploaded by the generating client to their
local server for later usage.</t>
          <ul empty="true">
            <li>
              <t><strong>TODO</strong>: Mark KeyPackages of last resort somehow.</t>
            </li>
          </ul>
          <t>This request is always sent to the hub server which then proxies the request
directly to the relevant follower server.</t>
          <artwork><![CDATA[
struct {
   // The user ID to retrieve KeyPackages for. This will download 1 KeyPackage
   // for each of the user's clients.
   opaque userId;

   // The user ID requesting the KeyPackages for `userId`.
   opaque requestingUserId;

   // The room (group) ID where the KeyPackages are valid for.
   opaque roomId;
} GetKeyPackagesRequest;

struct {
   // One KeyPackage for each of the requested user's clients.
   KeyPackage keyPackages<V>;
} GetKeyPackagesResponse;
]]></artwork>
          <ul empty="true">
            <li>
              <t><strong>TODO</strong>: Do we need to sign or otherwise guarantee security on the
<tt>requestingUserId</tt>? We do for invite events, so why not here?</t>
            </li>
          </ul>
          <artwork><![CDATA[
POST /v1/key_packages
Content-Type: application/octet-stream

Body
TLS-serialized GetKeyPackagesRequest

Response
TLS-serialized GetKeyPackagesResponse
]]></artwork>
        </section>
        <section anchor="op-external-join">
          <name>External Group Join</name>
          <t>When a client wishes to perform an external join to the MLS group, it may
require assistance from the hub server in order to be successful. This endpoint
is used by a follower server on a client's behalf to complete the external join.</t>
          <t>The hub server is able to provide this service to the requester because it keeps
track of the information required to generate a GroupInfo object. The requester
is still required to supply a <tt>Signature</tt> and relevant GroupInfo extensions,
which are required to complete the GroupInfo object.</t>
          <artwork><![CDATA[
struct {
   Extension group_info_extensions<V>;
   opaque Signature<V>;
} PartialGroupInfo;

struct {
   MLSMessage commit;
   PartialGroupInfo partial_group_info;
} MLSGroupUpdate;
]]></artwork>
          <t>The MLSMessage <bcp14>MUST</bcp14> contain a PublicMessage which contains a commit with sender
type NewMemberCommit.</t>
          <artwork><![CDATA[
POST /v1/external_join
Content-Type: application/octet-stream

Body
TLS-serialized MLSGroupUpdate

Response
Any meaningful information. The pass/fail is identified by the HTTP response
status code, not the response body.
]]></artwork>
        </section>
        <section anchor="op-mls-add">
          <name>Add, Remove, and Update MLS Group Clients</name>
          <t>As described by <xref target="joins"/>, users which are joined participants are able to add
their clients at any time to the MLS group. Clients which do not belong to a
joined user <bcp14>MUST</bcp14> be rejected from joining the group. Similarly, clients may
elect to leave the MLS group at any time, as per <xref target="leaves"/>.</t>
          <artwork><![CDATA[
struct {
   // MUST be a PublicMessage with a commit that only contains Add proposals
   // for a joined user's clients.
   //
   // MUST NOT change the sending client's credential.
   MLSGroupUpdate group_update;
   MLSMessage welcome_messages<V>;
} AddClientsRequest;

struct {
   // MUST NOT change the sending client's credential.
   MLSGroupUpdate group_update;
} RemoveClientsRequest;

struct {
   // MUST contain a PublicMessage which contains a commit with an UpdatePath,
   // but not other proposals by value.
   MLSGroupUpdate group_update;
} UpdateClientRequest;

enum {
   add,
   remove,
   update,
} MLSOperation;

struct {
   MLSOperation operation;

   select (GroupUpdateRequest.operation) {
      case add:
         AddClientsRequest request;
      case remove:
         RemoveClientsRequest request;
      case update:
         UpdateClientRequest request;
   }
} GroupUpdateRequest;
]]></artwork>
          <t>The group update contained within <tt>RemoveClientsRequest</tt> is additionally subject
to the requirements of <xref target="leaves"/>.</t>
          <artwork><![CDATA[
POST /v1/group_update
Content-Type: application/octet-stream

Body
TLS-serialized GroupUpdateRequest

Response
Any meaningful information. The pass/fail is identified by the HTTP response
status code, not the response body.
]]></artwork>
        </section>
      </section>
    </section>
    <section anchor="security-considerations">
      <name>Security Considerations</name>
      <t>Overall, the user participation state leads any possible MLS group state to
ensure malicious clients are not able to easily get access to messages.</t>
      <ul empty="true">
        <li>
          <t><strong>TODO</strong>: Other security guarantees? Consensus may be required here.</t>
        </li>
      </ul>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <t>IANA has created the following registries:</t>
      <ul spacing="normal">
        <li>
          <t>MIMI Event Types</t>
        </li>
      </ul>
      <section anchor="mimi-event-types">
        <name>MIMI Event Types</name>
        <t>An event type denotes the nature of a payload contained in an event, in the
context of the MIMI protocol. The event type is a string composed of substrings
separated by dots.</t>
        <t>The first substring is "m", followed by the logical container being affected
(typically just "room"), then a number of descriptor strings.</t>
        <t>Example: <tt>m.room.create</tt></t>
        <ul empty="true">
          <li>
            <t><strong>TODO</strong>: Does IANA need any other information for legal event types?</t>
          </li>
        </ul>
      </section>
    </section>
  </middle>
  <back>
    <references>
      <name>References</name>
      <references anchor="sec-normative-references">
        <name>Normative References</name>
        <reference anchor="RFC9420">
          <front>
            <title>The Messaging Layer Security (MLS) Protocol</title>
            <author fullname="R. Barnes" initials="R." surname="Barnes"/>
            <author fullname="B. Beurdouche" initials="B." surname="Beurdouche"/>
            <author fullname="R. Robert" initials="R." surname="Robert"/>
            <author fullname="J. Millican" initials="J." surname="Millican"/>
            <author fullname="E. Omara" initials="E." surname="Omara"/>
            <author fullname="K. Cohn-Gordon" initials="K." surname="Cohn-Gordon"/>
            <date month="July" 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 (FS) and post-compromise security (PCS) for groups in size ranging from two to thousands.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="9420"/>
          <seriesInfo name="DOI" value="10.17487/RFC9420"/>
        </reference>
        <reference anchor="I-D.barnes-mimi-arch">
          <front>
            <title>An Architecture for More Instant Messaging Interoperability (MIMI)</title>
            <author fullname="Richard Barnes" initials="R." surname="Barnes">
              <organization>Cisco</organization>
            </author>
            <date day="23" month="October" year="2023"/>
            <abstract>
              <t>   The More Instant Messaging Interoperability (MIMI) working group is
   defining a suite of protocols that allow messaging providers to
   interoperate with one another.  This document lays out an overall
   architecture enumerating the MIMI protocols and how they work
   together to enable an overall messaging experience.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-barnes-mimi-arch-02"/>
        </reference>
        <reference anchor="RFC5246">
          <front>
            <title>The Transport Layer Security (TLS) Protocol Version 1.2</title>
            <author fullname="T. Dierks" initials="T." surname="Dierks"/>
            <author fullname="E. Rescorla" initials="E." surname="Rescorla"/>
            <date month="August" year="2008"/>
            <abstract>
              <t>This document specifies Version 1.2 of the Transport Layer Security (TLS) protocol. The TLS protocol provides communications security over the Internet. The protocol allows client/server applications to communicate in a way that is designed to prevent eavesdropping, tampering, or message forgery. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="5246"/>
          <seriesInfo name="DOI" value="10.17487/RFC5246"/>
        </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="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="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="I-D.barnes-mimi-architecture">
          <front>
            <title>*** BROKEN REFERENCE ***</title>
            <author>
              <organization/>
            </author>
            <date/>
          </front>
        </reference>
      </references>
      <references anchor="sec-informative-references">
        <name>Informative References</name>
        <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="I-D.robert-mimi-delivery-service">
          <front>
            <title>MIMI Delivery Service</title>
            <author fullname="Raphael Robert" initials="R." surname="Robert">
              <organization>Phoenix R&amp;D</organization>
            </author>
            <author fullname="Konrad Kohbrok" initials="K." surname="Kohbrok">
              <organization>Phoenix R&amp;D</organization>
            </author>
            <date day="23" month="October" year="2023"/>
            <abstract>
              <t>   This document describes the MIMI Delivery Service.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-robert-mimi-delivery-service-05"/>
        </reference>
        <reference anchor="I-D.ietf-mimi-content">
          <front>
            <title>More Instant Messaging Interoperability (MIMI) message content</title>
            <author fullname="Rohan Mahy" initials="R." surname="Mahy">
              <organization>Wire</organization>
            </author>
            <date day="23" month="October" year="2023"/>
            <abstract>
              <t>   This document describes content semantics common in Instant Messaging
   (IM) systems and describes a profile suitable for instant messaging
   interoperability of messages end-to-end encrypted inside the MLS
   (Message Layer Security) Protocol.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ietf-mimi-content-01"/>
        </reference>
        <reference anchor="I-D.kohbrok-mimi-transport">
          <front>
            <title>MIMI Transport</title>
            <author fullname="Konrad Kohbrok" initials="K." surname="Kohbrok">
              <organization>Phoenix R&amp;D</organization>
            </author>
            <author fullname="Raphael Robert" initials="R." surname="Robert">
              <organization>Phoenix R&amp;D</organization>
            </author>
            <date day="21" month="September" year="2023"/>
            <abstract>
              <t>   This document defines an HTTPS based transport layer for use with the
   MIMI Protocol.

Discussion Venues

   This note is to be removed before publishing as an RFC.

   Discussion of this document takes place on the More Instant Messaging
   Interoperability Working Group mailing list (mimi@ietf.org), which is
   archived at https://mailarchive.ietf.org/arch/browse/mimi/.

   Source for this draft and an issue tracker can be found at
   https://github.com/kkohbrok/mimi-transport.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-kohbrok-mimi-transport-01"/>
        </reference>
        <reference anchor="I-D.ralston-mimi-signaling">
          <front>
            <title>MIMI Signaling Protocol</title>
            <author fullname="Travis Ralston" initials="T." surname="Ralston">
              <organization>The Matrix.org Foundation C.I.C.</organization>
            </author>
            <author fullname="Matthew Hodgson" initials="M." surname="Hodgson">
              <organization>The Matrix.org Foundation C.I.C.</organization>
            </author>
            <date day="22" month="September" year="2023"/>
            <abstract>
              <t>   The MIMI signaling protocol describes a framework for user-level
   interactions in the overall MIMI protocol stack.  The event structure
   can be used by control protocols described by [I-D.barnes-mimi-arch].

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ralston-mimi-signaling-00"/>
        </reference>
        <reference anchor="I-D.ralston-mimi-policy">
          <front>
            <title>MIMI Policy Envelope</title>
            <author fullname="Travis Ralston" initials="T." surname="Ralston">
              <organization>The Matrix.org Foundation C.I.C.</organization>
            </author>
            <author fullname="Matthew Hodgson" initials="M." surname="Hodgson">
              <organization>The Matrix.org Foundation C.I.C.</organization>
            </author>
            <date day="22" month="September" year="2023"/>
            <abstract>
              <t>   The MIMI Policy Envelope describes a _policy control protocol_ and
   _participation control protocol_ for use in a room, applied at the
   user participation level, as described by [I-D.barnes-mimi-arch].

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ralston-mimi-policy-00"/>
        </reference>
      </references>
    </references>
    <?line 1044?>

<section numbered="false" anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>This document is the consolidation of the following documents:</t>
      <ul spacing="normal">
        <li>
          <t><xref target="I-D.kohbrok-mimi-transport"/> forms the majority of <xref target="transport"/>.</t>
        </li>
        <li>
          <t><xref target="I-D.robert-mimi-delivery-service"/> describes details for <xref target="membership"/>,
subsections of <xref target="rest-api"/> (per transport draft), <xref target="reinit"/>, and
considerations for <xref target="ev-mroomencrypted"/>.</t>
        </li>
        <li>
          <t><xref target="I-D.ralston-mimi-signaling"/> describes <xref target="event-schema"/>, <xref target="event-auth"/>,
<xref target="room-creation"/>, details of <xref target="membership"/>, and subsections of <xref target="rest-api"/>.</t>
        </li>
      </ul>
      <t>Aspects of <xref target="I-D.ralston-mimi-policy"/> are additionally taken into
consideration in this document through subsections of <xref target="membership"/>, but is
largely unincorporated and may require updates to match this document's
specifics.</t>
      <t><xref target="I-D.barnes-mimi-architecture"/> was additionally used throughout the writing
of this document.</t>
    </section>
  </back>
  <!-- ##markdown-source:
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
AA==

-->

</rfc>
