<?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.43 (Ruby 4.0.7) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-ietf-mimi-protocol-07" category="std" consensus="true" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.35.0 -->
  <front>
    <title abbrev="MIMI+MLS Protocol">More Instant Messaging Interoperability (MIMI) using HTTPS and MLS</title>
    <seriesInfo name="Internet-Draft" value="draft-ietf-mimi-protocol-07"/>
    <author fullname="Richard L. Barnes">
      <organization>Cisco</organization>
      <address>
        <email>rlb@ipv.sx</email>
      </address>
    </author>
    <author fullname="Matthew Hodgson">
      <organization>The Matrix.org Foundation C.I.C.</organization>
      <address>
        <email>matthew@matrix.org</email>
      </address>
    </author>
    <author fullname="Konrad Kohbrok">
      <organization>Phoenix R&amp;D</organization>
      <address>
        <email>konrad.kohbrok@datashrine.de</email>
      </address>
    </author>
    <author fullname="Rohan Mahy">
      <organization>Rohan Mahy Consulting Services</organization>
      <address>
        <email>rohan.ietf@gmail.com</email>
      </address>
    </author>
    <author fullname="Travis Ralston">
      <organization>The Matrix.org Foundation C.I.C.</organization>
      <address>
        <email>travisr@matrix.org</email>
      </address>
    </author>
    <author fullname="Raphael Robert">
      <organization>Phoenix R&amp;D</organization>
      <address>
        <email>ietf@raphaelrobert.com</email>
      </address>
    </author>
    <date year="2026" month="November" day="02"/>
    <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 105?>

<t>This document specifies the More Instant Messaging Interoperability (MIMI)
transport protocol, which allows users of different messaging providers to
interoperate in group chats (rooms), including to send and receive messages,
share room policy, and add participants to and remove participants from rooms.
MIMI describes messages between providers, leaving most aspects of the
provider-internal client-server communication up to the provider.  MIMI
integrates the Messaging Layer Security (MLS) protocol to provide end-to-end security
assurances, including authentication of protocol participants, confidentiality
of messages exchanged within a room, and agreement on the state of the room.</t>
    </abstract>
    <note removeInRFC="true">
      <name>About This Document</name>
      <t>
        The latest revision of this draft can be found at <eref target="https://bifurcation.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-ietf-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/bifurcation/ietf-mimi-protocol"/>.</t>
    </note>
  </front>
  <middle>
    <?line 117?>

<section anchor="introduction">
      <name>Introduction</name>
      <t>The More Instant Messaging Interoperability (MIMI) transport protocol enables providers of
end-to-end encrypted instant messaging to interoperate. As described in the MIMI
architecture <xref target="I-D.ietf-mimi-arch"/>, group chats and direct messages are
described in terms of "rooms".  Each MIMI protocol room is hosted at a single
provider (the "hub" provider"), but allows users from different providers to
become participants in the room. The hub provider is responsible for ordering
and distributing messages, enforcing policy, and authorizing messages. It also
keeps a copy of the room state, which includes the room policy and participant
list, which it can provide to new joiners. Each provider also
stores initial keying material for its own users (who may be offline).</t>
      <t>This document describes the communication among different providers necessary to
support messaging application functionality, for example:</t>
      <ul spacing="normal">
        <li>
          <t>Sharing room policy</t>
        </li>
        <li>
          <t>Adding and removing participants in a room</t>
        </li>
        <li>
          <t>Exchanging secure messages</t>
        </li>
      </ul>
      <t>In support of these functions, the protocol also has primitives to fetch initial
keying material and fetch the current state of the underlying end-to-end encryption
protocol for the room.</t>
      <t>Messages sent inside each room are end-to-end encrypted using the Messaging
Layer Security (MLS) protocol <xref target="RFC9420"/>, and each room is associated with an
MLS group. MLS also ensures that clients in a room agree on the room policy and
participation.  MLS is integrated into MIMI in such a way as to ensure that a
client is joined to a room's MLS group only if the client's user is a
participant in the room, and that all clients in the group agree on the state
of the room (including, for example, the room's participant list).</t>
      <section anchor="known-gaps">
        <name>Known Gaps</name>
        <t>In this version of the document, we have tried to capture enough concrete
functionality to enable basic application functionality, while defining enough
of a protocol framework to indicate how to add other necessary functionality.
The following functions are likely to be needed by the complete protocol, but
are not covered here:</t>
        <dl>
          <dt>Authorization policy:</dt>
          <dd>
            <t>In this document, we introduce a notional concept of roles for
participants, and permissions for roles. Concrete authorization policies
are defined in <xref target="I-D.ietf-mimi-room-policy"/>.</t>
          </dd>
          <dt>Knock and invite flows:</dt>
          <dd>
            <t>This document describes how user can be added, or how authorized users can
add themselves to a group based on the policy of the room. It does not include
flows where a user can "knock" to ask to enter a room, nor does it
include "invitations", where a user offers information to another user about
how to be added to a room.</t>
          </dd>
          <dt>Identifiers:</dt>
          <dd>
            <t>Certain entities in the MIMI system need to be identified in the protocol.  In
this document, we define a notional syntax for identifiers, but a more
concrete one should be defined.</t>
          </dd>
          <dt>Authentication</dt>
          <dd>
            <t>While MLS provides basic message authentication, users should also be able
to (cryptographically) tie the identity of other users to their respective
providers. Further authentication such as tying clients to their users (or the
user's other clients) may also be desirable.</t>
          </dd>
        </dl>
      </section>
    </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.ietf-mimi-arch"/>.  We also
make use of terms from the MLS protocol <xref target="RFC9420"/>.</t>
      <t>Throughout this document, the examples use the TLS Presentation Language
<xref target="RFC8446"/> and the semantics of HTTP <xref target="RFC7231"/> respectively as
placeholder a set of binary encoding mechanism and transport semantics.</t>
      <t>The protocol layering of the MIMI transport protocol is as follows:</t>
      <ol spacing="normal" type="1"><li>
          <t>An application layer that enables messaging functionality</t>
        </li>
        <li>
          <t>A security layer that provides end-to-end security guarantees:
          </t>
          <ul spacing="normal">
            <li>
              <t>Confidentiality for messages</t>
            </li>
            <li>
              <t>Authentication of actors making changes to rooms</t>
            </li>
            <li>
              <t>Agreement on room state across the clients involved in a room</t>
            </li>
          </ul>
        </li>
        <li>
          <t>A transport layer that provides secure delivery of protocol objects between
servers.</t>
        </li>
      </ol>
      <figure anchor="fig-layers">
        <name>MIMI protocol layering</name>
        <artset>
          <artwork type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="144" width="216" viewBox="0 0 216 144" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
              <path d="M 8,32 L 8,128" fill="none" stroke="black"/>
              <path d="M 72,64 L 72,96" fill="none" stroke="black"/>
              <path d="M 208,32 L 208,128" fill="none" stroke="black"/>
              <path d="M 8,32 L 208,32" fill="none" stroke="black"/>
              <path d="M 72,64 L 208,64" fill="none" stroke="black"/>
              <path d="M 8,96 L 208,96" fill="none" stroke="black"/>
              <path d="M 8,128 L 208,128" fill="none" stroke="black"/>
              <g class="text">
                <text x="112" y="52">Application</text>
                <text x="104" y="84">E2E</text>
                <text x="156" y="84">Security</text>
                <text x="112" y="116">Transport</text>
              </g>
            </svg>
          </artwork>
          <artwork type="ascii-art"><![CDATA[
+------------------------+
|       Application      |
|       +----------------+
|       |  E2E Security  |
+-------+----------------+
|        Transport       |
+------------------------+
]]></artwork>
        </artset>
      </figure>
      <t>MIMI uses MLS <xref target="RFC9420"/> for end-to-end security, using the MLS AppDataUpdate
proposal type <xref target="I-D.ietf-mls-extensions"/> to efficiently synchronize room state
across the clients involved in a room. The MIMI transport is based on HTTPS over
mutually-authenticated TLS.</t>
      <section anchor="mimi-uris">
        <name>MIMI URIs</name>
        <t>Inside the protocol, each provider is represented by a domain name in the
<tt>host</tt> production of the <tt>authority</tt> of a MIMI URI <xref target="RFC3986"/>. Specific
hosts or servers are represented by domain names, but not by MIMI URIs.</t>
        <t>The first path segment in a MIMI URI discriminates the type of identifier, as
shown in <xref target="mimi-uri-types"/>. A MIMI URI that identifies a provider has no path.</t>
        <table anchor="mimi-uri-types">
          <name>MIMI URI identifier types</name>
          <thead>
            <tr>
              <th align="left">Identifier type</th>
              <th align="left">First path segment</th>
              <th align="left">Example URI</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="left">Provider</td>
              <td align="left">(no path)</td>
              <td align="left">
                <tt>mimi://a.example</tt></td>
            </tr>
            <tr>
              <td align="left">User</td>
              <td align="left">
                <tt>u</tt></td>
              <td align="left">
                <tt>mimi://a.example/u/alice</tt></td>
            </tr>
            <tr>
              <td align="left">Client</td>
              <td align="left">
                <tt>d</tt></td>
              <td align="left">
                <tt>mimi://a.example/d/ClientA1</tt></td>
            </tr>
            <tr>
              <td align="left">Room</td>
              <td align="left">
                <tt>r</tt></td>
              <td align="left">
                <tt>mimi://a.example/r/clubhouse</tt></td>
            </tr>
            <tr>
              <td align="left">MLS group</td>
              <td align="left">
                <tt>g</tt></td>
              <td align="left">
                <tt>mimi://a.example/g/clubhouse</tt></td>
            </tr>
          </tbody>
        </table>
      </section>
    </section>
    <section anchor="example-protocol-flow">
      <name>Example protocol flow</name>
      <t>This section walks through a basic scenario that illustrates how a room works
in the MIMI protocol.  The scenario involves the following actors:</t>
      <ul spacing="normal">
        <li>
          <t>Service providers <tt>a.example</tt>, <tt>b.example</tt>, and <tt>c.example</tt> represented by
servers <tt>ServerA</tt>, <tt>ServerB</tt>, and <tt>ServerC</tt> respectively</t>
        </li>
        <li>
          <t>Users Alice (<tt>alice</tt>), Bob (<tt>bob</tt>) and Cathy (<tt>cathy</tt>) of the service
providers <tt>a.example</tt>, <tt>b.example</tt>, and <tt>c.example</tt> respectively.</t>
        </li>
        <li>
          <t>Clients <tt>ClientA1</tt>, <tt>ClientA2</tt>, <tt>ClientB1</tt>, etc. belonging to these users</t>
        </li>
        <li>
          <t>A room <tt>clubhouse</tt> hosted by hub provider <tt>a.example</tt> where the three users
interact.</t>
        </li>
      </ul>
      <t>The MIMI URIs in this example follow the conventions in <xref target="mimi-uris"/>.</t>
      <t>As noted in <xref target="I-D.ietf-mimi-arch"/>, the MIMI protocol only defines interactions
between service providers' servers.  Interactions between clients and servers
within a service provider domain are shown here for completeness, but
surrounded by <tt>[[ double brackets ]]</tt>.</t>
      <section anchor="alice-creates-a-room">
        <name>Alice Creates a Room</name>
        <t>The first step in the lifetime of a MIMI room is its creation on the hub server.
This operation is local to the service provider, and does not entail any MIMI
protocol operations.  However, it must establish the initial state of the room,
which is then the basis for protocol operations related to the room.</t>
        <t>For authorization purposes, MIMI uses permissions based on room-defined roles
<xref target="I-D.ietf-mimi-room-policy"/>.
For example, a room might have a role named "admin", which has <tt>canAddParticipant</tt>,
<tt>canRemoveParticipant</tt>, and <tt>canChangeUserRole</tt> permissions.</t>
        <t>Here, we assume that Alice uses ClientA1 to create a room with the following
base policy properties:</t>
        <ul spacing="normal">
          <li>
            <t>Room Identifier: <tt>mimi://a.example/r/clubhouse</tt></t>
          </li>
          <li>
            <t>Roles: <tt>admin = [canAddParticipant, canRemoveParticipant, canChangeUserRole]</tt></t>
          </li>
        </ul>
        <t>And the following participant list:</t>
        <ul spacing="normal">
          <li>
            <t>Participants: <tt>[[mimi://a.example/u/alice, "admin"]]</tt></t>
          </li>
        </ul>
        <t>ClientA1 also creates an MLS group with group ID <tt>mimi://a.example/g/clubhouse</tt> and
ensures via provider-local operations that Alice's other clients are members of
this MLS group.</t>
      </section>
      <section anchor="alice-adds-bob-to-the-room">
        <name>Alice adds Bob to the Room</name>
        <t>Adding Bob to the room entails operations at two levels.  First, Bob's user
identity must be added to the room's participant list.  Second, Bob's clients
must be added to the room's MLS group.</t>
        <t>The process of adding Bob to the room thus begins by Alice fetching key material
for Bob's clients.  Alice then updates the room by sending an MLS Commit over
the following proposals:</t>
        <ul spacing="normal">
          <li>
            <t>An AppDataUpdate proposal for the <tt>participant_list</tt> component adding Bob
to the participant list</t>
          </li>
          <li>
            <t>Add proposals for Bob's clients</t>
          </li>
        </ul>
        <t>The MIMI protocol interactions are between Alice's server ServerA and Bob's
server ServerB.  ServerB stores KeyPackages on behalf of Bob's devices.  ServerA
performs the key material fetch on Alice's behalf, and delivers the resulting
KeyPackages to Alice's clients.  Both ServerA and ServerB remember the sources
of the KeyPackages they handle, so that they can route a Welcome message for
those KeyPackages to the proper recipients -- ServerA to ServerB, and ServerB to
Bob's clients.</t>
        <ul empty="true">
          <li>
            <t><strong>NOTE:</strong> In the protocol, it is necessary to have consent (see <xref target="consent"/>)
and access control on these operations.  We have elided that step here in
the interest of simplicity.</t>
          </li>
        </ul>
        <figure anchor="fig-ab-kp-fetch">
          <name>Alice Fetches KeyPackages for Bob's Clients</name>
          <artset>
            <artwork type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="368" width="544" viewBox="0 0 544 368" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
                <path d="M 24,48 L 24,208" fill="none" stroke="black"/>
                <path d="M 152,48 L 152,208" fill="none" stroke="black"/>
                <path d="M 280,48 L 280,208" fill="none" stroke="black"/>
                <path d="M 408,48 L 408,208" fill="none" stroke="black"/>
                <path d="M 288,80 Q 290,76.8 292,80 Q 294,83.2 296,80 Q 298,76.8 300,80 Q 302,83.2 304,80 Q 306,76.8 308,80 Q 310,83.2 312,80 Q 314,76.8 316,80 Q 318,83.2 320,80 Q 322,76.8 324,80 Q 326,83.2 328,80 Q 330,76.8 332,80 Q 334,83.2 336,80 Q 338,76.8 340,80 Q 342,83.2 344,80 Q 346,76.8 348,80 Q 350,83.2 352,80 Q 354,76.8 356,80 Q 358,83.2 360,80 Q 362,76.8 364,80 Q 366,83.2 368,80 Q 370,76.8 372,80 Q 374,83.2 376,80 Q 378,76.8 380,80 Q 382,83.2 384,80 Q 386,76.8 388,80 Q 390,83.2 392,80 Q 394,76.8 396,80 Q 398,83.2 400,80 Q 402,76.8 404,80 Q 406,83.2 408,80 " fill="none" stroke="black"/>
                <path d="M 288,96 Q 290,92.8 292,96 Q 294,99.2 296,96 Q 298,92.8 300,96 Q 302,99.2 304,96 Q 306,92.8 308,96 Q 310,99.2 312,96 Q 314,92.8 316,96 Q 318,99.2 320,96 Q 322,92.8 324,96 Q 326,99.2 328,96 Q 330,92.8 332,96 Q 334,99.2 336,96 Q 338,92.8 340,96 Q 342,99.2 344,96 Q 346,92.8 348,96 Q 350,99.2 352,96 Q 354,92.8 356,96 Q 358,99.2 360,96 Q 362,92.8 364,96 Q 366,99.2 368,96 Q 370,92.8 372,96 Q 374,99.2 376,96 Q 378,92.8 380,96 Q 382,99.2 384,96 Q 386,92.8 388,96 Q 390,99.2 392,96 Q 394,92.8 396,96 Q 398,99.2 400,96 Q 402,92.8 404,96 Q 406,99.2 408,96 " fill="none" stroke="black"/>
                <path d="M 24,128 Q 26,124.8 28,128 Q 30,131.2 32,128 Q 34,124.8 36,128 Q 38,131.2 40,128 Q 42,124.8 44,128 Q 46,131.2 48,128 Q 50,124.8 52,128 Q 54,131.2 56,128 Q 58,124.8 60,128 Q 62,131.2 64,128 Q 66,124.8 68,128 Q 70,131.2 72,128 Q 74,124.8 76,128 Q 78,131.2 80,128 Q 82,124.8 84,128 Q 86,131.2 88,128 Q 90,124.8 92,128 Q 94,131.2 96,128 Q 98,124.8 100,128 Q 102,131.2 104,128 Q 106,124.8 108,128 Q 110,131.2 112,128 Q 114,124.8 116,128 Q 118,131.2 120,128 Q 122,124.8 124,128 Q 126,131.2 128,128 Q 130,124.8 132,128 Q 134,131.2 136,128 Q 138,124.8 140,128 Q 142,131.2 144,128 " fill="none" stroke="black"/>
                <path d="M 152,144 L 272,144" fill="none" stroke="black"/>
                <path d="M 160,176 L 280,176" fill="none" stroke="black"/>
                <path d="M 32,192 Q 34,188.8 36,192 Q 38,195.2 40,192 Q 42,188.8 44,192 Q 46,195.2 48,192 Q 50,188.8 52,192 Q 54,195.2 56,192 Q 58,188.8 60,192 Q 62,195.2 64,192 Q 66,188.8 68,192 Q 70,195.2 72,192 Q 74,188.8 76,192 Q 78,195.2 80,192 Q 82,188.8 84,192 Q 86,195.2 88,192 Q 90,188.8 92,192 Q 94,195.2 96,192 Q 98,188.8 100,192 Q 102,195.2 104,192 Q 106,188.8 108,192 Q 110,195.2 112,192 Q 114,188.8 116,192 Q 118,195.2 120,192 Q 122,188.8 124,192 Q 126,195.2 128,192 Q 130,188.8 132,192 Q 134,195.2 136,192 Q 138,188.8 140,192 Q 142,195.2 144,192 Q 146,188.8 148,192 Q 150,195.2 152,192 " fill="none" stroke="black"/>
                <polygon class="arrowhead" points="296,96 284,90.4 284,101.6" fill="black" transform="rotate(180,288,96)"/>
                <polygon class="arrowhead" points="296,80 284,74.4 284,85.6" fill="black" transform="rotate(180,288,80)"/>
                <polygon class="arrowhead" points="280,144 268,138.4 268,149.6" fill="black" transform="rotate(0,272,144)"/>
                <polygon class="arrowhead" points="168,176 156,170.4 156,181.6" fill="black" transform="rotate(180,160,176)"/>
                <polygon class="arrowhead" points="152,128 140,122.4 140,133.6" fill="black" transform="rotate(0,144,128)"/>
                <polygon class="arrowhead" points="40,192 28,186.4 28,197.6" fill="black" transform="rotate(180,32,192)"/>
                <g class="text">
                  <text x="36" y="36">ClientA1</text>
                  <text x="152" y="36">ServerA</text>
                  <text x="280" y="36">ServerB</text>
                  <text x="412" y="36">ClientB*</text>
                  <text x="344" y="68">Store</text>
                  <text x="384" y="68">KPs</text>
                  <text x="64" y="116">Request</text>
                  <text x="112" y="116">KPs</text>
                  <text x="212" y="132">/keyMaterial</text>
                  <text x="232" y="164">200</text>
                  <text x="260" y="164">OK</text>
                  <text x="128" y="180">KPs</text>
                  <text x="76" y="244">ClientB*-&gt;ServerB:</text>
                  <text x="164" y="244">[[</text>
                  <text x="200" y="244">Store</text>
                  <text x="272" y="244">KeyPackages</text>
                  <text x="332" y="244">]]</text>
                  <text x="76" y="260">ClientA1-&gt;ServerA:</text>
                  <text x="164" y="260">[[</text>
                  <text x="208" y="260">request</text>
                  <text x="256" y="260">KPs</text>
                  <text x="288" y="260">for</text>
                  <text x="320" y="260">Bob</text>
                  <text x="348" y="260">]]</text>
                  <text x="72" y="276">ServerA-&gt;ServerB:</text>
                  <text x="164" y="276">POST</text>
                  <text x="288" y="276">/keyMaterial/{targetUser}</text>
                  <text x="468" y="276">KeyMaterialRequest</text>
                  <text x="36" y="292">ServerB:</text>
                  <text x="100" y="292">Verify</text>
                  <text x="148" y="292">that</text>
                  <text x="192" y="292">Alice</text>
                  <text x="228" y="292">is</text>
                  <text x="284" y="292">authorized</text>
                  <text x="340" y="292">to</text>
                  <text x="376" y="292">fetch</text>
                  <text x="448" y="292">KeyPackages</text>
                  <text x="36" y="308">ServerB:</text>
                  <text x="92" y="308">Mark</text>
                  <text x="148" y="308">returned</text>
                  <text x="200" y="308">KPs</text>
                  <text x="228" y="308">as</text>
                  <text x="276" y="308">reserved</text>
                  <text x="328" y="308">for</text>
                  <text x="376" y="308">Alice's</text>
                  <text x="424" y="308">use</text>
                  <text x="72" y="324">ServerB-&gt;ServerA:</text>
                  <text x="160" y="324">200</text>
                  <text x="188" y="324">OK</text>
                  <text x="280" y="324">KeyMaterialResponse</text>
                  <text x="36" y="340">ServerA:</text>
                  <text x="108" y="340">Remember</text>
                  <text x="164" y="340">that</text>
                  <text x="208" y="340">these</text>
                  <text x="248" y="340">KPs</text>
                  <text x="276" y="340">go</text>
                  <text x="300" y="340">to</text>
                  <text x="352" y="340">b.example</text>
                  <text x="76" y="356">ServerA-&gt;ClientA1:</text>
                  <text x="164" y="356">[[</text>
                  <text x="192" y="356">KPs</text>
                  <text x="220" y="356">]]</text>
                </g>
              </svg>
            </artwork>
            <artwork type="ascii-art"><![CDATA[
ClientA1       ServerA         ServerB         ClientB*
  |               |               |               |
  |               |               |     Store KPs |
  |               |               |<~~~~~~~~~~~~~~+
  |               |               |<~~~~~~~~~~~~~~+
  | Request KPs   |               |               |
  +~~~~~~~~~~~~~~>| /keyMaterial  |               |
  |               +-------------->|               |
  |               |        200 OK |               |
  |           KPs |<--------------+               |
  |<~~~~~~~~~~~~~~+               |               |
  |               |               |               |

ClientB*->ServerB: [[ Store KeyPackages ]]
ClientA1->ServerA: [[ request KPs for Bob ]]
ServerA->ServerB: POST /keyMaterial/{targetUser} KeyMaterialRequest
ServerB: Verify that Alice is authorized to fetch KeyPackages
ServerB: Mark returned KPs as reserved for Alice's use
ServerB->ServerA: 200 OK KeyMaterialResponse
ServerA: Remember that these KPs go to b.example
ServerA->ClientA1: [[ KPs ]]
]]></artwork>
          </artset>
        </figure>
        <figure anchor="fig-ab-add">
          <name>Alice Adds Bob to the Room and Bob's Clients to the MLS Group</name>
          <artset>
            <artwork type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="336" width="672" viewBox="0 0 672 336" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
                <path d="M 24,48 L 24,176" fill="none" stroke="black"/>
                <path d="M 152,48 L 152,176" fill="none" stroke="black"/>
                <path d="M 280,48 L 280,176" fill="none" stroke="black"/>
                <path d="M 408,48 L 408,176" fill="none" stroke="black"/>
                <path d="M 24,80 Q 26,76.8 28,80 Q 30,83.2 32,80 Q 34,76.8 36,80 Q 38,83.2 40,80 Q 42,76.8 44,80 Q 46,83.2 48,80 Q 50,76.8 52,80 Q 54,83.2 56,80 Q 58,76.8 60,80 Q 62,83.2 64,80 Q 66,76.8 68,80 Q 70,83.2 72,80 Q 74,76.8 76,80 Q 78,83.2 80,80 Q 82,76.8 84,80 Q 86,83.2 88,80 Q 90,76.8 92,80 Q 94,83.2 96,80 Q 98,76.8 100,80 Q 102,83.2 104,80 Q 106,76.8 108,80 Q 110,83.2 112,80 Q 114,76.8 116,80 Q 118,83.2 120,80 Q 122,76.8 124,80 Q 126,83.2 128,80 Q 130,76.8 132,80 Q 134,83.2 136,80 Q 138,76.8 140,80 Q 142,83.2 144,80 " fill="none" stroke="black"/>
                <path d="M 32,112 Q 34,108.8 36,112 Q 38,115.2 40,112 Q 42,108.8 44,112 Q 46,115.2 48,112 Q 50,108.8 52,112 Q 54,115.2 56,112 Q 58,108.8 60,112 Q 62,115.2 64,112 Q 66,108.8 68,112 Q 70,115.2 72,112 Q 74,108.8 76,112 Q 78,115.2 80,112 Q 82,108.8 84,112 Q 86,115.2 88,112 Q 90,108.8 92,112 Q 94,115.2 96,112 Q 98,108.8 100,112 Q 102,115.2 104,112 Q 106,108.8 108,112 Q 110,115.2 112,112 Q 114,108.8 116,112 Q 118,115.2 120,112 Q 122,108.8 124,112 Q 126,115.2 128,112 Q 130,108.8 132,112 Q 134,115.2 136,112 Q 138,108.8 140,112 Q 142,115.2 144,112 Q 146,108.8 148,112 Q 150,115.2 152,112 " fill="none" stroke="black"/>
                <path d="M 152,112 L 272,112" fill="none" stroke="black"/>
                <path d="M 160,144 L 280,144" fill="none" stroke="black"/>
                <path d="M 280,144 Q 282,140.8 284,144 Q 286,147.2 288,144 Q 290,140.8 292,144 Q 294,147.2 296,144 Q 298,140.8 300,144 Q 302,147.2 304,144 Q 306,140.8 308,144 Q 310,147.2 312,144 Q 314,140.8 316,144 Q 318,147.2 320,144 Q 322,140.8 324,144 Q 326,147.2 328,144 Q 330,140.8 332,144 Q 334,147.2 336,144 Q 338,140.8 340,144 Q 342,147.2 344,144 Q 346,140.8 348,144 Q 350,147.2 352,144 Q 354,140.8 356,144 Q 358,147.2 360,144 Q 362,140.8 364,144 Q 366,147.2 368,144 Q 370,140.8 372,144 Q 374,147.2 376,144 Q 378,140.8 380,144 Q 382,147.2 384,144 Q 386,140.8 388,144 Q 390,147.2 392,144 Q 394,140.8 396,144 Q 398,147.2 400,144 " fill="none" stroke="black"/>
                <path d="M 280,160 Q 282,156.8 284,160 Q 286,163.2 288,160 Q 290,156.8 292,160 Q 294,163.2 296,160 Q 298,156.8 300,160 Q 302,163.2 304,160 Q 306,156.8 308,160 Q 310,163.2 312,160 Q 314,156.8 316,160 Q 318,163.2 320,160 Q 322,156.8 324,160 Q 326,163.2 328,160 Q 330,156.8 332,160 Q 334,163.2 336,160 Q 338,156.8 340,160 Q 342,163.2 344,160 Q 346,156.8 348,160 Q 350,163.2 352,160 Q 354,156.8 356,160 Q 358,163.2 360,160 Q 362,156.8 364,160 Q 366,163.2 368,160 Q 370,156.8 372,160 Q 374,163.2 376,160 Q 378,156.8 380,160 Q 382,163.2 384,160 Q 386,156.8 388,160 Q 390,163.2 392,160 Q 394,156.8 396,160 Q 398,163.2 400,160 " fill="none" stroke="black"/>
                <polygon class="arrowhead" points="408,160 396,154.4 396,165.6" fill="black" transform="rotate(0,400,160)"/>
                <polygon class="arrowhead" points="408,144 396,138.4 396,149.6" fill="black" transform="rotate(0,400,144)"/>
                <polygon class="arrowhead" points="280,112 268,106.4 268,117.6" fill="black" transform="rotate(0,272,112)"/>
                <polygon class="arrowhead" points="168,144 156,138.4 156,149.6" fill="black" transform="rotate(180,160,144)"/>
                <polygon class="arrowhead" points="152,80 140,74.4 140,85.6" fill="black" transform="rotate(0,144,80)"/>
                <polygon class="arrowhead" points="40,112 28,106.4 28,117.6" fill="black" transform="rotate(180,32,112)"/>
                <g class="text">
                  <text x="36" y="36">ClientA1</text>
                  <text x="152" y="36">ServerA</text>
                  <text x="280" y="36">ServerB</text>
                  <text x="412" y="36">ClientB*</text>
                  <text x="64" y="68">Commit,</text>
                  <text x="116" y="68">etc.</text>
                  <text x="108" y="100">Accepted</text>
                  <text x="192" y="100">/notify</text>
                  <text x="232" y="132">200</text>
                  <text x="260" y="132">OK</text>
                  <text x="324" y="132">Welcome,</text>
                  <text x="380" y="132">Tree</text>
                  <text x="40" y="228">ClientA1:</text>
                  <text x="112" y="228">Prepare</text>
                  <text x="172" y="228">Commit</text>
                  <text x="220" y="228">over</text>
                  <text x="324" y="228">AppDataUpdate(+Bob),</text>
                  <text x="428" y="228">Add*</text>
                  <text x="76" y="244">ClientA1-&gt;ServerA:</text>
                  <text x="164" y="244">[[</text>
                  <text x="208" y="244">Commit,</text>
                  <text x="276" y="244">Welcome,</text>
                  <text x="360" y="244">GroupInfo?,</text>
                  <text x="460" y="244">RatchetTree?</text>
                  <text x="524" y="244">]]</text>
                  <text x="36" y="260">ServerA:</text>
                  <text x="100" y="260">Verify</text>
                  <text x="148" y="260">that</text>
                  <text x="228" y="260">AppDataUpdate,</text>
                  <text x="308" y="260">Adds</text>
                  <text x="344" y="260">are</text>
                  <text x="392" y="260">allowed</text>
                  <text x="436" y="260">by</text>
                  <text x="476" y="260">policy</text>
                  <text x="36" y="276">ServerA:</text>
                  <text x="116" y="276">Identifies</text>
                  <text x="192" y="276">Welcome</text>
                  <text x="256" y="276">domains</text>
                  <text x="312" y="276">based</text>
                  <text x="348" y="276">on</text>
                  <text x="372" y="276">KP</text>
                  <text x="404" y="276">hash</text>
                  <text x="436" y="276">in</text>
                  <text x="480" y="276">Welcome</text>
                  <text x="72" y="292">ServerA-&gt;ServerB:</text>
                  <text x="164" y="292">POST</text>
                  <text x="304" y="292">/notify/a.example/r/clubhouse</text>
                  <text x="452" y="292">Intro{</text>
                  <text x="516" y="292">Welcome,</text>
                  <text x="604" y="292">RatchetTree?</text>
                  <text x="664" y="292">}</text>
                  <text x="36" y="308">ServerB:</text>
                  <text x="116" y="308">Recognizes</text>
                  <text x="180" y="308">that</text>
                  <text x="232" y="308">Welcome</text>
                  <text x="276" y="308">is</text>
                  <text x="316" y="308">adding</text>
                  <text x="360" y="308">Bob</text>
                  <text x="388" y="308">to</text>
                  <text x="420" y="308">room</text>
                  <text x="480" y="308">clubhouse</text>
                  <text x="76" y="324">ServerB-&gt;ClientB*:</text>
                  <text x="164" y="324">[[</text>
                  <text x="212" y="324">Welcome,</text>
                  <text x="300" y="324">RatchetTree?</text>
                  <text x="364" y="324">]]</text>
                </g>
              </svg>
            </artwork>
            <artwork type="ascii-art"><![CDATA[
ClientA1       ServerA         ServerB         ClientB*
  |               |               |               |
  | Commit, etc.  |               |               |
  +~~~~~~~~~~~~~~>|               |               |
  |      Accepted | /notify       |               |
  |<~~~~~~~~~~~~~~+-------------->|               |
  |               |        200 OK | Welcome, Tree |
  |               |<--------------+~~~~~~~~~~~~~~>|
  |               |               +~~~~~~~~~~~~~~>|
  |               |               |               |


ClientA1: Prepare Commit over AppDataUpdate(+Bob), Add*
ClientA1->ServerA: [[ Commit, Welcome, GroupInfo?, RatchetTree? ]]
ServerA: Verify that AppDataUpdate, Adds are allowed by policy
ServerA: Identifies Welcome domains based on KP hash in Welcome
ServerA->ServerB: POST /notify/a.example/r/clubhouse Intro{ Welcome, RatchetTree? }
ServerB: Recognizes that Welcome is adding Bob to room clubhouse
ServerB->ClientB*: [[ Welcome, RatchetTree? ]]
]]></artwork>
          </artset>
        </figure>
      </section>
      <section anchor="bob-adds-cathy-to-the-room">
        <name>Bob adds Cathy to the Room</name>
        <t>The process of adding Bob was a bit abbreviated because Alice is a user of the
hub service provider.  When Bob adds Cathy, we see the full process, involving
the same two steps (KeyPackage fetch followed by Add), but this time indirected via the
hub server ServerA.  Also, now that there are users on ServerB involved in the
room, the hub ServerA will have to distribute the Commit adding Cathy and
Cathy's clients to ServerB as well as forwarding the Welcome to ServerC.</t>
        <figure anchor="fig-bc-kp-fetch">
          <name>Bob Fetches KeyPackages for Cathy's Clients</name>
          <artset>
            <artwork type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="400" width="576" viewBox="0 0 576 400" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
                <path d="M 24,48 L 24,208" fill="none" stroke="black"/>
                <path d="M 152,48 L 152,208" fill="none" stroke="black"/>
                <path d="M 280,48 L 280,208" fill="none" stroke="black"/>
                <path d="M 408,48 L 408,208" fill="none" stroke="black"/>
                <path d="M 536,48 L 536,208" fill="none" stroke="black"/>
                <path d="M 416,80 Q 418,76.8 420,80 Q 422,83.2 424,80 Q 426,76.8 428,80 Q 430,83.2 432,80 Q 434,76.8 436,80 Q 438,83.2 440,80 Q 442,76.8 444,80 Q 446,83.2 448,80 Q 450,76.8 452,80 Q 454,83.2 456,80 Q 458,76.8 460,80 Q 462,83.2 464,80 Q 466,76.8 468,80 Q 470,83.2 472,80 Q 474,76.8 476,80 Q 478,83.2 480,80 Q 482,76.8 484,80 Q 486,83.2 488,80 Q 490,76.8 492,80 Q 494,83.2 496,80 Q 498,76.8 500,80 Q 502,83.2 504,80 Q 506,76.8 508,80 Q 510,83.2 512,80 Q 514,76.8 516,80 Q 518,83.2 520,80 Q 522,76.8 524,80 Q 526,83.2 528,80 Q 530,76.8 532,80 Q 534,83.2 536,80 " fill="none" stroke="black"/>
                <path d="M 416,96 Q 418,92.8 420,96 Q 422,99.2 424,96 Q 426,92.8 428,96 Q 430,99.2 432,96 Q 434,92.8 436,96 Q 438,99.2 440,96 Q 442,92.8 444,96 Q 446,99.2 448,96 Q 450,92.8 452,96 Q 454,99.2 456,96 Q 458,92.8 460,96 Q 462,99.2 464,96 Q 466,92.8 468,96 Q 470,99.2 472,96 Q 474,92.8 476,96 Q 478,99.2 480,96 Q 482,92.8 484,96 Q 486,99.2 488,96 Q 490,92.8 492,96 Q 494,99.2 496,96 Q 498,92.8 500,96 Q 502,99.2 504,96 Q 506,92.8 508,96 Q 510,99.2 512,96 Q 514,92.8 516,96 Q 518,99.2 520,96 Q 522,92.8 524,96 Q 526,99.2 528,96 Q 530,92.8 532,96 Q 534,99.2 536,96 " fill="none" stroke="black"/>
                <path d="M 24,128 Q 26,124.8 28,128 Q 30,131.2 32,128 Q 34,124.8 36,128 Q 38,131.2 40,128 Q 42,124.8 44,128 Q 46,131.2 48,128 Q 50,124.8 52,128 Q 54,131.2 56,128 Q 58,124.8 60,128 Q 62,131.2 64,128 Q 66,124.8 68,128 Q 70,131.2 72,128 Q 74,124.8 76,128 Q 78,131.2 80,128 Q 82,124.8 84,128 Q 86,131.2 88,128 Q 90,124.8 92,128 Q 94,131.2 96,128 Q 98,124.8 100,128 Q 102,131.2 104,128 Q 106,124.8 108,128 Q 110,131.2 112,128 Q 114,124.8 116,128 Q 118,131.2 120,128 Q 122,124.8 124,128 Q 126,131.2 128,128 Q 130,124.8 132,128 Q 134,131.2 136,128 Q 138,124.8 140,128 Q 142,131.2 144,128 " fill="none" stroke="black"/>
                <path d="M 152,144 L 400,144" fill="none" stroke="black"/>
                <path d="M 160,176 L 408,176" fill="none" stroke="black"/>
                <path d="M 32,192 Q 34,188.8 36,192 Q 38,195.2 40,192 Q 42,188.8 44,192 Q 46,195.2 48,192 Q 50,188.8 52,192 Q 54,195.2 56,192 Q 58,188.8 60,192 Q 62,195.2 64,192 Q 66,188.8 68,192 Q 70,195.2 72,192 Q 74,188.8 76,192 Q 78,195.2 80,192 Q 82,188.8 84,192 Q 86,195.2 88,192 Q 90,188.8 92,192 Q 94,195.2 96,192 Q 98,188.8 100,192 Q 102,195.2 104,192 Q 106,188.8 108,192 Q 110,195.2 112,192 Q 114,188.8 116,192 Q 118,195.2 120,192 Q 122,188.8 124,192 Q 126,195.2 128,192 Q 130,188.8 132,192 Q 134,195.2 136,192 Q 138,188.8 140,192 Q 142,195.2 144,192 Q 146,188.8 148,192 Q 150,195.2 152,192 " fill="none" stroke="black"/>
                <polygon class="arrowhead" points="424,96 412,90.4 412,101.6" fill="black" transform="rotate(180,416,96)"/>
                <polygon class="arrowhead" points="424,80 412,74.4 412,85.6" fill="black" transform="rotate(180,416,80)"/>
                <polygon class="arrowhead" points="408,144 396,138.4 396,149.6" fill="black" transform="rotate(0,400,144)"/>
                <polygon class="arrowhead" points="296,176 284,170.4 284,181.6" fill="black" transform="rotate(180,288,176)"/>
                <polygon class="arrowhead" points="280,144 268,138.4 268,149.6" fill="black" transform="rotate(0,272,144)"/>
                <polygon class="arrowhead" points="168,176 156,170.4 156,181.6" fill="black" transform="rotate(180,160,176)"/>
                <polygon class="arrowhead" points="152,128 140,122.4 140,133.6" fill="black" transform="rotate(0,144,128)"/>
                <polygon class="arrowhead" points="40,192 28,186.4 28,197.6" fill="black" transform="rotate(180,32,192)"/>
                <g class="text">
                  <text x="36" y="36">ClientB1</text>
                  <text x="152" y="36">ServerB</text>
                  <text x="280" y="36">ServerA</text>
                  <text x="408" y="36">ServerC</text>
                  <text x="540" y="36">ClientC*</text>
                  <text x="472" y="68">Store</text>
                  <text x="512" y="68">KPs</text>
                  <text x="64" y="116">Request</text>
                  <text x="112" y="116">KPs</text>
                  <text x="212" y="132">/keyMaterial</text>
                  <text x="340" y="132">/keyMaterial</text>
                  <text x="232" y="164">200</text>
                  <text x="260" y="164">OK</text>
                  <text x="360" y="164">200</text>
                  <text x="388" y="164">OK</text>
                  <text x="128" y="180">KPs</text>
                  <text x="76" y="244">ClientC*-&gt;ServerC:</text>
                  <text x="164" y="244">[[</text>
                  <text x="200" y="244">Store</text>
                  <text x="272" y="244">KeyPackages</text>
                  <text x="332" y="244">]]</text>
                  <text x="76" y="260">ClientB1-&gt;ServerB:</text>
                  <text x="164" y="260">[[</text>
                  <text x="208" y="260">request</text>
                  <text x="256" y="260">KPs</text>
                  <text x="288" y="260">for</text>
                  <text x="320" y="260">Bob</text>
                  <text x="348" y="260">]]</text>
                  <text x="72" y="276">ServerB-&gt;ServerA:</text>
                  <text x="164" y="276">POST</text>
                  <text x="288" y="276">/keyMaterial/{targetUser}</text>
                  <text x="468" y="276">KeyMaterialRequest</text>
                  <text x="72" y="292">ServerA-&gt;ServerC:</text>
                  <text x="164" y="292">POST</text>
                  <text x="288" y="292">/keyMaterial/{targetUser}</text>
                  <text x="468" y="292">KeyMaterialRequest</text>
                  <text x="36" y="308">ServerB:</text>
                  <text x="100" y="308">Verify</text>
                  <text x="148" y="308">that</text>
                  <text x="184" y="308">Bob</text>
                  <text x="212" y="308">is</text>
                  <text x="268" y="308">authorized</text>
                  <text x="324" y="308">to</text>
                  <text x="360" y="308">fetch</text>
                  <text x="432" y="308">KeyPackages</text>
                  <text x="36" y="324">ServerB:</text>
                  <text x="92" y="324">Mark</text>
                  <text x="148" y="324">returned</text>
                  <text x="200" y="324">KPs</text>
                  <text x="228" y="324">as</text>
                  <text x="276" y="324">reserved</text>
                  <text x="328" y="324">for</text>
                  <text x="368" y="324">Bob's</text>
                  <text x="408" y="324">use</text>
                  <text x="72" y="340">ServerC-&gt;ServerA:</text>
                  <text x="160" y="340">200</text>
                  <text x="188" y="340">OK</text>
                  <text x="280" y="340">KeyMaterialResponse</text>
                  <text x="36" y="356">ServerA:</text>
                  <text x="108" y="356">Remember</text>
                  <text x="164" y="356">that</text>
                  <text x="208" y="356">these</text>
                  <text x="248" y="356">KPs</text>
                  <text x="276" y="356">go</text>
                  <text x="300" y="356">to</text>
                  <text x="352" y="356">b.example</text>
                  <text x="72" y="372">ServerA-&gt;ServerB:</text>
                  <text x="160" y="372">200</text>
                  <text x="188" y="372">OK</text>
                  <text x="280" y="372">KeyMaterialResponse</text>
                  <text x="76" y="388">ServerB-&gt;ClientB1:</text>
                  <text x="164" y="388">[[</text>
                  <text x="192" y="388">KPs</text>
                  <text x="220" y="388">]]</text>
                </g>
              </svg>
            </artwork>
            <artwork type="ascii-art"><![CDATA[
ClientB1       ServerB         ServerA         ServerC         ClientC*
  |               |               |               |               |
  |               |               |               |     Store KPs |
  |               |               |               |<~~~~~~~~~~~~~~+
  |               |               |               |<~~~~~~~~~~~~~~+
  | Request KPs   |               |               |               |
  +~~~~~~~~~~~~~~>| /keyMaterial  | /keyMaterial  |               |
  |               +-------------->+-------------->|               |
  |               |        200 OK |        200 OK |               |
  |           KPs |<--------------+<--------------+               |
  |<~~~~~~~~~~~~~~+               |               |               |
  |               |               |               |               |

ClientC*->ServerC: [[ Store KeyPackages ]]
ClientB1->ServerB: [[ request KPs for Bob ]]
ServerB->ServerA: POST /keyMaterial/{targetUser} KeyMaterialRequest
ServerA->ServerC: POST /keyMaterial/{targetUser} KeyMaterialRequest
ServerB: Verify that Bob is authorized to fetch KeyPackages
ServerB: Mark returned KPs as reserved for Bob's use
ServerC->ServerA: 200 OK KeyMaterialResponse
ServerA: Remember that these KPs go to b.example
ServerA->ServerB: 200 OK KeyMaterialResponse
ServerB->ClientB1: [[ KPs ]]
]]></artwork>
          </artset>
        </figure>
        <figure anchor="fig-bc-add">
          <name>Bob Adds Cathy to the Room and Cathy's Clients to the MLS Group</name>
          <artset>
            <artwork type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="496" width="576" viewBox="0 0 576 496" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
                <path d="M 8,64 L 8,272" fill="none" stroke="black"/>
                <path d="M 120,64 L 120,272" fill="none" stroke="black"/>
                <path d="M 216,64 L 216,240" fill="none" stroke="black"/>
                <path d="M 312,64 L 312,208" fill="none" stroke="black"/>
                <path d="M 408,64 L 408,208" fill="none" stroke="black"/>
                <path d="M 488,64 L 488,208" fill="none" stroke="black"/>
                <path d="M 488,240 L 488,272" fill="none" stroke="black"/>
                <path d="M 568,64 L 568,272" fill="none" stroke="black"/>
                <path d="M 8,96 Q 10,92.8 12,96 Q 14,99.2 16,96 Q 18,92.8 20,96 Q 22,99.2 24,96 Q 26,92.8 28,96 Q 30,99.2 32,96 Q 34,92.8 36,96 Q 38,99.2 40,96 Q 42,92.8 44,96 Q 46,99.2 48,96 Q 50,92.8 52,96 Q 54,99.2 56,96 Q 58,92.8 60,96 Q 62,99.2 64,96 Q 66,92.8 68,96 Q 70,99.2 72,96 Q 74,92.8 76,96 Q 78,99.2 80,96 Q 82,92.8 84,96 Q 86,99.2 88,96 Q 90,92.8 92,96 Q 94,99.2 96,96 Q 98,92.8 100,96 Q 102,99.2 104,96 Q 106,92.8 108,96 Q 110,99.2 112,96 " fill="none" stroke="black"/>
                <path d="M 120,112 L 208,112" fill="none" stroke="black"/>
                <path d="M 128,144 L 216,144" fill="none" stroke="black"/>
                <path d="M 16,176 Q 18,172.8 20,176 Q 22,179.2 24,176 Q 26,172.8 28,176 Q 30,179.2 32,176 Q 34,172.8 36,176 Q 38,179.2 40,176 Q 42,172.8 44,176 Q 46,179.2 48,176 Q 50,172.8 52,176 Q 54,179.2 56,176 Q 58,172.8 60,176 Q 62,179.2 64,176 Q 66,172.8 68,176 Q 70,179.2 72,176 Q 74,172.8 76,176 Q 78,179.2 80,176 Q 82,172.8 84,176 Q 86,179.2 88,176 Q 90,172.8 92,176 Q 94,179.2 96,176 Q 98,172.8 100,176 Q 102,179.2 104,176 Q 106,172.8 108,176 Q 110,179.2 112,176 Q 114,172.8 116,176 Q 118,179.2 120,176 " fill="none" stroke="black"/>
                <path d="M 216,176 L 304,176" fill="none" stroke="black"/>
                <path d="M 312,192 Q 314,188.8 316,192 Q 318,195.2 320,192 Q 322,188.8 324,192 Q 326,195.2 328,192 Q 330,188.8 332,192 Q 334,195.2 336,192 Q 338,188.8 340,192 Q 342,195.2 344,192 Q 346,188.8 348,192 Q 350,195.2 352,192 Q 354,188.8 356,192 Q 358,195.2 360,192 Q 362,188.8 364,192 Q 366,195.2 368,192 Q 370,188.8 372,192 Q 374,195.2 376,192 Q 378,188.8 380,192 Q 382,195.2 384,192 Q 386,188.8 388,192 Q 390,195.2 392,192 Q 394,188.8 396,192 Q 398,195.2 400,192 " fill="none" stroke="black"/>
                <path d="M 312,208 Q 314,204.8 316,208 Q 318,211.2 320,208 Q 322,204.8 324,208 Q 326,211.2 328,208 Q 330,204.8 332,208 Q 334,211.2 336,208 Q 338,204.8 340,208 Q 342,211.2 344,208 Q 346,204.8 348,208 Q 350,211.2 352,208 Q 354,204.8 356,208 Q 358,211.2 360,208 Q 362,204.8 364,208 Q 366,211.2 368,208 Q 370,204.8 372,208 Q 374,211.2 376,208 Q 378,204.8 380,208 Q 382,211.2 384,208 Q 386,204.8 388,208 Q 390,211.2 392,208 Q 394,204.8 396,208 Q 398,211.2 400,208 " fill="none" stroke="black"/>
                <path d="M 128,224 L 216,224" fill="none" stroke="black"/>
                <path d="M 216,224 Q 218,220.8 220,224 Q 222,227.2 224,224 Q 226,220.8 228,224 Q 230,227.2 232,224 Q 234,220.8 236,224 Q 238,227.2 240,224 Q 242,220.8 244,224 Q 246,227.2 248,224 Q 250,220.8 252,224 Q 254,227.2 256,224 Q 258,220.8 260,224 Q 262,227.2 264,224 Q 266,220.8 268,224 Q 270,227.2 272,224 Q 274,220.8 276,224 Q 278,227.2 280,224 Q 282,220.8 284,224 Q 286,227.2 288,224 Q 290,220.8 292,224 Q 294,227.2 296,224 Q 298,220.8 300,224 Q 302,227.2 304,224 Q 306,220.8 308,224 Q 310,227.2 312,224 Q 314,220.8 316,224 Q 318,227.2 320,224 Q 322,220.8 324,224 Q 326,227.2 328,224 Q 330,220.8 332,224 Q 334,227.2 336,224 Q 338,220.8 340,224 Q 342,227.2 344,224 Q 346,220.8 348,224 Q 350,227.2 352,224 Q 354,220.8 356,224 Q 358,227.2 360,224 Q 362,220.8 364,224 Q 366,227.2 368,224 Q 370,220.8 372,224 Q 374,227.2 376,224 Q 378,220.8 380,224 Q 382,227.2 384,224 Q 386,220.8 388,224 Q 390,227.2 392,224 Q 394,220.8 396,224 Q 398,227.2 400,224 Q 402,220.8 404,224 Q 406,227.2 408,224 Q 410,220.8 412,224 Q 414,227.2 416,224 Q 418,220.8 420,224 Q 422,227.2 424,224 Q 426,220.8 428,224 Q 430,227.2 432,224 Q 434,220.8 436,224 Q 438,227.2 440,224 Q 442,220.8 444,224 Q 446,227.2 448,224 Q 450,220.8 452,224 Q 454,227.2 456,224 Q 458,220.8 460,224 Q 462,227.2 464,224 Q 466,220.8 468,224 Q 470,227.2 472,224 Q 474,220.8 476,224 Q 478,227.2 480,224 Q 482,220.8 484,224 Q 486,227.2 488,224 Q 490,220.8 492,224 Q 494,227.2 496,224 Q 498,220.8 500,224 Q 502,227.2 504,224 Q 506,220.8 508,224 Q 510,227.2 512,224 Q 514,220.8 516,224 Q 518,227.2 520,224 Q 522,220.8 524,224 Q 526,227.2 528,224 Q 530,220.8 532,224 Q 534,227.2 536,224 Q 538,220.8 540,224 Q 542,227.2 544,224 Q 546,220.8 548,224 Q 550,227.2 552,224 Q 554,220.8 556,224 Q 558,227.2 560,224 " fill="none" stroke="black"/>
                <path d="M 120,256 Q 122,252.8 124,256 Q 126,259.2 128,256 Q 130,252.8 132,256 Q 134,259.2 136,256 Q 138,252.8 140,256 Q 142,259.2 144,256 Q 146,252.8 148,256 Q 150,259.2 152,256 Q 154,252.8 156,256 Q 158,259.2 160,256 Q 162,252.8 164,256 Q 166,259.2 168,256 Q 170,252.8 172,256 Q 174,259.2 176,256 Q 178,252.8 180,256 Q 182,259.2 184,256 Q 186,252.8 188,256 Q 190,259.2 192,256 Q 194,252.8 196,256 Q 198,259.2 200,256 Q 202,252.8 204,256 Q 206,259.2 208,256 Q 210,252.8 212,256 Q 214,259.2 216,256 Q 218,252.8 220,256 Q 222,259.2 224,256 Q 226,252.8 228,256 Q 230,259.2 232,256 Q 234,252.8 236,256 Q 238,259.2 240,256 Q 242,252.8 244,256 Q 246,259.2 248,256 Q 250,252.8 252,256 Q 254,259.2 256,256 Q 258,252.8 260,256 Q 262,259.2 264,256 Q 266,252.8 268,256 Q 270,259.2 272,256 Q 274,252.8 276,256 Q 278,259.2 280,256 Q 282,252.8 284,256 Q 286,259.2 288,256 Q 290,252.8 292,256 Q 294,259.2 296,256 Q 298,252.8 300,256 Q 302,259.2 304,256 Q 306,252.8 308,256 Q 310,259.2 312,256 Q 314,252.8 316,256 Q 318,259.2 320,256 Q 322,252.8 324,256 Q 326,259.2 328,256 Q 330,252.8 332,256 Q 334,259.2 336,256 Q 338,252.8 340,256 Q 342,259.2 344,256 Q 346,252.8 348,256 Q 350,259.2 352,256 Q 354,252.8 356,256 Q 358,259.2 360,256 Q 362,252.8 364,256 Q 366,259.2 368,256 Q 370,252.8 372,256 Q 374,259.2 376,256 Q 378,252.8 380,256 Q 382,259.2 384,256 Q 386,252.8 388,256 Q 390,259.2 392,256 Q 394,252.8 396,256 Q 398,259.2 400,256 Q 402,252.8 404,256 Q 406,259.2 408,256 Q 410,252.8 412,256 Q 414,259.2 416,256 Q 418,252.8 420,256 Q 422,259.2 424,256 Q 426,252.8 428,256 Q 430,259.2 432,256 Q 434,252.8 436,256 Q 438,259.2 440,256 Q 442,252.8 444,256 Q 446,259.2 448,256 Q 450,252.8 452,256 Q 454,259.2 456,256 Q 458,252.8 460,256 Q 462,259.2 464,256 Q 466,252.8 468,256 Q 470,259.2 472,256 Q 474,252.8 476,256 Q 478,259.2 480,256 " fill="none" stroke="black"/>
                <polygon class="arrowhead" points="568,224 556,218.4 556,229.6" fill="black" transform="rotate(0,560,224)"/>
                <polygon class="arrowhead" points="488,256 476,250.4 476,261.6" fill="black" transform="rotate(0,480,256)"/>
                <polygon class="arrowhead" points="408,208 396,202.4 396,213.6" fill="black" transform="rotate(0,400,208)"/>
                <polygon class="arrowhead" points="408,192 396,186.4 396,197.6" fill="black" transform="rotate(0,400,192)"/>
                <polygon class="arrowhead" points="312,176 300,170.4 300,181.6" fill="black" transform="rotate(0,304,176)"/>
                <polygon class="arrowhead" points="216,112 204,106.4 204,117.6" fill="black" transform="rotate(0,208,112)"/>
                <polygon class="arrowhead" points="136,224 124,218.4 124,229.6" fill="black" transform="rotate(180,128,224)"/>
                <polygon class="arrowhead" points="136,144 124,138.4 124,149.6" fill="black" transform="rotate(180,128,144)"/>
                <polygon class="arrowhead" points="120,96 108,90.4 108,101.6" fill="black" transform="rotate(0,112,96)"/>
                <polygon class="arrowhead" points="24,176 12,170.4 12,181.6" fill="black" transform="rotate(180,16,176)"/>
                <g class="text">
                  <text x="28" y="36">Client</text>
                  <text x="404" y="36">Client</text>
                  <text x="484" y="36">Client</text>
                  <text x="548" y="36">Client</text>
                  <text x="12" y="52">B1</text>
                  <text x="120" y="52">ServerB</text>
                  <text x="216" y="52">ServerA</text>
                  <text x="312" y="52">ServerC</text>
                  <text x="396" y="52">C*</text>
                  <text x="476" y="52">B*</text>
                  <text x="556" y="52">A*</text>
                  <text x="48" y="84">Commit,</text>
                  <text x="96" y="84">etc</text>
                  <text x="160" y="100">/update</text>
                  <text x="168" y="132">200</text>
                  <text x="196" y="132">OK</text>
                  <text x="76" y="164">Accepted</text>
                  <text x="256" y="164">/notify</text>
                  <text x="356" y="164">Welcome,</text>
                  <text x="340" y="180">Tree</text>
                  <text x="176" y="212">/notify</text>
                  <text x="252" y="212">Commit</text>
                  <text x="156" y="244">Commit</text>
                  <text x="312" y="244">|</text>
                  <text x="408" y="244">|</text>
                  <text x="216" y="276">|</text>
                  <text x="312" y="276">|</text>
                  <text x="408" y="276">|</text>
                  <text x="40" y="308">ClientB1:</text>
                  <text x="112" y="308">Prepare</text>
                  <text x="172" y="308">Commit</text>
                  <text x="220" y="308">over</text>
                  <text x="332" y="308">AppDataUpdate(+Cathy),</text>
                  <text x="444" y="308">Add*</text>
                  <text x="76" y="324">ClientB1-&gt;ServerB:</text>
                  <text x="164" y="324">[[</text>
                  <text x="208" y="324">Commit,</text>
                  <text x="276" y="324">Welcome,</text>
                  <text x="360" y="324">GroupInfo?,</text>
                  <text x="460" y="324">RatchetTree?</text>
                  <text x="524" y="324">]]</text>
                  <text x="72" y="340">ServerB-&gt;ServerA:</text>
                  <text x="164" y="340">POST</text>
                  <text x="304" y="340">/update/a.example/r/clubhouse</text>
                  <text x="476" y="340">CommitBundle</text>
                  <text x="36" y="356">ServerA:</text>
                  <text x="100" y="356">Verify</text>
                  <text x="148" y="356">that</text>
                  <text x="188" y="356">Adds</text>
                  <text x="224" y="356">are</text>
                  <text x="272" y="356">allowed</text>
                  <text x="316" y="356">by</text>
                  <text x="356" y="356">policy</text>
                  <text x="72" y="372">ServerA-&gt;ServerB:</text>
                  <text x="160" y="372">200</text>
                  <text x="188" y="372">OK</text>
                  <text x="72" y="388">ServerA-&gt;ServerC:</text>
                  <text x="164" y="388">POST</text>
                  <text x="304" y="388">/notify/a.example/r/clubhouse</text>
                  <text x="212" y="404">Intro{</text>
                  <text x="276" y="404">Welcome,</text>
                  <text x="364" y="404">RatchetTree?</text>
                  <text x="424" y="404">}</text>
                  <text x="36" y="420">ServerC:</text>
                  <text x="116" y="420">Recognizes</text>
                  <text x="180" y="420">that</text>
                  <text x="232" y="420">Welcome</text>
                  <text x="276" y="420">is</text>
                  <text x="316" y="420">adding</text>
                  <text x="368" y="420">Cathy</text>
                  <text x="404" y="420">to</text>
                  <text x="456" y="420">clubhouse</text>
                  <text x="76" y="436">ServerC-&gt;ClientC*:</text>
                  <text x="164" y="436">[[</text>
                  <text x="212" y="436">Welcome,</text>
                  <text x="300" y="436">RatchetTree?</text>
                  <text x="364" y="436">]]</text>
                  <text x="72" y="452">ServerA-&gt;ServerB:</text>
                  <text x="164" y="452">POST</text>
                  <text x="304" y="452">/notify/a.example/r/clubhouse</text>
                  <text x="452" y="452">Commit</text>
                  <text x="76" y="468">ServerB-&gt;ClientB*:</text>
                  <text x="164" y="468">[[</text>
                  <text x="204" y="468">Commit</text>
                  <text x="244" y="468">]]</text>
                  <text x="76" y="484">ServerA-&gt;ClientA*:</text>
                  <text x="164" y="484">[[</text>
                  <text x="204" y="484">Commit</text>
                  <text x="244" y="484">]]</text>
                </g>
              </svg>
            </artwork>
            <artwork type="ascii-art"><![CDATA[
Client                                         Client    Client  Client
B1         ServerB     ServerA     ServerC      C*        B*        A*
|             |           |           |           |         |         |
| Commit, etc |           |           |           |         |         |
+~~~~~~~~~~~~>| /update   |           |           |         |         |
|             +---------->|           |           |         |         |
|             |    200 OK |           |           |         |         |
|             |<----------+           |           |         |         |
|    Accepted |           | /notify   | Welcome,  |         |         |
|<~~~~~~~~~~~~+           +---------->| Tree      |         |         |
|             |           |           +~~~~~~~~~~>|         |         |
|             |   /notify | Commit    +~~~~~~~~~~>|         |         |
|             |<----------+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|
|             | Commit    |           |           |         |         |
|             +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|         |
|             |           |           |           |         |         |

ClientB1: Prepare Commit over AppDataUpdate(+Cathy), Add*
ClientB1->ServerB: [[ Commit, Welcome, GroupInfo?, RatchetTree? ]]
ServerB->ServerA: POST /update/a.example/r/clubhouse CommitBundle
ServerA: Verify that Adds are allowed by policy
ServerA->ServerB: 200 OK
ServerA->ServerC: POST /notify/a.example/r/clubhouse
                       Intro{ Welcome, RatchetTree? }
ServerC: Recognizes that Welcome is adding Cathy to clubhouse
ServerC->ClientC*: [[ Welcome, RatchetTree? ]]
ServerA->ServerB: POST /notify/a.example/r/clubhouse Commit
ServerB->ClientB*: [[ Commit ]]
ServerA->ClientA*: [[ Commit ]]
]]></artwork>
          </artset>
        </figure>
      </section>
      <section anchor="cathy-sends-a-message">
        <name>Cathy Sends a Message</name>
        <t>Now that Alice, Bob, and Cathy are all in the room, Cathy wants to say hello to
everyone.  Cathy's client encapsulates the message in an MLS PrivateMessage and
sends it to ServerC, who forwards it to the hub ServerA on Cathy's behalf.
Assuming Cathy is allowed to speak in the room, ServerA will forward Cathy's
message to the other servers involved in the room, who distribute it to their
clients.</t>
        <figure anchor="fig-c-msg">
          <name>Cathy Sends a Message to the Room</name>
          <artset>
            <artwork type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="464" width="736" viewBox="0 0 736 464" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
                <path d="M 24,48 L 24,288" fill="none" stroke="black"/>
                <path d="M 152,48 L 152,288" fill="none" stroke="black"/>
                <path d="M 280,48 L 280,224" fill="none" stroke="black"/>
                <path d="M 280,256 L 280,288" fill="none" stroke="black"/>
                <path d="M 408,48 L 408,224" fill="none" stroke="black"/>
                <path d="M 536,48 L 536,224" fill="none" stroke="black"/>
                <path d="M 616,48 L 616,256" fill="none" stroke="black"/>
                <path d="M 696,48 L 696,288" fill="none" stroke="black"/>
                <path d="M 24,80 Q 26,76.8 28,80 Q 30,83.2 32,80 Q 34,76.8 36,80 Q 38,83.2 40,80 Q 42,76.8 44,80 Q 46,83.2 48,80 Q 50,76.8 52,80 Q 54,83.2 56,80 Q 58,76.8 60,80 Q 62,83.2 64,80 Q 66,76.8 68,80 Q 70,83.2 72,80 Q 74,76.8 76,80 Q 78,83.2 80,80 Q 82,76.8 84,80 Q 86,83.2 88,80 Q 90,76.8 92,80 Q 94,83.2 96,80 Q 98,76.8 100,80 Q 102,83.2 104,80 Q 106,76.8 108,80 Q 110,83.2 112,80 Q 114,76.8 116,80 Q 118,83.2 120,80 Q 122,76.8 124,80 Q 126,83.2 128,80 Q 130,76.8 132,80 Q 134,83.2 136,80 Q 138,76.8 140,80 Q 142,83.2 144,80 " fill="none" stroke="black"/>
                <path d="M 152,96 L 272,96" fill="none" stroke="black"/>
                <path d="M 160,128 L 280,128" fill="none" stroke="black"/>
                <path d="M 32,160 Q 34,156.8 36,160 Q 38,163.2 40,160 Q 42,156.8 44,160 Q 46,163.2 48,160 Q 50,156.8 52,160 Q 54,163.2 56,160 Q 58,156.8 60,160 Q 62,163.2 64,160 Q 66,156.8 68,160 Q 70,163.2 72,160 Q 74,156.8 76,160 Q 78,163.2 80,160 Q 82,156.8 84,160 Q 86,163.2 88,160 Q 90,156.8 92,160 Q 94,163.2 96,160 Q 98,156.8 100,160 Q 102,163.2 104,160 Q 106,156.8 108,160 Q 110,163.2 112,160 Q 114,156.8 116,160 Q 118,163.2 120,160 Q 122,156.8 124,160 Q 126,163.2 128,160 Q 130,156.8 132,160 Q 134,163.2 136,160 Q 138,156.8 140,160 Q 142,163.2 144,160 Q 146,156.8 148,160 Q 150,163.2 152,160 " fill="none" stroke="black"/>
                <path d="M 280,160 L 400,160" fill="none" stroke="black"/>
                <path d="M 408,176 Q 410,172.8 412,176 Q 414,179.2 416,176 Q 418,172.8 420,176 Q 422,179.2 424,176 Q 426,172.8 428,176 Q 430,179.2 432,176 Q 434,172.8 436,176 Q 438,179.2 440,176 Q 442,172.8 444,176 Q 446,179.2 448,176 Q 450,172.8 452,176 Q 454,179.2 456,176 Q 458,172.8 460,176 Q 462,179.2 464,176 Q 466,172.8 468,176 Q 470,179.2 472,176 Q 474,172.8 476,176 Q 478,179.2 480,176 Q 482,172.8 484,176 Q 486,179.2 488,176 Q 490,172.8 492,176 Q 494,179.2 496,176 Q 498,172.8 500,176 Q 502,179.2 504,176 Q 506,172.8 508,176 Q 510,179.2 512,176 Q 514,172.8 516,176 Q 518,179.2 520,176 Q 522,172.8 524,176 Q 526,179.2 528,176 " fill="none" stroke="black"/>
                <path d="M 160,208 L 280,208" fill="none" stroke="black"/>
                <path d="M 152,240 Q 154,236.8 156,240 Q 158,243.2 160,240 Q 162,236.8 164,240 Q 166,243.2 168,240 Q 170,236.8 172,240 Q 174,243.2 176,240 Q 178,236.8 180,240 Q 182,243.2 184,240 Q 186,236.8 188,240 Q 190,243.2 192,240 Q 194,236.8 196,240 Q 198,243.2 200,240 Q 202,236.8 204,240 Q 206,243.2 208,240 Q 210,236.8 212,240 Q 214,243.2 216,240 Q 218,236.8 220,240 Q 222,243.2 224,240 Q 226,236.8 228,240 Q 230,243.2 232,240 Q 234,236.8 236,240 Q 238,243.2 240,240 Q 242,236.8 244,240 Q 246,243.2 248,240 Q 250,236.8 252,240 Q 254,243.2 256,240 Q 258,236.8 260,240 Q 262,243.2 264,240 Q 266,236.8 268,240 Q 270,243.2 272,240 Q 274,236.8 276,240 Q 278,243.2 280,240 Q 282,236.8 284,240 Q 286,243.2 288,240 Q 290,236.8 292,240 Q 294,243.2 296,240 Q 298,236.8 300,240 Q 302,243.2 304,240 Q 306,236.8 308,240 Q 310,243.2 312,240 Q 314,236.8 316,240 Q 318,243.2 320,240 Q 322,236.8 324,240 Q 326,243.2 328,240 Q 330,236.8 332,240 Q 334,243.2 336,240 Q 338,236.8 340,240 Q 342,243.2 344,240 Q 346,236.8 348,240 Q 350,243.2 352,240 Q 354,236.8 356,240 Q 358,243.2 360,240 Q 362,236.8 364,240 Q 366,243.2 368,240 Q 370,236.8 372,240 Q 374,243.2 376,240 Q 378,236.8 380,240 Q 382,243.2 384,240 Q 386,236.8 388,240 Q 390,243.2 392,240 Q 394,236.8 396,240 Q 398,243.2 400,240 Q 402,236.8 404,240 Q 406,243.2 408,240 Q 410,236.8 412,240 Q 414,243.2 416,240 Q 418,236.8 420,240 Q 422,243.2 424,240 Q 426,236.8 428,240 Q 430,243.2 432,240 Q 434,236.8 436,240 Q 438,243.2 440,240 Q 442,236.8 444,240 Q 446,243.2 448,240 Q 450,236.8 452,240 Q 454,243.2 456,240 Q 458,236.8 460,240 Q 462,243.2 464,240 Q 466,236.8 468,240 Q 470,243.2 472,240 Q 474,236.8 476,240 Q 478,243.2 480,240 Q 482,236.8 484,240 Q 486,243.2 488,240 Q 490,236.8 492,240 Q 494,243.2 496,240 Q 498,236.8 500,240 Q 502,243.2 504,240 Q 506,236.8 508,240 Q 510,243.2 512,240 Q 514,236.8 516,240 Q 518,243.2 520,240 Q 522,236.8 524,240 Q 526,243.2 528,240 Q 530,236.8 532,240 Q 534,243.2 536,240 Q 538,236.8 540,240 Q 542,243.2 544,240 Q 546,236.8 548,240 Q 550,243.2 552,240 Q 554,236.8 556,240 Q 558,243.2 560,240 Q 562,236.8 564,240 Q 566,243.2 568,240 Q 570,236.8 572,240 Q 574,243.2 576,240 Q 578,236.8 580,240 Q 582,243.2 584,240 Q 586,236.8 588,240 Q 590,243.2 592,240 Q 594,236.8 596,240 Q 598,243.2 600,240 Q 602,236.8 604,240 Q 606,243.2 608,240 " fill="none" stroke="black"/>
                <path d="M 280,272 Q 282,268.8 284,272 Q 286,275.2 288,272 Q 290,268.8 292,272 Q 294,275.2 296,272 Q 298,268.8 300,272 Q 302,275.2 304,272 Q 306,268.8 308,272 Q 310,275.2 312,272 Q 314,268.8 316,272 Q 318,275.2 320,272 Q 322,268.8 324,272 Q 326,275.2 328,272 Q 330,268.8 332,272 Q 334,275.2 336,272 Q 338,268.8 340,272 Q 342,275.2 344,272 Q 346,268.8 348,272 Q 350,275.2 352,272 Q 354,268.8 356,272 Q 358,275.2 360,272 Q 362,268.8 364,272 Q 366,275.2 368,272 Q 370,268.8 372,272 Q 374,275.2 376,272 Q 378,268.8 380,272 Q 382,275.2 384,272 Q 386,268.8 388,272 Q 390,275.2 392,272 Q 394,268.8 396,272 Q 398,275.2 400,272 Q 402,268.8 404,272 Q 406,275.2 408,272 Q 410,268.8 412,272 Q 414,275.2 416,272 Q 418,268.8 420,272 Q 422,275.2 424,272 Q 426,268.8 428,272 Q 430,275.2 432,272 Q 434,268.8 436,272 Q 438,275.2 440,272 Q 442,268.8 444,272 Q 446,275.2 448,272 Q 450,268.8 452,272 Q 454,275.2 456,272 Q 458,268.8 460,272 Q 462,275.2 464,272 Q 466,268.8 468,272 Q 470,275.2 472,272 Q 474,268.8 476,272 Q 478,275.2 480,272 Q 482,268.8 484,272 Q 486,275.2 488,272 Q 490,268.8 492,272 Q 494,275.2 496,272 Q 498,268.8 500,272 Q 502,275.2 504,272 Q 506,268.8 508,272 Q 510,275.2 512,272 Q 514,268.8 516,272 Q 518,275.2 520,272 Q 522,268.8 524,272 Q 526,275.2 528,272 Q 530,268.8 532,272 Q 534,275.2 536,272 Q 538,268.8 540,272 Q 542,275.2 544,272 Q 546,268.8 548,272 Q 550,275.2 552,272 Q 554,268.8 556,272 Q 558,275.2 560,272 Q 562,268.8 564,272 Q 566,275.2 568,272 Q 570,268.8 572,272 Q 574,275.2 576,272 Q 578,268.8 580,272 Q 582,275.2 584,272 Q 586,268.8 588,272 Q 590,275.2 592,272 Q 594,268.8 596,272 Q 598,275.2 600,272 Q 602,268.8 604,272 Q 606,275.2 608,272 Q 610,268.8 612,272 Q 614,275.2 616,272 Q 618,268.8 620,272 Q 622,275.2 624,272 Q 626,268.8 628,272 Q 630,275.2 632,272 Q 634,268.8 636,272 Q 638,275.2 640,272 Q 642,268.8 644,272 Q 646,275.2 648,272 Q 650,268.8 652,272 Q 654,275.2 656,272 Q 658,268.8 660,272 Q 662,275.2 664,272 Q 666,268.8 668,272 Q 670,275.2 672,272 Q 674,268.8 676,272 Q 678,275.2 680,272 Q 682,268.8 684,272 Q 686,275.2 688,272 " fill="none" stroke="black"/>
                <polygon class="arrowhead" points="696,272 684,266.4 684,277.6" fill="black" transform="rotate(0,688,272)"/>
                <polygon class="arrowhead" points="616,240 604,234.4 604,245.6" fill="black" transform="rotate(0,608,240)"/>
                <polygon class="arrowhead" points="536,176 524,170.4 524,181.6" fill="black" transform="rotate(0,528,176)"/>
                <polygon class="arrowhead" points="408,160 396,154.4 396,165.6" fill="black" transform="rotate(0,400,160)"/>
                <polygon class="arrowhead" points="280,96 268,90.4 268,101.6" fill="black" transform="rotate(0,272,96)"/>
                <polygon class="arrowhead" points="168,208 156,202.4 156,213.6" fill="black" transform="rotate(180,160,208)"/>
                <polygon class="arrowhead" points="168,128 156,122.4 156,133.6" fill="black" transform="rotate(180,160,128)"/>
                <polygon class="arrowhead" points="152,80 140,74.4 140,85.6" fill="black" transform="rotate(0,144,80)"/>
                <polygon class="arrowhead" points="40,160 28,154.4 28,165.6" fill="black" transform="rotate(180,32,160)"/>
                <g class="text">
                  <text x="36" y="36">ClientC1</text>
                  <text x="152" y="36">ServerC</text>
                  <text x="280" y="36">ServerA</text>
                  <text x="408" y="36">ServerB</text>
                  <text x="540" y="36">ClientB*</text>
                  <text x="620" y="36">ClientC*</text>
                  <text x="700" y="36">ClientA*</text>
                  <text x="64" y="68">Message</text>
                  <text x="192" y="84">/submit</text>
                  <text x="232" y="116">200</text>
                  <text x="260" y="116">OK</text>
                  <text x="108" y="148">Accepted</text>
                  <text x="320" y="148">/notify</text>
                  <text x="448" y="164">Message</text>
                  <text x="240" y="196">/notify</text>
                  <text x="192" y="228">Message</text>
                  <text x="320" y="260">Message</text>
                  <text x="408" y="260">|</text>
                  <text x="536" y="260">|</text>
                  <text x="408" y="292">|</text>
                  <text x="536" y="292">|</text>
                  <text x="616" y="292">|</text>
                  <text x="76" y="324">ClientC1-&gt;ServerC:</text>
                  <text x="164" y="324">[[</text>
                  <text x="284" y="324">MLSMessage(PrivateMessage)</text>
                  <text x="404" y="324">]]</text>
                  <text x="72" y="340">ServerC-&gt;ServerA:</text>
                  <text x="164" y="340">POST</text>
                  <text x="180" y="356">/submitMessage/a.example/r/clubhouse</text>
                  <text x="436" y="356">MLSMessage(PrivateMessage)</text>
                  <text x="36" y="372">ServerA:</text>
                  <text x="108" y="372">Verifies</text>
                  <text x="164" y="372">that</text>
                  <text x="216" y="372">message</text>
                  <text x="260" y="372">is</text>
                  <text x="304" y="372">allowed</text>
                  <text x="72" y="388">ServerA-&gt;ServerC:</text>
                  <text x="164" y="388">POST</text>
                  <text x="304" y="388">/notify/a.example/r/clubhouse</text>
                  <text x="460" y="388">Message{</text>
                  <text x="604" y="388">MLSMessage(PrivateMessage)</text>
                  <text x="720" y="388">}</text>
                  <text x="72" y="404">ServerA-&gt;ServerB:</text>
                  <text x="164" y="404">POST</text>
                  <text x="304" y="404">/notify/a.example/r/clubhouse</text>
                  <text x="460" y="404">Message{</text>
                  <text x="604" y="404">MLSMessage(PrivateMessage)</text>
                  <text x="720" y="404">}</text>
                  <text x="76" y="420">ServerA-&gt;ClientA*:</text>
                  <text x="164" y="420">[[</text>
                  <text x="284" y="420">MLSMessage(PrivateMessage)</text>
                  <text x="404" y="420">]]</text>
                  <text x="76" y="436">ServerB-&gt;ClientB*:</text>
                  <text x="164" y="436">[[</text>
                  <text x="284" y="436">MLSMessage(PrivateMessage)</text>
                  <text x="404" y="436">]]</text>
                  <text x="76" y="452">ServerC-&gt;ClientC*:</text>
                  <text x="164" y="452">[[</text>
                  <text x="284" y="452">MLSMessage(PrivateMessage)</text>
                  <text x="404" y="452">]]</text>
                </g>
              </svg>
            </artwork>
            <artwork type="ascii-art"><![CDATA[
ClientC1       ServerC         ServerA         ServerB         ClientB*  ClientC*  ClientA*
  |               |               |               |               |         |         |
  | Message       |               |               |               |         |         |
  +~~~~~~~~~~~~~~>| /submit       |               |               |         |         |
  |               +-------------->|               |               |         |         |
  |               |        200 OK |               |               |         |         |
  |               |<--------------+               |               |         |         |
  |      Accepted |               | /notify       |               |         |         |
  |<~~~~~~~~~~~~~~+               +-------------->| Message       |         |         |
  |               |               |               +~~~~~~~~~~~~~~>|         |         |
  |               |       /notify |               |               |         |         |
  |               |<--------------+               |               |         |         |
  |               | Message       |               |               |         |         |
  |               +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|         |
  |               |               | Message       |               |         |         |
  |               |               +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|
  |               |               |               |               |         |         |

ClientC1->ServerC: [[ MLSMessage(PrivateMessage) ]]
ServerC->ServerA: POST
    /submitMessage/a.example/r/clubhouse MLSMessage(PrivateMessage)
ServerA: Verifies that message is allowed
ServerA->ServerC: POST /notify/a.example/r/clubhouse Message{ MLSMessage(PrivateMessage) }
ServerA->ServerB: POST /notify/a.example/r/clubhouse Message{ MLSMessage(PrivateMessage) }
ServerA->ClientA*: [[ MLSMessage(PrivateMessage) ]]
ServerB->ClientB*: [[ MLSMessage(PrivateMessage) ]]
ServerC->ClientC*: [[ MLSMessage(PrivateMessage) ]]
]]></artwork>
          </artset>
        </figure>
      </section>
      <section anchor="bob-leaves-the-room">
        <name>Bob Leaves the Room</name>
        <t>A user removing another user follows the same flow as adding the user.  The
user performing the removal creates an MLS commit covering Remove proposals for
all of the removed user's devices, and an AppDataUpdate proposal updating the
<tt>participant_list</tt> component to remove the removed user from the room's
participant list.</t>
        <t>One's own user leaving is slightly more complicated than removing another user,
because the leaving user cannot remove all of their devices from the MLS group.
Instead, the leave happens in three steps:</t>
        <ol spacing="normal" type="1"><li>
            <t>The leaving client constructs MLS Remove proposals for all of the user's
devices (including the leaving client), and an AppDataUpdate proposal for the
<tt>participant_list</tt> component that removes its user from the participant list.</t>
          </li>
          <li>
            <t>The leaving client sends these proposals to the hub.  The hub caches the proposals.</t>
          </li>
          <li>
            <t>The next time a client attempts to commit, the hub requires the client to
include the cached proposals.</t>
          </li>
        </ol>
        <t>The hub thus guarantees the leaving client that they will be removed as soon as
possible.</t>
        <figure anchor="fig-b-leave">
          <name>Bob Leaves the Room</name>
          <artset>
            <artwork type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="704" width="608" viewBox="0 0 608 704" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
                <path d="M 24,48 L 24,416" fill="none" stroke="black"/>
                <path d="M 152,48 L 152,416" fill="none" stroke="black"/>
                <path d="M 280,48 L 280,416" fill="none" stroke="black"/>
                <path d="M 408,48 L 408,416" fill="none" stroke="black"/>
                <path d="M 536,48 L 536,368" fill="none" stroke="black"/>
                <path d="M 536,400 L 536,416" fill="none" stroke="black"/>
                <path d="M 600,48 L 600,416" fill="none" stroke="black"/>
                <path d="M 24,80 Q 26,76.8 28,80 Q 30,83.2 32,80 Q 34,76.8 36,80 Q 38,83.2 40,80 Q 42,76.8 44,80 Q 46,83.2 48,80 Q 50,76.8 52,80 Q 54,83.2 56,80 Q 58,76.8 60,80 Q 62,83.2 64,80 Q 66,76.8 68,80 Q 70,83.2 72,80 Q 74,76.8 76,80 Q 78,83.2 80,80 Q 82,76.8 84,80 Q 86,83.2 88,80 Q 90,76.8 92,80 Q 94,83.2 96,80 Q 98,76.8 100,80 Q 102,83.2 104,80 Q 106,76.8 108,80 Q 110,83.2 112,80 Q 114,76.8 116,80 Q 118,83.2 120,80 Q 122,76.8 124,80 Q 126,83.2 128,80 Q 130,76.8 132,80 Q 134,83.2 136,80 Q 138,76.8 140,80 Q 142,83.2 144,80 " fill="none" stroke="black"/>
                <path d="M 152,96 L 272,96" fill="none" stroke="black"/>
                <path d="M 160,128 L 280,128" fill="none" stroke="black"/>
                <path d="M 32,160 Q 34,156.8 36,160 Q 38,163.2 40,160 Q 42,156.8 44,160 Q 46,163.2 48,160 Q 50,156.8 52,160 Q 54,163.2 56,160 Q 58,156.8 60,160 Q 62,163.2 64,160 Q 66,156.8 68,160 Q 70,163.2 72,160 Q 74,156.8 76,160 Q 78,163.2 80,160 Q 82,156.8 84,160 Q 86,163.2 88,160 Q 90,156.8 92,160 Q 94,163.2 96,160 Q 98,156.8 100,160 Q 102,163.2 104,160 Q 106,156.8 108,160 Q 110,163.2 112,160 Q 114,156.8 116,160 Q 118,163.2 120,160 Q 122,156.8 124,160 Q 126,163.2 128,160 Q 130,156.8 132,160 Q 134,163.2 136,160 Q 138,156.8 140,160 Q 142,163.2 144,160 Q 146,156.8 148,160 Q 150,163.2 152,160 " fill="none" stroke="black"/>
                <path d="M 280,160 L 400,160" fill="none" stroke="black"/>
                <path d="M 408,192 Q 410,188.8 412,192 Q 414,195.2 416,192 Q 418,188.8 420,192 Q 422,195.2 424,192 Q 426,188.8 428,192 Q 430,195.2 432,192 Q 434,188.8 436,192 Q 438,195.2 440,192 Q 442,188.8 444,192 Q 446,195.2 448,192 Q 450,188.8 452,192 Q 454,195.2 456,192 Q 458,188.8 460,192 Q 462,195.2 464,192 Q 466,188.8 468,192 Q 470,195.2 472,192 Q 474,188.8 476,192 Q 478,195.2 480,192 Q 482,188.8 484,192 Q 486,195.2 488,192 Q 490,188.8 492,192 Q 494,195.2 496,192 Q 498,188.8 500,192 Q 502,195.2 504,192 Q 506,188.8 508,192 Q 510,195.2 512,192 Q 514,188.8 516,192 Q 518,195.2 520,192 Q 522,188.8 524,192 Q 526,195.2 528,192 " fill="none" stroke="black"/>
                <path d="M 416,240 Q 418,236.8 420,240 Q 422,243.2 424,240 Q 426,236.8 428,240 Q 430,243.2 432,240 Q 434,236.8 436,240 Q 438,243.2 440,240 Q 442,236.8 444,240 Q 446,243.2 448,240 Q 450,236.8 452,240 Q 454,243.2 456,240 Q 458,236.8 460,240 Q 462,243.2 464,240 Q 466,236.8 468,240 Q 470,243.2 472,240 Q 474,236.8 476,240 Q 478,243.2 480,240 Q 482,236.8 484,240 Q 486,243.2 488,240 Q 490,236.8 492,240 Q 494,243.2 496,240 Q 498,236.8 500,240 Q 502,243.2 504,240 Q 506,236.8 508,240 Q 510,243.2 512,240 Q 514,236.8 516,240 Q 518,243.2 520,240 Q 522,236.8 524,240 Q 526,243.2 528,240 Q 530,236.8 532,240 Q 534,243.2 536,240 " fill="none" stroke="black"/>
                <path d="M 288,272 L 408,272" fill="none" stroke="black"/>
                <path d="M 280,304 L 400,304" fill="none" stroke="black"/>
                <path d="M 408,336 Q 410,332.8 412,336 Q 414,339.2 416,336 Q 418,332.8 420,336 Q 422,339.2 424,336 Q 426,332.8 428,336 Q 430,339.2 432,336 Q 434,332.8 436,336 Q 438,339.2 440,336 Q 442,332.8 444,336 Q 446,339.2 448,336 Q 450,332.8 452,336 Q 454,339.2 456,336 Q 458,332.8 460,336 Q 462,339.2 464,336 Q 466,332.8 468,336 Q 470,339.2 472,336 Q 474,332.8 476,336 Q 478,339.2 480,336 Q 482,332.8 484,336 Q 486,339.2 488,336 Q 490,332.8 492,336 Q 494,339.2 496,336 Q 498,332.8 500,336 Q 502,339.2 504,336 Q 506,332.8 508,336 Q 510,339.2 512,336 Q 514,332.8 516,336 Q 518,339.2 520,336 Q 522,332.8 524,336 Q 526,339.2 528,336 " fill="none" stroke="black"/>
                <path d="M 160,368 L 400,368" fill="none" stroke="black"/>
                <path d="M 32,384 Q 34,380.8 36,384 Q 38,387.2 40,384 Q 42,380.8 44,384 Q 46,387.2 48,384 Q 50,380.8 52,384 Q 54,387.2 56,384 Q 58,380.8 60,384 Q 62,387.2 64,384 Q 66,380.8 68,384 Q 70,387.2 72,384 Q 74,380.8 76,384 Q 78,387.2 80,384 Q 82,380.8 84,384 Q 86,387.2 88,384 Q 90,380.8 92,384 Q 94,387.2 96,384 Q 98,380.8 100,384 Q 102,387.2 104,384 Q 106,380.8 108,384 Q 110,387.2 112,384 Q 114,380.8 116,384 Q 118,387.2 120,384 Q 122,380.8 124,384 Q 126,387.2 128,384 Q 130,380.8 132,384 Q 134,387.2 136,384 Q 138,380.8 140,384 Q 142,387.2 144,384 Q 146,380.8 148,384 Q 150,387.2 152,384 " fill="none" stroke="black"/>
                <path d="M 408,384 Q 410,380.8 412,384 Q 414,387.2 416,384 Q 418,380.8 420,384 Q 422,387.2 424,384 Q 426,380.8 428,384 Q 430,387.2 432,384 Q 434,380.8 436,384 Q 438,387.2 440,384 Q 442,380.8 444,384 Q 446,387.2 448,384 Q 450,380.8 452,384 Q 454,387.2 456,384 Q 458,380.8 460,384 Q 462,387.2 464,384 Q 466,380.8 468,384 Q 470,387.2 472,384 Q 474,380.8 476,384 Q 478,387.2 480,384 Q 482,380.8 484,384 Q 486,387.2 488,384 Q 490,380.8 492,384 Q 494,387.2 496,384 Q 498,380.8 500,384 Q 502,387.2 504,384 Q 506,380.8 508,384 Q 510,387.2 512,384 Q 514,380.8 516,384 Q 518,387.2 520,384 Q 522,380.8 524,384 Q 526,387.2 528,384 Q 530,380.8 532,384 Q 534,387.2 536,384 Q 538,380.8 540,384 Q 542,387.2 544,384 Q 546,380.8 548,384 Q 550,387.2 552,384 Q 554,380.8 556,384 Q 558,387.2 560,384 Q 562,380.8 564,384 Q 566,387.2 568,384 Q 570,380.8 572,384 Q 574,387.2 576,384 Q 578,380.8 580,384 Q 582,387.2 584,384 Q 586,380.8 588,384 Q 590,387.2 592,384 " fill="none" stroke="black"/>
                <path d="M 408,400 Q 410,396.8 412,400 Q 414,403.2 416,400 Q 418,396.8 420,400 Q 422,403.2 424,400 Q 426,396.8 428,400 Q 430,403.2 432,400 Q 434,396.8 436,400 Q 438,403.2 440,400 Q 442,396.8 444,400 Q 446,403.2 448,400 Q 450,396.8 452,400 Q 454,403.2 456,400 Q 458,396.8 460,400 Q 462,403.2 464,400 Q 466,396.8 468,400 Q 470,403.2 472,400 Q 474,396.8 476,400 Q 478,403.2 480,400 Q 482,396.8 484,400 Q 486,403.2 488,400 Q 490,396.8 492,400 Q 494,403.2 496,400 Q 498,396.8 500,400 Q 502,403.2 504,400 Q 506,396.8 508,400 Q 510,403.2 512,400 Q 514,396.8 516,400 Q 518,403.2 520,400 Q 522,396.8 524,400 Q 526,403.2 528,400 " fill="none" stroke="black"/>
                <polygon class="arrowhead" points="600,384 588,378.4 588,389.6" fill="black" transform="rotate(0,592,384)"/>
                <polygon class="arrowhead" points="536,400 524,394.4 524,405.6" fill="black" transform="rotate(0,528,400)"/>
                <polygon class="arrowhead" points="536,336 524,330.4 524,341.6" fill="black" transform="rotate(0,528,336)"/>
                <polygon class="arrowhead" points="536,192 524,186.4 524,197.6" fill="black" transform="rotate(0,528,192)"/>
                <polygon class="arrowhead" points="424,240 412,234.4 412,245.6" fill="black" transform="rotate(180,416,240)"/>
                <polygon class="arrowhead" points="408,368 396,362.4 396,373.6" fill="black" transform="rotate(0,400,368)"/>
                <polygon class="arrowhead" points="408,304 396,298.4 396,309.6" fill="black" transform="rotate(0,400,304)"/>
                <polygon class="arrowhead" points="408,160 396,154.4 396,165.6" fill="black" transform="rotate(0,400,160)"/>
                <polygon class="arrowhead" points="296,272 284,266.4 284,277.6" fill="black" transform="rotate(180,288,272)"/>
                <polygon class="arrowhead" points="280,96 268,90.4 268,101.6" fill="black" transform="rotate(0,272,96)"/>
                <polygon class="arrowhead" points="168,368 156,362.4 156,373.6" fill="black" transform="rotate(180,160,368)"/>
                <polygon class="arrowhead" points="168,128 156,122.4 156,133.6" fill="black" transform="rotate(180,160,128)"/>
                <polygon class="arrowhead" points="152,80 140,74.4 140,85.6" fill="black" transform="rotate(0,144,80)"/>
                <polygon class="arrowhead" points="40,384 28,378.4 28,389.6" fill="black" transform="rotate(180,32,384)"/>
                <polygon class="arrowhead" points="40,160 28,154.4 28,165.6" fill="black" transform="rotate(180,32,160)"/>
                <g class="text">
                  <text x="36" y="36">ClientB1</text>
                  <text x="152" y="36">ServerB</text>
                  <text x="280" y="36">ServerA</text>
                  <text x="408" y="36">ServerC</text>
                  <text x="540" y="36">ClientC1</text>
                  <text x="596" y="36">C2</text>
                  <text x="72" y="68">Proposals</text>
                  <text x="192" y="84">/update</text>
                  <text x="232" y="116">200</text>
                  <text x="260" y="116">OK</text>
                  <text x="108" y="148">Accepted</text>
                  <text x="328" y="148">/notify</text>
                  <text x="456" y="180">Proposals</text>
                  <text x="472" y="228">Commit(Props)</text>
                  <text x="368" y="260">/update</text>
                  <text x="304" y="292">200</text>
                  <text x="332" y="292">OK</text>
                  <text x="452" y="324">Accepted</text>
                  <text x="240" y="356">/notify</text>
                  <text x="320" y="356">/notify</text>
                  <text x="116" y="372">Commit</text>
                  <text x="444" y="372">Commit</text>
                  <text x="40" y="452">ClientB1:</text>
                  <text x="112" y="452">Prepare</text>
                  <text x="180" y="452">Remove*,</text>
                  <text x="296" y="452">AppDataUpdate(-Bob)</text>
                  <text x="76" y="468">ClientB1-&gt;ServerB:</text>
                  <text x="164" y="468">[[</text>
                  <text x="212" y="468">Remove*,</text>
                  <text x="304" y="468">AppDataUpdate</text>
                  <text x="372" y="468">]]</text>
                  <text x="72" y="484">ServerB-&gt;ServerA:</text>
                  <text x="164" y="484">POST</text>
                  <text x="304" y="484">/update/a.example/r/clubhouse</text>
                  <text x="460" y="484">Remove*,</text>
                  <text x="552" y="484">AppDataUpdate</text>
                  <text x="36" y="500">ServerA:</text>
                  <text x="100" y="500">Verify</text>
                  <text x="148" y="500">that</text>
                  <text x="204" y="500">Removes,</text>
                  <text x="296" y="500">AppDataUpdate</text>
                  <text x="368" y="500">are</text>
                  <text x="416" y="500">allowed</text>
                  <text x="460" y="500">by</text>
                  <text x="504" y="500">policy;</text>
                  <text x="560" y="500">cache</text>
                  <text x="72" y="516">ServerA-&gt;ServerB:</text>
                  <text x="160" y="516">200</text>
                  <text x="188" y="516">OK</text>
                  <text x="72" y="532">ServerA-&gt;ServerC:</text>
                  <text x="164" y="532">POST</text>
                  <text x="304" y="532">/notify/a.example/r/clubhouse</text>
                  <text x="464" y="532">Proposals</text>
                  <text x="80" y="548">ServerC1-&gt;ClientC1:</text>
                  <text x="172" y="548">[[</text>
                  <text x="224" y="548">Proposals</text>
                  <text x="276" y="548">]]</text>
                  <text x="76" y="564">ClientC1-&gt;ServerC:</text>
                  <text x="164" y="564">[[</text>
                  <text x="236" y="564">Commit(Props),</text>
                  <text x="332" y="564">Welcome,</text>
                  <text x="416" y="564">GroupInfo?,</text>
                  <text x="516" y="564">RatchetTree?</text>
                  <text x="580" y="564">]]</text>
                  <text x="72" y="580">ServerC-&gt;ServerA:</text>
                  <text x="164" y="580">POST</text>
                  <text x="304" y="580">/update/a.example/r/clubhouse</text>
                  <text x="476" y="580">CommitBundle</text>
                  <text x="36" y="596">ServerA:</text>
                  <text x="96" y="596">Check</text>
                  <text x="152" y="596">whether</text>
                  <text x="212" y="596">Commit</text>
                  <text x="276" y="596">includes</text>
                  <text x="340" y="596">queued</text>
                  <text x="412" y="596">proposals;</text>
                  <text x="484" y="596">accept</text>
                  <text x="72" y="612">ServerA-&gt;ServerC:</text>
                  <text x="160" y="612">200</text>
                  <text x="188" y="612">OK</text>
                  <text x="72" y="628">ServerA-&gt;ServerB:</text>
                  <text x="164" y="628">POST</text>
                  <text x="304" y="628">/notify/a.example/r/clubhouse</text>
                  <text x="452" y="628">Commit</text>
                  <text x="72" y="644">ServerA-&gt;ServerC:</text>
                  <text x="164" y="644">POST</text>
                  <text x="304" y="644">/notify/a.example/r/clubhouse</text>
                  <text x="452" y="644">Commit</text>
                  <text x="76" y="660">ServerB-&gt;ClientB1:</text>
                  <text x="164" y="660">[[</text>
                  <text x="204" y="660">Commit</text>
                  <text x="244" y="660">]]</text>
                  <text x="76" y="676">ServerC-&gt;ClientC2:</text>
                  <text x="164" y="676">[[</text>
                  <text x="204" y="676">Commit</text>
                  <text x="244" y="676">]]</text>
                  <text x="76" y="692">ServerC-&gt;ClientC1:</text>
                  <text x="164" y="692">[[</text>
                  <text x="204" y="692">Commit</text>
                  <text x="244" y="692">]]</text>
                  <text x="272" y="692">(up</text>
                  <text x="300" y="692">to</text>
                  <text x="352" y="692">provider)</text>
                </g>
              </svg>
            </artwork>
            <artwork type="ascii-art"><![CDATA[
ClientB1       ServerB         ServerA         ServerC         ClientC1  C2
  |               |               |               |               |       |
  | Proposals     |               |               |               |       |
  +~~~~~~~~~~~~~~>| /update       |               |               |       |
  |               +-------------->|               |               |       |
  |               |        200 OK |               |               |       |
  |               |<--------------+               |               |       |
  |      Accepted |               |  /notify      |               |       |
  |<~~~~~~~~~~~~~~+               +-------------->|               |       |
  |               |               |               | Proposals     |       |
  |               |               |               +~~~~~~~~~~~~~~>|       |
  |               |               |               |               |       |
  |               |               |               | Commit(Props) |       |
  |               |               |               |<~~~~~~~~~~~~~~+       |
  |               |               |       /update |               |       |
  |               |               |<--------------+               |       |
  |               |               | 200 OK        |               |       |
  |               |               +-------------->|               |       |
  |               |               |               | Accepted      |       |
  |               |               |               +~~~~~~~~~~~~~~>|       |
  |               |       /notify | /notify       |               |       |
  |        Commit |<--------------+-------------->| Commit        |       |
  |<~~~~~~~~~~~~~~+               |               +~~~~~~~~~~~~~~~~~~~~~~>|
  |               |               |               +~~~~~~~~~~~~~~>|       |
  |               |               |               |               |       |

ClientB1: Prepare Remove*, AppDataUpdate(-Bob)
ClientB1->ServerB: [[ Remove*, AppDataUpdate ]]
ServerB->ServerA: POST /update/a.example/r/clubhouse Remove*, AppDataUpdate
ServerA: Verify that Removes, AppDataUpdate are allowed by policy; cache
ServerA->ServerB: 200 OK
ServerA->ServerC: POST /notify/a.example/r/clubhouse Proposals
ServerC1->ClientC1: [[ Proposals ]]
ClientC1->ServerC: [[ Commit(Props), Welcome, GroupInfo?, RatchetTree? ]]
ServerC->ServerA: POST /update/a.example/r/clubhouse CommitBundle
ServerA: Check whether Commit includes queued proposals; accept
ServerA->ServerC: 200 OK
ServerA->ServerB: POST /notify/a.example/r/clubhouse Commit
ServerA->ServerC: POST /notify/a.example/r/clubhouse Commit
ServerB->ClientB1: [[ Commit ]]
ServerC->ClientC2: [[ Commit ]]
ServerC->ClientC1: [[ Commit ]] (up to provider)
]]></artwork>
          </artset>
        </figure>
      </section>
      <section anchor="cathy-adds-a-new-device">
        <name>Cathy adds a new device</name>
        <t>Many users have multiple clients often running on different devices
(for example a phone, a tablet, and a computer). When a user creates a new
client, that client needs to be able to join all the MLS groups associated
with the rooms in which the user is a participant.</t>
        <t>In MLS in order to initiate joining a group the joining client needs to get the current GroupInfo
and <tt>ratchet_tree</tt>, and then send an External Commit to the hub. In MIMI,
the hub keeps or reconstructs a copy of the GroupInfo, assuming that other
clients may not be available to assist the client with joining.</t>
        <t>For Cathy's new client (ClientC3) to join the MLS group and therefore fully participate
in the room with Alice, ClientC3 needs to fetch the MLS GroupInfo, and then
generate an External Commit adding ClientC3.</t>
        <t>Cathy's new client sends the External Commit to the room's MLS group by sending
an /update to the room.</t>
        <figure anchor="fig-c3-new-client">
          <name>Cathy Adds a new Client</name>
          <artset>
            <artwork type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="736" width="736" viewBox="0 0 736 736" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
                <path d="M 24,48 L 24,448" fill="none" stroke="black"/>
                <path d="M 152,48 L 152,448" fill="none" stroke="black"/>
                <path d="M 280,48 L 280,416" fill="none" stroke="black"/>
                <path d="M 408,48 L 408,288" fill="none" stroke="black"/>
                <path d="M 408,320 L 408,416" fill="none" stroke="black"/>
                <path d="M 536,48 L 536,288" fill="none" stroke="black"/>
                <path d="M 536,320 L 536,416" fill="none" stroke="black"/>
                <path d="M 616,48 L 616,288" fill="none" stroke="black"/>
                <path d="M 616,320 L 616,448" fill="none" stroke="black"/>
                <path d="M 696,48 L 696,448" fill="none" stroke="black"/>
                <path d="M 32,96 Q 34,92.8 36,96 Q 38,99.2 40,96 Q 42,92.8 44,96 Q 46,99.2 48,96 Q 50,92.8 52,96 Q 54,99.2 56,96 Q 58,92.8 60,96 Q 62,99.2 64,96 Q 66,92.8 68,96 Q 70,99.2 72,96 Q 74,92.8 76,96 Q 78,99.2 80,96 Q 82,92.8 84,96 Q 86,99.2 88,96 Q 90,92.8 92,96 Q 94,99.2 96,96 Q 98,92.8 100,96 Q 102,99.2 104,96 Q 106,92.8 108,96 Q 110,99.2 112,96 Q 114,92.8 116,96 Q 118,99.2 120,96 Q 122,92.8 124,96 Q 126,99.2 128,96 Q 130,92.8 132,96 Q 134,99.2 136,96 Q 138,92.8 140,96 Q 142,99.2 144,96 " fill="none" stroke="black"/>
                <path d="M 160,112 L 272,112" fill="none" stroke="black"/>
                <path d="M 160,144 L 272,144" fill="none" stroke="black"/>
                <path d="M 32,160 Q 34,156.8 36,160 Q 38,163.2 40,160 Q 42,156.8 44,160 Q 46,163.2 48,160 Q 50,156.8 52,160 Q 54,163.2 56,160 Q 58,156.8 60,160 Q 62,163.2 64,160 Q 66,156.8 68,160 Q 70,163.2 72,160 Q 74,156.8 76,160 Q 78,163.2 80,160 Q 82,156.8 84,160 Q 86,163.2 88,160 Q 90,156.8 92,160 Q 94,163.2 96,160 Q 98,156.8 100,160 Q 102,163.2 104,160 Q 106,156.8 108,160 Q 110,163.2 112,160 Q 114,156.8 116,160 Q 118,163.2 120,160 Q 122,156.8 124,160 Q 126,163.2 128,160 Q 130,156.8 132,160 Q 134,163.2 136,160 Q 138,156.8 140,160 Q 142,163.2 144,160 " fill="none" stroke="black"/>
                <path d="M 24,224 Q 26,220.8 28,224 Q 30,227.2 32,224 Q 34,220.8 36,224 Q 38,227.2 40,224 Q 42,220.8 44,224 Q 46,227.2 48,224 Q 50,220.8 52,224 Q 54,227.2 56,224 Q 58,220.8 60,224 Q 62,227.2 64,224 Q 66,220.8 68,224 Q 70,227.2 72,224 Q 74,220.8 76,224 Q 78,227.2 80,224 Q 82,220.8 84,224 Q 86,227.2 88,224 Q 90,220.8 92,224 Q 94,227.2 96,224 Q 98,220.8 100,224 Q 102,227.2 104,224 Q 106,220.8 108,224 Q 110,227.2 112,224 Q 114,220.8 116,224 Q 118,227.2 120,224 Q 122,220.8 124,224 Q 126,227.2 128,224 Q 130,220.8 132,224 Q 134,227.2 136,224 Q 138,220.8 140,224 Q 142,227.2 144,224 " fill="none" stroke="black"/>
                <path d="M 152,240 L 272,240" fill="none" stroke="black"/>
                <path d="M 160,272 L 280,272" fill="none" stroke="black"/>
                <path d="M 32,304 Q 34,300.8 36,304 Q 38,307.2 40,304 Q 42,300.8 44,304 Q 46,307.2 48,304 Q 50,300.8 52,304 Q 54,307.2 56,304 Q 58,300.8 60,304 Q 62,307.2 64,304 Q 66,300.8 68,304 Q 70,307.2 72,304 Q 74,300.8 76,304 Q 78,307.2 80,304 Q 82,300.8 84,304 Q 86,307.2 88,304 Q 90,300.8 92,304 Q 94,307.2 96,304 Q 98,300.8 100,304 Q 102,307.2 104,304 Q 106,300.8 108,304 Q 110,307.2 112,304 Q 114,300.8 116,304 Q 118,307.2 120,304 Q 122,300.8 124,304 Q 126,307.2 128,304 Q 130,300.8 132,304 Q 134,307.2 136,304 Q 138,300.8 140,304 Q 142,307.2 144,304 " fill="none" stroke="black"/>
                <path d="M 280,304 Q 282,300.8 284,304 Q 286,307.2 288,304 Q 290,300.8 292,304 Q 294,307.2 296,304 Q 298,300.8 300,304 Q 302,307.2 304,304 Q 306,300.8 308,304 Q 310,307.2 312,304 Q 314,300.8 316,304 Q 318,307.2 320,304 Q 322,300.8 324,304 Q 326,307.2 328,304 Q 330,300.8 332,304 Q 334,307.2 336,304 Q 338,300.8 340,304 Q 342,307.2 344,304 Q 346,300.8 348,304 Q 350,307.2 352,304 Q 354,300.8 356,304 Q 358,307.2 360,304 Q 362,300.8 364,304 Q 366,307.2 368,304 Q 370,300.8 372,304 Q 374,307.2 376,304 Q 378,300.8 380,304 Q 382,307.2 384,304 Q 386,300.8 388,304 Q 390,307.2 392,304 Q 394,300.8 396,304 Q 398,307.2 400,304 Q 402,300.8 404,304 Q 406,307.2 408,304 Q 410,300.8 412,304 Q 414,307.2 416,304 Q 418,300.8 420,304 Q 422,307.2 424,304 Q 426,300.8 428,304 Q 430,307.2 432,304 Q 434,300.8 436,304 Q 438,307.2 440,304 Q 442,300.8 444,304 Q 446,307.2 448,304 Q 450,300.8 452,304 Q 454,307.2 456,304 Q 458,300.8 460,304 Q 462,307.2 464,304 Q 466,300.8 468,304 Q 470,307.2 472,304 Q 474,300.8 476,304 Q 478,307.2 480,304 Q 482,300.8 484,304 Q 486,307.2 488,304 Q 490,300.8 492,304 Q 494,307.2 496,304 Q 498,300.8 500,304 Q 502,307.2 504,304 Q 506,300.8 508,304 Q 510,307.2 512,304 Q 514,300.8 516,304 Q 518,307.2 520,304 Q 522,300.8 524,304 Q 526,307.2 528,304 Q 530,300.8 532,304 Q 534,307.2 536,304 Q 538,300.8 540,304 Q 542,307.2 544,304 Q 546,300.8 548,304 Q 550,307.2 552,304 Q 554,300.8 556,304 Q 558,307.2 560,304 Q 562,300.8 564,304 Q 566,307.2 568,304 Q 570,300.8 572,304 Q 574,307.2 576,304 Q 578,300.8 580,304 Q 582,307.2 584,304 Q 586,300.8 588,304 Q 590,307.2 592,304 Q 594,300.8 596,304 Q 598,307.2 600,304 Q 602,300.8 604,304 Q 606,307.2 608,304 Q 610,300.8 612,304 Q 614,307.2 616,304 Q 618,300.8 620,304 Q 622,307.2 624,304 Q 626,300.8 628,304 Q 630,307.2 632,304 Q 634,300.8 636,304 Q 638,307.2 640,304 Q 642,300.8 644,304 Q 646,307.2 648,304 Q 650,300.8 652,304 Q 654,307.2 656,304 Q 658,300.8 660,304 Q 662,307.2 664,304 Q 666,300.8 668,304 Q 670,307.2 672,304 Q 674,300.8 676,304 Q 678,307.2 680,304 Q 682,300.8 684,304 Q 686,307.2 688,304 " fill="none" stroke="black"/>
                <path d="M 280,352 L 400,352" fill="none" stroke="black"/>
                <path d="M 408,368 Q 410,364.8 412,368 Q 414,371.2 416,368 Q 418,364.8 420,368 Q 422,371.2 424,368 Q 426,364.8 428,368 Q 430,371.2 432,368 Q 434,364.8 436,368 Q 438,371.2 440,368 Q 442,364.8 444,368 Q 446,371.2 448,368 Q 450,364.8 452,368 Q 454,371.2 456,368 Q 458,364.8 460,368 Q 462,371.2 464,368 Q 466,364.8 468,368 Q 470,371.2 472,368 Q 474,364.8 476,368 Q 478,371.2 480,368 Q 482,364.8 484,368 Q 486,371.2 488,368 Q 490,364.8 492,368 Q 494,371.2 496,368 Q 498,364.8 500,368 Q 502,371.2 504,368 Q 506,364.8 508,368 Q 510,371.2 512,368 Q 514,364.8 516,368 Q 518,371.2 520,368 Q 522,364.8 524,368 Q 526,371.2 528,368 " fill="none" stroke="black"/>
                <path d="M 160,400 L 280,400" fill="none" stroke="black"/>
                <path d="M 152,432 Q 154,428.8 156,432 Q 158,435.2 160,432 Q 162,428.8 164,432 Q 166,435.2 168,432 Q 170,428.8 172,432 Q 174,435.2 176,432 Q 178,428.8 180,432 Q 182,435.2 184,432 Q 186,428.8 188,432 Q 190,435.2 192,432 Q 194,428.8 196,432 Q 198,435.2 200,432 Q 202,428.8 204,432 Q 206,435.2 208,432 Q 210,428.8 212,432 Q 214,435.2 216,432 Q 218,428.8 220,432 Q 222,435.2 224,432 Q 226,428.8 228,432 Q 230,435.2 232,432 Q 234,428.8 236,432 Q 238,435.2 240,432 Q 242,428.8 244,432 Q 246,435.2 248,432 Q 250,428.8 252,432 Q 254,435.2 256,432 Q 258,428.8 260,432 Q 262,435.2 264,432 Q 266,428.8 268,432 Q 270,435.2 272,432 Q 274,428.8 276,432 Q 278,435.2 280,432 Q 282,428.8 284,432 Q 286,435.2 288,432 Q 290,428.8 292,432 Q 294,435.2 296,432 Q 298,428.8 300,432 Q 302,435.2 304,432 Q 306,428.8 308,432 Q 310,435.2 312,432 Q 314,428.8 316,432 Q 318,435.2 320,432 Q 322,428.8 324,432 Q 326,435.2 328,432 Q 330,428.8 332,432 Q 334,435.2 336,432 Q 338,428.8 340,432 Q 342,435.2 344,432 Q 346,428.8 348,432 Q 350,435.2 352,432 Q 354,428.8 356,432 Q 358,435.2 360,432 Q 362,428.8 364,432 Q 366,435.2 368,432 Q 370,428.8 372,432 Q 374,435.2 376,432 Q 378,428.8 380,432 Q 382,435.2 384,432 Q 386,428.8 388,432 Q 390,435.2 392,432 Q 394,428.8 396,432 Q 398,435.2 400,432 Q 402,428.8 404,432 Q 406,435.2 408,432 Q 410,428.8 412,432 Q 414,435.2 416,432 Q 418,428.8 420,432 Q 422,435.2 424,432 Q 426,428.8 428,432 Q 430,435.2 432,432 Q 434,428.8 436,432 Q 438,435.2 440,432 Q 442,428.8 444,432 Q 446,435.2 448,432 Q 450,428.8 452,432 Q 454,435.2 456,432 Q 458,428.8 460,432 Q 462,435.2 464,432 Q 466,428.8 468,432 Q 470,435.2 472,432 Q 474,428.8 476,432 Q 478,435.2 480,432 Q 482,428.8 484,432 Q 486,435.2 488,432 Q 490,428.8 492,432 Q 494,435.2 496,432 Q 498,428.8 500,432 Q 502,435.2 504,432 Q 506,428.8 508,432 Q 510,435.2 512,432 Q 514,428.8 516,432 Q 518,435.2 520,432 Q 522,428.8 524,432 Q 526,435.2 528,432 Q 530,428.8 532,432 Q 534,435.2 536,432 Q 538,428.8 540,432 Q 542,435.2 544,432 Q 546,428.8 548,432 Q 550,435.2 552,432 Q 554,428.8 556,432 Q 558,435.2 560,432 Q 562,428.8 564,432 Q 566,435.2 568,432 Q 570,428.8 572,432 Q 574,435.2 576,432 Q 578,428.8 580,432 Q 582,435.2 584,432 Q 586,428.8 588,432 Q 590,435.2 592,432 Q 594,428.8 596,432 Q 598,435.2 600,432 Q 602,428.8 604,432 Q 606,435.2 608,432 " fill="none" stroke="black"/>
                <polygon class="arrowhead" points="696,304 684,298.4 684,309.6" fill="black" transform="rotate(0,688,304)"/>
                <polygon class="arrowhead" points="616,432 604,426.4 604,437.6" fill="black" transform="rotate(0,608,432)"/>
                <polygon class="arrowhead" points="536,368 524,362.4 524,373.6" fill="black" transform="rotate(0,528,368)"/>
                <polygon class="arrowhead" points="408,352 396,346.4 396,357.6" fill="black" transform="rotate(0,400,352)"/>
                <polygon class="arrowhead" points="280,240 268,234.4 268,245.6" fill="black" transform="rotate(0,272,240)"/>
                <polygon class="arrowhead" points="280,112 268,106.4 268,117.6" fill="black" transform="rotate(0,272,112)"/>
                <polygon class="arrowhead" points="168,400 156,394.4 156,405.6" fill="black" transform="rotate(180,160,400)"/>
                <polygon class="arrowhead" points="168,272 156,266.4 156,277.6" fill="black" transform="rotate(180,160,272)"/>
                <polygon class="arrowhead" points="168,144 156,138.4 156,149.6" fill="black" transform="rotate(180,160,144)"/>
                <polygon class="arrowhead" points="152,224 140,218.4 140,229.6" fill="black" transform="rotate(0,144,224)"/>
                <polygon class="arrowhead" points="152,96 140,90.4 140,101.6" fill="black" transform="rotate(0,144,96)"/>
                <polygon class="arrowhead" points="40,304 28,298.4 28,309.6" fill="black" transform="rotate(180,32,304)"/>
                <polygon class="arrowhead" points="40,160 28,154.4 28,165.6" fill="black" transform="rotate(180,32,160)"/>
                <g class="text">
                  <text x="36" y="36">ClientC3</text>
                  <text x="152" y="36">ServerC</text>
                  <text x="280" y="36">ServerA</text>
                  <text x="408" y="36">ServerB</text>
                  <text x="540" y="36">ClientB*</text>
                  <text x="620" y="36">ClientC*</text>
                  <text x="700" y="36">ClientA*</text>
                  <text x="56" y="68">Fetch</text>
                  <text x="72" y="84">GroupInfo</text>
                  <text x="204" y="100">/groupInfo</text>
                  <text x="72" y="132">GroupInfo</text>
                  <text x="120" y="132">+</text>
                  <text x="232" y="132">200</text>
                  <text x="260" y="132">OK</text>
                  <text x="52" y="148">tree</text>
                  <text x="68" y="196">External</text>
                  <text x="64" y="212">Commit,</text>
                  <text x="116" y="212">etc.</text>
                  <text x="192" y="228">/update</text>
                  <text x="232" y="260">200</text>
                  <text x="260" y="260">OK</text>
                  <text x="108" y="292">Accepted</text>
                  <text x="316" y="292">Commit</text>
                  <text x="320" y="340">/notify</text>
                  <text x="444" y="356">Commit</text>
                  <text x="240" y="388">/notify</text>
                  <text x="188" y="420">Commit</text>
                  <text x="280" y="452">|</text>
                  <text x="408" y="452">|</text>
                  <text x="536" y="452">|</text>
                  <text x="76" y="484">ClientC3-&gt;ServerC:</text>
                  <text x="164" y="484">[[</text>
                  <text x="208" y="484">request</text>
                  <text x="272" y="484">current</text>
                  <text x="344" y="484">GroupInfo</text>
                  <text x="396" y="484">]]</text>
                  <text x="72" y="500">ServerC-&gt;ServerA:</text>
                  <text x="164" y="500">POST</text>
                  <text x="316" y="500">/groupInfo/a.example/r/clubhouse</text>
                  <text x="36" y="516">ServerA:</text>
                  <text x="100" y="516">Verify</text>
                  <text x="148" y="516">that</text>
                  <text x="204" y="516">ClientC3</text>
                  <text x="256" y="516">has</text>
                  <text x="328" y="516">authorization</text>
                  <text x="396" y="516">to</text>
                  <text x="428" y="516">join</text>
                  <text x="464" y="516">the</text>
                  <text x="500" y="516">room</text>
                  <text x="72" y="532">ServerA-&gt;ServerC:</text>
                  <text x="160" y="532">200</text>
                  <text x="188" y="532">OK</text>
                  <text x="212" y="532">w/</text>
                  <text x="256" y="532">current</text>
                  <text x="328" y="532">GroupInfo</text>
                  <text x="384" y="532">and</text>
                  <text x="432" y="532">ratchet</text>
                  <text x="484" y="532">tree</text>
                  <text x="76" y="548">ServerC-&gt;ClientC3:</text>
                  <text x="164" y="548">[[</text>
                  <text x="220" y="548">GroupInfo,</text>
                  <text x="284" y="548">tree</text>
                  <text x="316" y="548">]]</text>
                  <text x="40" y="564">ClientC3:</text>
                  <text x="112" y="564">Prepare</text>
                  <text x="180" y="564">External</text>
                  <text x="244" y="564">Commit</text>
                  <text x="292" y="564">Add*</text>
                  <text x="76" y="580">ClientC3-&gt;ServerC:</text>
                  <text x="164" y="580">[[</text>
                  <text x="208" y="580">Commit,</text>
                  <text x="288" y="580">GroupInfo?,</text>
                  <text x="388" y="580">RatchetTree?</text>
                  <text x="452" y="580">]]</text>
                  <text x="72" y="596">ServerC-&gt;ServerA:</text>
                  <text x="164" y="596">POST</text>
                  <text x="304" y="596">/update/a.example/r/clubhouse</text>
                  <text x="476" y="596">CommitBundle</text>
                  <text x="36" y="612">ServerA:</text>
                  <text x="100" y="612">Verify</text>
                  <text x="148" y="612">that</text>
                  <text x="196" y="612">Commit</text>
                  <text x="236" y="612">is</text>
                  <text x="272" y="612">valid</text>
                  <text x="312" y="612">and</text>
                  <text x="364" y="612">ClientC3</text>
                  <text x="412" y="612">is</text>
                  <text x="468" y="612">authorized</text>
                  <text x="72" y="628">ServerA-&gt;ServerC:</text>
                  <text x="160" y="628">200</text>
                  <text x="188" y="628">OK</text>
                  <text x="76" y="644">ServerC-&gt;ClientC3:</text>
                  <text x="164" y="644">[[</text>
                  <text x="212" y="644">External</text>
                  <text x="276" y="644">Commit</text>
                  <text x="320" y="644">was</text>
                  <text x="372" y="644">accepted</text>
                  <text x="420" y="644">]]</text>
                  <text x="76" y="660">ServerA-&gt;ClientA*:</text>
                  <text x="164" y="660">[[</text>
                  <text x="204" y="660">Commit</text>
                  <text x="244" y="660">]]</text>
                  <text x="72" y="676">ServerA-&gt;ServerB:</text>
                  <text x="164" y="676">POST</text>
                  <text x="304" y="676">/notify/a.example/r/clubhouse</text>
                  <text x="452" y="676">Commit</text>
                  <text x="76" y="692">ServerB-&gt;ClientB*:</text>
                  <text x="164" y="692">[[</text>
                  <text x="204" y="692">Commit</text>
                  <text x="244" y="692">]]</text>
                  <text x="72" y="708">ServerA-&gt;ServerC:</text>
                  <text x="164" y="708">POST</text>
                  <text x="304" y="708">/notify/a.example/r/clubhouse</text>
                  <text x="452" y="708">Commit</text>
                  <text x="76" y="724">ServerC-&gt;ClientC*:</text>
                  <text x="164" y="724">[[</text>
                  <text x="204" y="724">Commit</text>
                  <text x="244" y="724">]]</text>
                </g>
              </svg>
            </artwork>
            <artwork type="ascii-art"><![CDATA[
ClientC3       ServerC         ServerA         ServerB         ClientB*  ClientC*  ClientA*
  |               |               |               |               |         |         |
  | Fetch         |               |               |               |         |         |
  | GroupInfo     |               |               |               |         |         |
  |~~~~~~~~~~~~~~>| /groupInfo    |               |               |         |         |
  |               |-------------->|               |               |         |         |
  | GroupInfo +   |        200 OK |               |               |         |         |
  | tree          |<--------------|               |               |         |         |
  |<~~~~~~~~~~~~~~|               |               |               |         |         |
  |               |               |               |               |         |         |
  | External      |               |               |               |         |         |
  | Commit, etc.  |               |               |               |         |         |
  +~~~~~~~~~~~~~~>| /update       |               |               |         |         |
  |               +-------------->|               |               |         |         |
  |               |        200 OK |               |               |         |         |
  |               |<--------------+               |               |         |         |
  |      Accepted |               | Commit        |               |         |         |
  |<~~~~~~~~~~~~~~|               +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|
  |               |               |               |               |         |         |
  |               |               | /notify       |               |         |         |
  |               +               +-------------->| Commit        |         |         |
  |               |               |               +~~~~~~~~~~~~~~>|         |         |
  |               |       /notify |               |               |         |         |
  |               |<--------------+               |               |         |         |
  |               | Commit        |               |               |         |         |
  |               +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|         |
  |               |               |               |               |         |         |

ClientC3->ServerC: [[ request current GroupInfo ]]
ServerC->ServerA: POST /groupInfo/a.example/r/clubhouse
ServerA: Verify that ClientC3 has authorization to join the room
ServerA->ServerC: 200 OK w/ current GroupInfo and ratchet tree
ServerC->ClientC3: [[ GroupInfo, tree ]]
ClientC3: Prepare External Commit Add*
ClientC3->ServerC: [[ Commit, GroupInfo?, RatchetTree? ]]
ServerC->ServerA: POST /update/a.example/r/clubhouse CommitBundle
ServerA: Verify that Commit is valid and ClientC3 is authorized
ServerA->ServerC: 200 OK
ServerC->ClientC3: [[ External Commit was accepted ]]
ServerA->ClientA*: [[ Commit ]]
ServerA->ServerB: POST /notify/a.example/r/clubhouse Commit
ServerB->ClientB*: [[ Commit ]]
ServerA->ServerC: POST /notify/a.example/r/clubhouse Commit
ServerC->ClientC*: [[ Commit ]]
]]></artwork>
          </artset>
        </figure>
      </section>
    </section>
    <section anchor="services-required-at-each-layer">
      <name>Services required at each layer</name>
      <section anchor="transport-layer">
        <name>Transport layer</name>
        <t>MIMI servers communicate using HTTPS.  The HTTP request <bcp14>MUST</bcp14> identify the
source and target providers for the request, in the following way:</t>
        <ul spacing="normal">
          <li>
            <t>The target provider is indicated using a Host header <xref target="RFC9110"/>.  If the
provider is using a non-standard port, then the port component of the Host
header is ignored.</t>
          </li>
          <li>
            <t>The source provider is indicated using a From header <xref target="RFC9110"/>.  The
<tt>mailbox</tt> production in the From header <bcp14>MUST</bcp14> use the <tt>addr-spec</tt> variant, and
the <tt>local-part</tt> of the address <bcp14>MUST</bcp14> contain the fixed string <tt>mimi</tt>.  Thus,
the content of the From header will be <tt>mimi@a.example</tt>, where <tt>a.example</tt> is
the domain name of the source provider.</t>
          </li>
        </ul>
        <ul empty="true">
          <li>
            <t><strong>NOTE</strong>: The use of the From header field here is not really well-aligned with its
  intended use.  The WG should consider whether this is correct, or whether a new
  header field would be better.  Perhaps something like "From-Host" to match Host?</t>
          </li>
        </ul>
        <t>The TLS connection underlying the HTTPS connection <bcp14>MUST</bcp14> be mutually
authenticated.  The certificates presented in the TLS handshake <bcp14>MUST</bcp14>
authenticate the source and target provider domains, according to <xref target="RFC6125"/>.</t>
        <t>The bodies of HTTP requests and responses are defined by the individual
endpoints defined in <xref target="application-layer"/>.</t>
      </section>
      <section anchor="end-to-end-security-layer">
        <name>End-to-End Security Layer</name>
        <t>Every MIMI room has an MLS group associated to it, which provides end-to-end
security guarantees.  The clients participating in the room manage the MLS-level
membership by sending Commit messages covering Add and Remove proposals.</t>
        <t>Every application message sent within a room is authenticated and confidentiality-protected
by virtue of being encapsulated in an MLS PrivateMessage object.</t>
        <t>MIMI uses the MLS application state synchronization mechanism
(<xref target="I-D.ietf-mls-extensions"/>) to ensure that the clients involved
in a MIMI room agree on the state of the room.  Each MIMI message that changes
the state of the room is encapsulated in an AppDataUpdate proposal and transmitted
inside an MLS PublicMessage object.</t>
        <t>The PublicMessage encapsulation provides sender authentication, including the
ability for actors outside the group (e.g., servers involved in the room) to
originate AppDataUpdate proposals.  Encoding room state changes in MLS proposals
ensures that a client will not process a commit that confirms a state change
before processing the state change itself.</t>
        <ul empty="true">
          <li>
            <t><strong>TODO</strong>: A little more needs to be said here about how MLS is used.  For
example: What types of credential are required / allowed?  If servers are going
to be allowed to introduce room changes, how are their keys provisioned as
external signers? Need to maintain the membership and the list of queued proposals.</t>
          </li>
        </ul>
      </section>
      <section anchor="application-layer">
        <name>Application Layer</name>
        <t>Servers in MIMI provide a few functions that enable messaging applications.
All servers act as publication points for key material used to add their users
to rooms. The hub server for a room tracks the state of the room, and controls
how the room's state evolves, e.g., by ensuring that changes are compliant with
the room's policy. Non-hub servers facilitate interactions between their clients
and the hub server.</t>
        <t>In this section, we describe the state that servers keep. The following top
level section describes the HTTP endpoints exposed to enable these functions.</t>
        <section anchor="server-state">
          <name>Server State</name>
          <t>Every MIMI server is a publication point for users' key material, via the
<tt>keyMaterial</tt> endpoint discussed in <xref target="fetch-key-material"/>.  To support this
endpoint, the server stores a set of KeyPackages, where each KeyPackage belongs
to a specific user and device.</t>
          <t>Each KeyPackage includes a list of its MLS client's capabilities (MLS
protocol versions, cipher suites, extensions, proposal types, and credential
types). When claiming KeyPackages, the requester includes the list of
<tt>RequiredCapabilites</tt> to ensure the new joiner is compatible with and
capable of participating in the corresponding room.</t>
          <t>The hub server for the room stores the state of the room, comprising:</t>
          <ul spacing="normal">
            <li>
              <t>The <em>base policy</em> of the room, which does not depend on the specific
participants in the room. For example, this includes the room <em>roles</em>
and their permissions (defined in <xref target="I-D.ietf-mimi-room-policy"/> and
<em>preauthorization</em> policy).</t>
            </li>
            <li>
              <t>The <em>participant list</em>: a list of the users who are participants of the
room, and each user's role in the room (defined in <xref target="participant-list"/>).</t>
            </li>
            <li>
              <t>Room metadata, such as the room name, description, and image (defined in
<xref target="room-metadata"/>).</t>
            </li>
          </ul>
          <t>When a client requests key material via the hub, the hub records the
KeyPackageRef values for the returned KeyPackages, and the identity of the
provider from which they were received.  This information is then used to route
Welcome message to the proper provider.</t>
        </section>
        <section anchor="participant-list-changes">
          <name>Participant List Changes</name>
          <t>The participant list can be changed by adding or removing users, or changing
a user's role.  These changes are described as a list of adds, removes, and
role changes, as described in <xref target="participant-list"/>.</t>
          <figure anchor="fig-room-state-change">
            <name>Changing the state of the room</name>
            <artwork type="ascii-art"><![CDATA[
Add: ["mimi://d.example/u/diana", role: 4 (admin)],
     ["mimi://e.example/u/eric", role: 3 (moderator)],
Remove: ["mimi://b.example/u/bob"],
SetRole: [["mimi://c.example/u/cathy", role: 1 (banned)]]
]]></artwork>
          </figure>
          <t>To put these changes into effect, a client or server encodes them in an
AppDataUpdate <xref target="I-D.ietf-mls-extensions"/> proposal, signs the proposal as a
PublicMessage, and submits them to the <tt>update</tt> endpoint on the hub.</t>
        </section>
      </section>
    </section>
    <section anchor="mimi-endpoints-and-framing">
      <name>MIMI Endpoints and Framing</name>
      <t>This section describes the specific endpoints necessary to provide the
functionality in the example flow. The framing for each endpoint includes a
protocol so that different variations of the end-to-end encryption can be used.</t>
      <ul empty="true">
        <li>
          <t><strong>TODO</strong>: Determine the what needs to be included in the protocol. MIMI
  version, e2e protocol version, etc.</t>
        </li>
      </ul>
      <t>The syntax of the MIMI protocol messages are described using the TLS
presentation language format (<xref section="3" sectionFormat="of" target="RFC8446"/>).
Request and response bodies encoded using the structures in this document use
the media type <tt>application/mimi-protocol</tt> (<xref target="iana-media-type"/>).</t>
      <sourcecode type="tls"><![CDATA[
enum {
    reserved(0),
    mls10(1),
    (255)
} Protocol;
]]></sourcecode>
      <section anchor="directory">
        <name>Directory</name>
        <t>Like the ACME protocol (See <xref section="7.1.1" sectionFormat="of" target="RFC8555"/>), the MIMI protocol uses a directory document
to convey the HTTPS URLs used to reach certain endpoints (as opposed to hard
coding the endpoints).</t>
        <t>The directory URL is discovered using the <tt>mimi-protocol-directory</tt> well-known
URI. The response is a JSON document with URIs for each type of endpoint.</t>
        <artwork><![CDATA[
GET /.well-known/mimi-protocol-directory
]]></artwork>
        <artwork><![CDATA[
{
  "keyMaterial":
     "https://mimi.example.com/v1/keyMaterial/{targetUser}",
  "update": "https://mimi.example.com/v1/update/{roomId}",
  "notify": "https://mimi.example.com/v1/notify/{roomId}",
  "submitMessage":
     "https://mimi.example.com/v1/submitMessage/{roomId}",
  "groupInfo":
     "https://mimi.example.com/v1/groupInfo/{roomId}",
  "requestConsent":
     "https://mimi.example.com/v1/requestConsent/{targetDomain}",
  "updateConsent":
     "https://mimi.example.com/v1/updateConsent/{requesterDomain}",
  "identifierQuery":
     "https://mimi.example.com/v1/identifierQuery/{domain}",
  "reportAbuse":
     "https://mimi.example.com/v1/reportAbuse/{roomId}",
  "proxyDownload":
     "https://mimi.example.com/v1/proxyDownload/{downloadUrl}"
}
]]></artwork>
      </section>
      <section anchor="fetch-key-material">
        <name>Fetch Key Material</name>
        <t>This action attempts to claim initial keying material for all the clients
of a single user at a specific provider. The keying material is designed
for use in a single room and may not be reused. It uses the HTTP POST method.</t>
        <artwork><![CDATA[
POST /keyMaterial/{targetUser}
]]></artwork>
        <t>The target user's URI is listed in the request path. KeyPackages
requested using this primitive <bcp14>MUST</bcp14> be sent via the hub provider of whatever
room they will be used in. (If this is not the case, the hub provider will be
unable to forward a Welcome message to the target provider).</t>
        <t>The path includes the target user URI (with any necessary percent-encoding). The
request body includes the protocol (currently just MLS 1.0), and the requesting
user. When the request is being made in the context of adding the target user to
a room, the request <bcp14>MUST</bcp14> include the room ID for which the KeyPackage is
intended, as the target may have only granted consent for a specific room.</t>
        <t>For MLS, the request includes a non-empty list of acceptable MLS ciphersuites.
Next there is an MLS <tt>RequiredCapabilities</tt> object, which contains (possibly
empty) lists of required credential types, non-default proposal types, and
extensions) required by the requesting provider. Next there is a
SignaturePublicKey and a corresponding Credential for the requester. Finally,
the request includes a signature, using the SignaturePublicKey and covering
KeyMaterialRequestTBS.</t>
        <t>The request body has the following form.</t>
        <sourcecode type="tls"><![CDATA[
struct {
    opaque uri<V>;
} IdentifierUri;

struct {
    Protocol protocol;
    IdentifierUri requestingUser;
    IdentifierUri targetUser;
    IdentifierUri roomId;
    select (protocol) {
        case mls10:
            CipherSuite acceptableCiphersuites<V>;
            RequiredCapabilities requiredCapabilities;
            SignaturePublicKey requesterSignatureKey;
            Credential requesterCredential;
            /* SignWithLabel(requesterSignatureKey,              */
            /*   "KeyMaterialRequestTBS", KeyMaterialRequestTBS) */
            opaque key_material_request_signature<V>;
    };
} KeyMaterialRequest;

struct {
    Protocol protocol;
    IdentifierUri requestingUser;
    IdentifierUri targetUser;
    IdentifierUri roomId;
    select (protocol) {
        case mls10:
            CipherSuite acceptableCiphersuites<V>;
            RequiredCapabilities requiredCapabilities;
            SignaturePublicKey requesterSignatureKey;
            Credential requesterCredential;
    };
} KeyMaterialRequestTBS;

key_material_request_signature = SignWithLabel(requesterSignatureKey,
                      "KeyMaterialRequestTBS", KeyMaterialRequestTBS)
]]></sourcecode>
        <t>The response contains a user status code that indicates keying material was
returned for all the user's clients (<tt>success</tt>), that keying material was
returned for some of their clients (<tt>partialSuccess</tt>), or a specific user code
indicating failure. If the user code is success or partialSuccess, each client
is enumerated in the response. Then for each client with a <em>client</em> success
code, the structure includes initial keying material (a KeyPackage for MLS 1.0).
If the client's code is <tt>nothingCompatible</tt>, the client's capabilities are
optionally included (The client's capabilities could be omitted for privacy
reasons.)</t>
        <t>If the <em>user</em> code is <tt>noCompatibleMaterial</tt>, the provider <bcp14>MAY</bcp14> populate the
<tt>clients</tt> list. For any other user code, the provider <bcp14>MUST NOT</bcp14> populate the
<tt>clients</tt> list.</t>
        <t>Keying material provided from one response <bcp14>MUST NOT</bcp14> be provided in any other
response.
The target provider <bcp14>MUST NOT</bcp14> provide expired keying material (ex: an MLS
KeyPackage containing a LeafNode with a <tt>notAfter</tt> time past the current date
and time).</t>
        <sourcecode type="tls"><![CDATA[
enum {
    success(0),
    partialSuccess(1),
    incompatibleProtocol(2),
    noCompatibleMaterial(3),
    userUnknown(4),
    noConsent(5),
    noConsentForThisRoom(6),
    userDeleted(7),
    (255)
} KeyMaterialUserCode;

enum {
    success(0),
    keyMaterialExhausted(1),
    nothingCompatible(2),
    (255)
} KeyMaterialClientCode;


struct {
    KeyMaterialClientCode clientStatus;
    IdentifierUri clientUri;
    select (protocol) {
        case mls10:
            select (clientStatus) {
                case success:
                    KeyPackage keyPackage;
                case nothingCompatible:
                    optional<Capabilities> clientCapabilities;
            };
    };
} ClientKeyMaterial;

struct {
    Protocol protocol;
    KeyMaterialUserCode userStatus;
    IdentifierUri userUri;
    ClientKeyMaterial clients<V>;
} KeyMaterialResponse;
]]></sourcecode>
        <t>The semantics of the <tt>KeyMaterialUserCode</tt> are as follows:</t>
        <ul spacing="normal">
          <li>
            <t><tt>success</tt> indicates that key material was provided for every client of the
target user.</t>
          </li>
          <li>
            <t><tt>partialSuccess</tt> indicates that key material was provided for at least one
client of the target user.</t>
          </li>
          <li>
            <t><tt>incompatibleProtocol</tt> indicates that either one of providers supports the
protocol requested, or none of the clients of the target user support the
protocol requested.</t>
          </li>
          <li>
            <t><tt>noCompatibleMaterial</tt> indicates that none of the clients was able to
supply key material compatible with the <tt>requiredCapabilities</tt> field in the
request.</t>
          </li>
          <li>
            <t><tt>userUnknown</tt> indicates that the target user is not known to the target
provider.</t>
          </li>
          <li>
            <t><tt>noConsent</tt> indicates that the requester does not have consent to fetch
key material for the target user. The target provider can use this response
as a catch all and in place of other status codes such as <tt>userUnknown</tt> if
desired to preserve the privacy of its users.</t>
          </li>
          <li>
            <t><tt>noConsentForThisRoom</tt> indicates that the target user might have allowed
a request for another room, but does not for this room. If the provider
does not wish to make this distinction, it can return <tt>noConsent</tt> instead.</t>
          </li>
          <li>
            <t><tt>userDeleted</tt> indicates that the target provider wishes the requester to
know that the target user was previously a valid user of the system and has
been deleted. A target provider can of course use <tt>userUnknown</tt> if the
provider does wish to keep or specify this distinction.</t>
          </li>
        </ul>
        <t>The semantics of the <tt>KeyMaterialClientCode</tt> are as follows:</t>
        <ul spacing="normal">
          <li>
            <t><tt>success</tt> indicates that key material was provided for the specified
client.</t>
          </li>
          <li>
            <t><tt>keyMaterialExhausted</tt> indicates that there was no keying material
available for the specified client.</t>
          </li>
          <li>
            <t><tt>nothingCompatible</tt> indicates that the specified clients had no key
material compatible with the <tt>requiredCapabilities</tt> field in the request.</t>
          </li>
        </ul>
        <t>At minimum, as each MLS KeyPackage is returned to a requesting provider (on
behalf of a requesting IM client), the target provider needs to associate its
<tt>KeyPackageRef</tt> with the target client and the hub provider needs to associate
its <tt>KeyPackageRef</tt> with the target provider. This ensures that Welcome messages
can be correctly routed to the target provider and client. These associations
can be deleted after a Welcome message is forwarded or after the KeyPackage
<tt>leaf_node.lifetime.not_after</tt> time has passed.</t>
      </section>
      <section anchor="update-room-state">
        <name>Update Room State</name>
        <t>Adds, removes, and policy changes to the room are all forms of updating the
room state. They are accomplished using the update transaction which is used to
update the room base policy, participation list, or its underlying MLS group.
It uses the HTTP POST method.</t>
        <artwork><![CDATA[
POST /update/{roomId}
]]></artwork>
        <t>Any change to the participant list or room policy (including
authorization policy) is communicated via an <tt>AppDataUpdate</tt> proposal for the
<tt>participant_list</tt> component or the room policy components
<xref target="I-D.ietf-mimi-room-policy"/>, respectively. When adding a user, the proposal
containing the participant list change <bcp14>MUST</bcp14> be committed either before or
simultaneously with the corresponding MLS operation.</t>
        <t>Removing an active user from a participant list or banning an active participant
likewise also happen simultaneously with any MLS changes made to the commit removing
the participant.</t>
        <t>A hub provider which observes that an active participant has been removed or
banned from the room, <bcp14>MUST</bcp14> prevent any of its clients from sending or
receiving any additional application messages in the corresponding MLS group;
<bcp14>MUST</bcp14> prevent any of those clients from sending Commit messages in that group;
and <bcp14>MUST</bcp14> prevent it from sending any proposals except for <tt>Remove</tt> and
<tt>SelfRemove</tt> <xref target="I-D.ietf-mls-extensions"/> proposals for its users in that group.</t>
        <t>The update request body is described below, using the
<tt>RatchetTreeOption</tt> and <tt>PartialGroupInfo</tt> structs defined in
<xref target="I-D.ietf-mls-ratchet-tree-options"/>:</t>
        <sourcecode type="tls"><![CDATA[
struct {
  /* A Proposal or Commit which is either a PublicMessage; */
  /* or a SemiPrivateMessage                               */
  MLSMessage proposalOrCommit;
  select (proposalOrCommit.content.content_type) {
    case commit:
      /* Both the Welcome and GroupInfo omit the ratchet_tree */
      optional<Welcome> welcome;
      GroupInfoOption groupInfoOption;
      RatchetTreeOption ratchetTreeOption;
    case proposal:
      /* a list of additional proposals, each represented */
      /* as either PublicMessage or SemiPrivateMessage    */
      MLSMessage moreProposals<V>;
  };
} HandshakeBundle;

enum {
  reserved(0),
  full(1),
  partial(2),
  (255)
} GroupInfoRepresentation;

struct {
   GroupInfoRepresentation representation;
   select (representation) {
     case full:
       GroupInfo groupInfo;
     case partial:
       PartialGroupInfo partialGroupInfo;
   };
} GroupInfoOption;

struct {
  select (room.protocol) {
    case mls10:
      HandshakeBundle bundle;
  };
} UpdateRequest;
]]></sourcecode>
        <t>The semantics of <tt>GroupInfoRepresentation</tt> are as follows:</t>
        <ul spacing="normal">
          <li>
            <t><tt>full</tt> means that the entire GroupInfo will be included.</t>
          </li>
          <li>
            <t><tt>partial</tt> means that a <tt>PartialGroupInfo </tt> struct will be shared and
 that the Distribution Service is expected to reconstruct the GroupInfo
 as described in <xref target="I-D.ietf-mls-ratchet-tree-options"/>.</t>
          </li>
        </ul>
        <t>For example, in the first use case described in the Protocol Overview, Alice creates a Commit
containing an AppDataUpdate proposal adding Bob (<tt>mimi://b.example/u/bob</tt>), and
Add proposals for all Bob's MLS clients.  Alice includes the Welcome message
which will be sent for Bob, a GroupInfo object for the hub provider, and
complete <tt>ratchet_tree</tt> extension.</t>
        <t>A handshake message could be sent by the client as an MLS
<tt>PublicMessage</tt> (which is visible to all providers), or as an MLS
<tt>SemiPrivateMessage</tt> <xref target="I-D.mahy-mls-semiprivatemessage"/> encrypted
for the members and the hub provider as the sole <tt>external_receiver</tt>.
(The contents and sender of a <tt>SemiPrivateMessage</tt> would not be visible to
other providers). The use of <tt>SemiPrivateMessage</tt> allows the Hub to
accomplish its policy enforcement responsibilities without the other
providers being aware of the membership of non-local users.</t>
        <t>The response body is described below:</t>
        <sourcecode type="tls"><![CDATA[
enum {
  success(0),
  wrongEpoch(1),
  notAllowed(2),
  invalidProposal(3),
  (255)
} UpdateResponseCode;

struct {
  UpdateResponseCode responseCode;
  UTF8String errorDescription;
  select (responseCode) {
    case success:
      /* the hub acceptance time (in milliseconds from the UNIX epoch) */
      uint64 accepted_timestamp;
    case wrongEpoch:
      /* current MLS epoch for the MLS group */
      uint64 currentEpoch;
    case invalidProposal:
      ProposalRef invalidProposals<V>;
  };
} UpdateRoomResponse;
]]></sourcecode>
        <t>The semantics of the <tt>UpdateResponseCode</tt> values are as follows:</t>
        <ul spacing="normal">
          <li>
            <t><tt>success</tt> indicates the <tt>UpdateRequest</tt> was accepted and will be distributed.</t>
          </li>
          <li>
            <t><tt>wrongEpoch</tt> indicates that the hub provider is using a different epoch. The
<tt>currentEpoch</tt> is provided in the response.</t>
          </li>
          <li>
            <t><tt>notAllowed</tt> indicates that some type of policy or authorization prevented the
hub provider from accepting the <tt>UpdateRequest</tt>.</t>
          </li>
          <li>
            <t><tt>invalidProposal</tt> indicates that at least one proposal is invalid. A list of
invalidProposals is provided in the response.</t>
          </li>
        </ul>
      </section>
      <section anchor="submit-a-message">
        <name>Submit a Message</name>
        <t>End-to-end encrypted (application) messages are submitted to the hub for
authorization and eventual fanout using an HTTP POST request.</t>
        <artwork><![CDATA[
POST /submitMessage/{roomId}
]]></artwork>
        <t>The request body is as follows:</t>
        <sourcecode type="tls"><![CDATA[
struct {
  Protocol protocol;
  select(protocol) {
    case mls10:
      /* PrivateMessage containing an application message */
      MLSMessage appMessage;
      IdentifierUri sendingUri;
  };
} SubmitMessageRequest;
]]></sourcecode>
        <t>If the protocol is MLS 1.0, the request body (<tt>appMessage</tt>) is an MLSMessage
with a WireFormat of PrivateMessage, and a <tt>content_type</tt> of <tt>application</tt>.
The <tt>sendingUri</tt> is a valid URI of the sender and is an active participant
in the room (a user URI in the participant list of the room).</t>
        <t>The response indicates if the message was accepted by the hub provider. If a
<tt>franking_tag</tt> was included in the <tt>frank_aad</tt> component <xref target="iana-frank-aad"/> in
the PrivateMessage Additional Authenticated Data (AAD) in the request, the
server attempts to frank the message and includes the <tt>server_frank</tt> in a
successful response (see the next subsection).</t>
        <sourcecode type="tls"><![CDATA[
enum {
  accepted(0),
  notAllowed(1),
  epochTooOld(2),
  (255)
} SubmitResponseCode;

struct {
  uint8 server_frank[32];
  CipherSuite franking_signature_ciphersuite;
  opaque franking_integrity_signature<V>;
} Frank;

struct {
  Protocol protocol;
  select(protocol) {
    case mls10:
      SubmitResponseCode statusCode;
      select (statusCode) {
        case accepted:
          /* the hub acceptance time
             (in milliseconds from the UNIX epoch) */
          uint64 accepted_timestamp;
          optional<Frank> frank;
        case epochTooOld:
          /* current MLS epoch for the MLS group */
          uint64 currentEpoch;
      };
  };
} SubmitMessageResponse;
]]></sourcecode>
        <t>The semantics of the <tt>SubmitResponseCode</tt> values are as follows:</t>
        <ul spacing="normal">
          <li>
            <t><tt>accepted</tt> indicates the <tt>SubmitMessageRequest</tt> was accepted and will be distributed.</t>
          </li>
          <li>
            <t><tt>notAllowed</tt> indicates that some type of policy or authorization prevented the
hub provider from accepting the <tt>SubmitMessageRequest</tt>. This could include
nonsensical inputs such as an MLS epoch more recent than the hub's.</t>
          </li>
          <li>
            <t><tt>epochTooOld</tt> indicates that the hub provider is using a new MLS epoch
for the group. The <tt>currentEpoch</tt> is provided in the response.</t>
          </li>
        </ul>
        <ul empty="true">
          <li>
            <t><strong>ISSUE:</strong> Do we want to offer a distinction between regular application
messages and ephemeral applications messages (for example "is typing"
notifications), which do not need to be queued at the target provider.</t>
          </li>
        </ul>
        <section anchor="message-franking">
          <name>Message Franking</name>
          <t>Franking is the placing of a cryptographic "stamp" on a message. In the
MIMI context, the Hub is able to mark that it received a message without
learning the message content. A receiver that decrypts the message can use
a valid frank to prove it was received by the Hub and that the content was
sent by a specific sender. Outsiders (including follower providers) never
learn the content of the message, nor the sender.</t>
          <t>Franking was popularized by Facebook and described in their whitepaper
<xref target="SecretConversations"/> about their end-to-end encryption system. This
franking mechanism is largely motivated by that solution with two
significant changes as discussed in the final paragraph of this section.</t>
          <t>MIMI franking relies on two new MLS application components. The first is the
<tt>frank_aad</tt> Safe AAD component <xref section="4.9" sectionFormat="of" target="I-D.ietf-mls-extensions"/>. The
second is the <tt>franking_agent</tt> GroupContext component <xref section="4.6" sectionFormat="of" target="I-D.ietf-mls-extensions"/>. The structure of <tt>franking_agent</tt> mirrors that of
the <tt>ExternalSender</tt> struct described in <xref section="12.1.8.1" sectionFormat="of" target="RFC9420"/>. It
contains a single signature key.</t>
          <sourcecode type="tls"><![CDATA[
struct {
  uint8 franking_tag[32];
} FrankAAD;

FrankAAD frank_aad;

struct {
  SignaturePublicKey franking_signature_key;
  Credential credential;
} FrankingAgentData;

FrankingAgentData franking_agent;
FrankingAgentData FrankingAgentUpdate;
]]></sourcecode>
          <t>The signature algorithm of the <tt>franking_signature_key</tt> is the same as the
signature algorithm of cipher suite of the MLS group which corresponds to the
room.</t>
          <t>FrankingAgentUpdate is the format of the <tt>update</tt> field inside the AppDataUpdate
struct in an AppDataUpdate Proposal for the <tt>franking_agent</tt> component. The use
of AppDataUpdate on the <tt>franking_agent</tt> is <bcp14>RECOMMENDED</bcp14> only when adding a new
<tt>franking_agent</tt>. To avoid confusion about which signature key to use, when an
MLS client rotates the <tt>franking_agent</tt>, the client <bcp14>SHOULD</bcp14> create a new MLS
group by sending a ReInit proposal.</t>
          <section anchor="client-creation-and-sending">
            <name>Client creation and sending</name>
            <t>The franking mechanism requires any franked message format to contain a random
salt, the sender URI, and the room URI. This section describes the exact way to
extract these fields from the MIMI content format <xref target="I-D.ietf-mimi-content"/>.
Other message formats would need to describe how to locate or derive these
values.</t>
            <t>The MIMI content format includes a per-message, mandatory, cryptographically
random 128-bit salt generated by the sender. (An example mechanism to safely
generate the salt is discussed in Section 8.2 of <xref target="I-D.ietf-mimi-content"/>.)</t>
            <t>The sender of a MIMI content message attaches to the message any fields the
sender wishes to commit that are not otherwise represented in the content. For a
MIMI content object, the sender includes the sender's user URI and room URI in
the MIMI content extensions map (see definitions in <xref section="8.3" sectionFormat="of" target="I-D.ietf-mimi-content"/>).</t>
            <sourcecode type="cbor-diag"><![CDATA[
/ MIMI content extensions map /
{
  / sender_uri / 1: "mimi://b.example/u/alice",
  / room_uri   / 2: "mimi://hub.example/r/Rl33FWLCYWOwxHrYnpWDQg"
}
]]></sourcecode>
            <t>Note that these assertions do not vouch for the validity of these values,
it just means that the sender is claiming it sent the values in the content,
and cannot later deny to a receiver that it sent them.</t>
            <t>Then the client calculates the <tt>franking_tag</tt>, as the HMAC SHA256 of the
<tt>application_data</tt> (which includes the values in the extensions map above)
using the <tt>salt</tt> in the MIMI content format:</t>
            <ul empty="true">
              <li>
                <t>Note that when the content advertisement mechanism in
<xref section="6.2" sectionFormat="of" target="I-D.ietf-mls-extensions"/> is used, the <tt>application_data</tt> includes the
<tt>media_type</tt> in the <tt>ApplicationFraming</tt> struct.</t>
              </li>
            </ul>
            <artwork><![CDATA[
franking_tag = HMAC_SHA256( salt, application_data)
]]></artwork>
            <t>The client includes the <tt>franking_tag</tt> in the Additional Authenticated Data
of the MLS PrivateMessage using the <tt>frank_aad</tt> Safe AAD component. The client
uses the MIMI submitMessage to send its message, and also asserts a sender
identity to the Hub, which could be a valid pseudonym, and needs to match
the sender URI value embedded in the message. If the message is accepted,
the response includes the accepted timestamp and the server_frank (generated
by the server).</t>
          </section>
          <section anchor="hub-processing">
            <name>Hub processing</name>
            <t>When a valid <tt>franking_agent</tt> application component <xref target="iana-franking-sig-key"/> is
present in the GroupContext, the Hub can frank messages, and sign the frank with
the Hub's <tt>franking_private_key</tt> corresponding to the <tt>franking_signature_key</tt>
in the FrankingAgentData struct.</t>
            <t>When the Hub receives an acceptable application message with the <tt>frank_aad</tt>
Safe AAD component and a valid sender identity, it calculates a server frank for
the message, and a <tt>franking_integrity_signature</tt> as follows:</t>
            <sourcecode type="tls"><![CDATA[
struct {
    IdentifierUri sender_uri;
    IdentifierUri room_uri;
    uint64 accepted_timestamp;
} ServerFrankingContext;

ServerFrankingContext context;

server_frank = HMAC_SHA256(hub_key, (franking_tag || context) )

struct {
    opaque server_frank[32];
    CipherSuite franking_signature_ciphersuite;
    ServerFrankingContext context;
} FrankingIntegrityTBS;

franking_integrity_signature = SignWithLabel(franking_private_key,
    "FrankingIntegrityTBS", FrankingIntegrityTBS)
]]></sourcecode>
            <t><tt>hub_key</tt> is a secret symmetric key used on the Hub which the Hub can use to
verify its own <tt>server_frank</tt>.</t>
            <t>The <tt>franking_integrity_signature</tt> is used by receivers to verify that the
values added by the Hub (the <tt>server_frank</tt>, and <tt>accepted_timestamp</tt>) were not
modified by a follower provider, and that the <tt>sender_uri</tt> and <tt>room_uri</tt> match
those provided by the sending client.
The <tt>franking_signature_ciphersuite</tt> is the MLS cipher suite in use at the time
the message is franked. It is used to insure that a frank contains the
signature algorithm used to generate the <tt>franking_integrity_signature</tt>.
The specific construction used is discussed in the Security Considerations
in <xref target="franking"/>.</t>
            <t>The Hub fans out the encrypted message (which includes the <tt>franking_tag</tt>),
the <tt>server_frank</tt>, the <tt>accepted_timestamp</tt>, the room URI, the
<tt>franking_signature_ciphersuite</tt> and the <tt>franking_integrity_signature</tt>.
Note that the <tt>sender_uri</tt> is encrypted in the application message, so the
sender can remain anonymous with respect to follower providers.</t>
          </section>
          <section anchor="receiver-verification-of-frank">
            <name>Receiver verification of frank</name>
            <t>When a client receives and decrypts an otherwise valid application message
from a hub provider, the client looks for the existence of a frank
(consisting of the <tt>franking_tag</tt> in the AAD, the <tt>server_frank</tt>, the
<tt>franking_signature_ciphersuite</tt> and the <tt>franking_integrity_signature</tt>). If
those fields are available, and the <tt>franking_signature_ciphersuite</tt> matches the
MLS cipher suite in-use, the client looks for the <tt>franking_agent</tt>
application component in the GroupContext. It verifies the domain name in the
<tt>franking_agent.credential</tt> corresponds to the domain of the Hub, and extracts
the <tt>franking_signature_key</tt>.</t>
            <t>Next it verifies the integrity of the <tt>server_frank</tt>, <tt>accepted_timestamp</tt>,
<tt>sender_uri</tt>, and <tt>room_uri</tt> by calculating the <tt>ServerFrankingContext</tt> and
<tt>FrankingIntegrityTBS</tt>, and verifying the <tt>franking_integrity_signature</tt> as
described below.</t>
            <artwork><![CDATA[
VerifyWithLabel(franking_signature_key, "FrankingIntegrityTBS",
     FrankingIntegrityTBS, franking_integrity_signature)
]]></artwork>
            <t>Finally it verifies the construction of the <tt>franking_tag</tt> from the content
format of the message (including the embedded <tt>salt</tt>),
that the sender's identity in its credential in its MLS LeafNode matches
the <tt>sender_uri</tt> asserted in the extensions map inside the MIMI Content, and
that the <tt>room_uri</tt> asserted in the extensions map inside the MIMI Content
matches the room ID in the received message.</t>
            <t>The receiver needs to store the <tt>server_frank</tt>,
<tt>franking_signature_ciphersuite</tt>, <tt>franking_integrity_signature</tt>, and <tt>context</tt>
fields with the decoded message, so they can be used later.</t>
          </section>
          <section anchor="comparison-with-the-facebook-franking-scheme">
            <name>Comparison with the Facebook franking scheme</name>
            <t>Unlike in the Facebook franking scheme <xref target="SecretConversations"/>, the MIMI
use case involves traffic which can transit multiple federated providers,
any of which may be compromised or malicious. The MIMI franking scheme
described here differs in the following ways.</t>
            <t>Firstly, the sender includes its <tt>franking_tag</tt> application component as
Additional Authenticated Data (AAD) inside the end-to-end encrypted message.
This insures that the <tt>franking_tag</tt> is not tampered with by the sender's
provider. According to <xref target="Grubbs2017"/>,
"... [Facebook's] franking scheme does not bind [the franking tag] to [the
ciphertext] by including [the franking tag] in the associated data during
encryption".</t>
            <t>In MLS, the Hub cannot view the sender identity in an application message,
so the sender sends its identity to the Hub. The hub never sends the
identity of the sender to receivers, since this would be observed by
follower providers. However, the receiver needs to verify that the sender
identity provided by the sender's provider to the Hub matches the identity
the receiver sees after it decrypts the message. Using the
<tt>franking_integrity_signature</tt> generated by the Hub, receivers can verify the
message context (sender identity, room id, and timestamp) and the server_frank
with the <tt>franking_signature_key</tt> in the <tt>franking_agent</tt> component in the
GroupContext.
This second change provides two functions. It allows receivers to
validate the <tt>sender_uri</tt> in the hub's context, without revealing the sender URI
to follower providers. It also prevents a follower provider from modifying the
server_frank, or any elements of the context (ex: modifying the
<tt>accepted_timestamp</tt>) without detection. A valid signature ensures
that follower providers did not tamper with the context or the server_frank.</t>
          </section>
        </section>
      </section>
      <section anchor="fanout-messages-and-room-events">
        <name>Fanout Messages and Room Events</name>
        <t>If the hub provider accepts an application or handshake message (proposal or
commit) message, it forwards that message to all other providers with active
participants in the room and all local clients which are active members.
This is described as fanning the message out. One can think of fanning a
message out as presenting an ordered list of MLS-protected events to the next
"hop" toward the receiving client.</t>
        <t>An MLS Welcome message is sent to the providers and local users associated with
the <tt>KeyPackageRef</tt> values in the <tt>secrets</tt> array of the Welcome. In the case
of a Welcome message, a <tt>RatchetTreeOption</tt>
(see Section 3 of <xref target="I-D.ietf-mls-ratchet-tree-options"/>) is also included
in the FanoutMessage.</t>
        <t>The hub provider also fans out any messages which originate from itself (ex: MLS
External Proposals).</t>
        <ul empty="true">
          <li>
            <t>An external commit will invalidate certain pending proposals. For example, if
the hub generates Remove proposals to remove a lost client or a deleted user,
an external commit can invalidate pending Remove proposals. The hub would then
be expected to regenerate any relevant, comparable proposals in the new epoch.
To prevent a race condition where a member commit arrives before the
regenerated proposals arrive, the hub can staple regenerated proposals to an
external commit during the fanout process.</t>
          </li>
        </ul>
        <t>The hub can include multiple concatenated <tt>FanoutMessage</tt> objects relevant to
the same room. This endpoint uses the HTTP POST method.</t>
        <artwork><![CDATA[
POST /notify/{roomId}
]]></artwork>
        <sourcecode type="tls"><![CDATA[
struct {
  /* the hub acceptance time (in milliseconds from the UNIX epoch) */
  uint64 timestamp;
  select (protocol) {
    case mls10:
      /* A PrivateMessage containing an application message, */
      /* a SemiPrivateMessage or PublicMessage containing a  */
      /* proposal or commit, or a Welcome message.           */
      MLSMessage message;
      select (message.wire_format) {
        case application:
           optional<Frank> frank;
        case welcome:
           RatchetTreeOption ratchetTreeOption;
        case proposal:
           /* a list of additional proposals, each represented */
           /* as either PublicMessage or SemiPrivateMessage    */
           MLSMessage moreProposals<V>;
        case commit:
           /* If this was an external commit, and any pending      */
           /* proposals were invalidated, staple the new epoch's   */
           /* replacement proposals (from the hub) to the commit   */
           /* commit */
           MLSMessage externalProposals<V>;
      };
  };
} FanoutMessage;
]]></sourcecode>
        <ul empty="true">
          <li>
            <t><strong>NOTE:</strong> Correctly fanning out Welcome messages relies on the hub and target
providers storing the <tt>KeyPackageRef</tt> of claimed KeyPackages.</t>
          </li>
        </ul>
        <t>A client which receives a <tt>success</tt> to either an <tt>UpdateRoomResponse</tt> or a
<tt>SubmitMessageResponse</tt> can view this as a commitment from the hub provider that
the message will eventually be distributed to the group. The hub is not
expected to forward the client's own message to the client or its provider.
However, the client and its provider need to be prepared to receive the
client's (effectively duplicate) message. This situation can occur during
failover in high availability recovery scenarios. This exemption for the
client's own message does not apply to a Welcome message, which the hub sends
to every provider associated with a <tt>KeyPackageRef</tt> in its <tt>secrets</tt> array,
including the provider of the client that submitted it.</t>
        <t>Clients that are being removed <bcp14>SHOULD</bcp14> receive the corresponding
Commit message, so they can recognize that they have been removed and clean up
their internal state. A removed client might not receive a commit if it was
removed as a malicious or abusive client, or if it was obviously deleted.</t>
        <t>The <tt>moreProposals</tt> list in a <tt>FanoutMessage</tt> <bcp14>MUST</bcp14> be the same as the
corresponding <tt>moreProposals</tt> list in the <tt>HandshakeBundle</tt> of an
<tt>UpdateRequest</tt>.</t>
        <t>The hub of a room is the provider identified by the <tt>authority</tt> of the
room's MIMI URI. A provider that receives a <tt>/notify/{roomId}</tt> request <bcp14>MUST</bcp14>
verify that the source provider authenticated by the transport layer (see
<xref target="transport-layer"/>) corresponds to the hub of <tt>roomId</tt>. If it is not, the
receiving provider <bcp14>MUST</bcp14> reject the request and <bcp14>MUST NOT</bcp14> process, store, or
forward any FanoutMessage it carries.</t>
        <t>The response to a FanoutMessage contains no body. The HTTP response code
indicates if the messages in the request were accepted (201 response code), or
if there was an error. The hub need not wait for a response before sending the
next fanout message.</t>
        <t>If the hub server does not contain an HTTP 201 response code, then it <bcp14>SHOULD</bcp14>
retry the request, respecting any guidance provided by the server in HTTP header
fields such as Retry-After.  If a follower server receives a duplicate request
to the <tt>/notify</tt> endpoint, in the sense of a request from the same hub server
with the same request body as a previous <tt>/notify</tt> request, then the follower
server <bcp14>MUST</bcp14> return a 201 Accepted response.  In such cases, the follower server
<bcp14>SHOULD</bcp14> process only the first request; subsequent duplicate requests <bcp14>SHOULD</bcp14> be
ignored (despite the success response).</t>
        <ul empty="true">
          <li>
            <t><strong>NOTE:</strong> These deduplication provisions require follower servers to track
which request bodies they have received from which hub servers.  Since the
matching here is byte-exact, it can be done by keeping a rolling list of
hashes of recent messages.</t>
            <t>This byte-exact replay criterion might not be the right deduplication
strategy.  There might be situations where it is valid for the same hub server
to send the same payload multiple times, e.g., due to accidental collisions.</t>
            <t>If this is a concern, then an explicit transaction ID could be introduced.
The follower server would still have to keep a list of recently seen
transaction IDs, but deduplication could be done irrespective of the content
of request bodies.</t>
          </li>
        </ul>
      </section>
      <section anchor="claim-group-key-information">
        <name>Claim group key information</name>
        <t>When a client joins an MLS group without an existing member adding the
client to the MLS group, that is called an external join. This is useful
a) when a new client of an existing user needs to join the groups of all the
user's rooms. It can also be used b) when a client did not have key packages
available but their user is already in the participation list for the
corresponding room, c) when joining an open room, or d) when joining using
an external authentication joining code. In MIMI, external joins are
accomplished by fetching the MLS GroupInfo for a room's MLS group, and then
sending an external commit incorporating the GroupInfo.</t>
        <t>The GroupInfoRequest uses the HTTP POST method.</t>
        <artwork><![CDATA[
POST /groupInfo/{roomId}
]]></artwork>
        <t>The request provides an MLS credential proving the requesting client's real or
pseudonymous identity. This user identity is used by the hub to correlate this
request with the subsequent external commit. The credential may constitute
sufficient permission to authorize providing the GroupInfo and later joining
the group. Alternatively, the request can include an optional opaque joining
code, which the requester could use to prove permission to fetch the GroupInfo,
even if it is not yet a participant.</t>
        <t>The request also
provides a signature public key
corresponding to the requester's credential. It also specifies a CipherSuite
which merely needs to be one ciphersuite in common with the hub. It is
needed only to specify the algorithms used to sign the
GroupInfoRequest and GroupInfoResponse.</t>
        <sourcecode type="tls"><![CDATA[
struct {
  Protocol protocol;
  select (protocol) {
    case mls10:
      CipherSuite cipher_suite;
      SignaturePublicKey requestingSignatureKey;
      Credential requestingCredential;
      HPKEPublicKey groupInfoPublicKey;
      optional opaque joiningCode<V>;
  };
} GroupInfoRequestTBS;

struct {
  Protocol protocol;
  select (protocol) {
    case mls10:
      CipherSuite cipher_suite;
      SignaturePublicKey requestingSignatureKey;
      Credential requestingCredential;
      HPKEPublicKey groupInfoPublicKey;
      opaque joiningCode<V>;
      /* SignWithLabel(requestingSignatureKey,          */
      /*    "GroupInfoRequestTBS", GroupInfoRequestTBS) */
      opaque signature<V>;
  };
} GroupInfoRequest;
]]></sourcecode>
        <t>If successful, the response body contains the GroupInfo, a way to get the
<tt>ratchet_tree</tt>, and a list of any pending proposals for the epoch, all
encrypted with the <tt>groupInfoPublicKey</tt> passed in the request.</t>
        <sourcecode type="tls"><![CDATA[
enum {
  reserved(0),
  success(1),
  notAuthorized(2),
  noSuchRoom(3),
  (255)
} GroupInfoCode;

struct {
    MLSMessage proposal;
    uint64 hub_accepted_time;
} PendingProposal;

struct {
  GroupInfo groupInfo;   /* without embedded ratchet_tree */
  RatchetTreeOption ratchetTreeOption;
  /* A list of valid pending proposals accepted by the hub */
  /* during the current epoch                              */
  PendingProposal pending_proposals<V>;
} GroupInfoRatchetTreeTBE;

GroupInfoRatchetTreeTBE group_info_ratchet_tree_tbe;

encrypted_groupinfo_and_tree = EncryptWithLabel(
  groupInfoPublicKey,
  "GroupInfo and ratchet_tree encryption",
  room_id,                         /* context */
  group_info_ratchet_tree_tbe)

struct {
  Protocol protocol;
  opaque room_id<V>;
  GroupInfoCode status;
  select (protocol) {
    case mls10:
      CipherSuite cipher_suite;
      ExternalSender hub_sender;
      HPKECiphertext encrypted_groupinfo_and_tree;
  };
} GroupInfoResponseTBS;

struct {
  Protocol protocol;
  opaque room_id<V>;
  GroupInfoCode status;
  select (status) {
    case success:
      select (protocol) {
        case mls10:
          CipherSuite cipher_suite;
          ExternalSender hub_sender;
          HPKECiphertext encrypted_groupinfo_and_tree;
          /* SignWithLabel(hub_sender.signature_key,        */
          /*  "GroupInfoResponseTBS", GroupInfoResponseTBS) */
          opaque signature<V>;
      };
  default: struct{};
  };
} GroupInfoResponse;
]]></sourcecode>
        <t>The semantics of the <tt>GroupInfoCode</tt> are as follows:</t>
        <ul spacing="normal">
          <li>
            <t><tt>success</tt> indicates that GroupInfo and ratchet tree was provided as
requested.</t>
          </li>
          <li>
            <t><tt>notAuthorized</tt> indicates that the requester was not authorized to access
the GroupInfo.</t>
          </li>
          <li>
            <t><tt>noSuchRoom</tt> indicates that the requested room does not exist. If the hub
does not want to reveal if a room ID does not exist it can use
<tt>notAuthorized</tt> instead.</t>
          </li>
        </ul>
        <ul empty="true">
          <li>
            <t><strong>TODO</strong>: Consider adding additional failure codes/semantics for joining
codes (ex: code expired, already used, invalid)</t>
          </li>
        </ul>
        <t><strong>ISSUE</strong>: What security properties are needed to protect a
GroupInfo object in the MIMI context are still under discussion. It is
possible that the requester only needs to prove possession of their private
key. The GroupInfo in another context might be sufficiently sensitive that
it should be encrypted from the end client to the hub provider (unreadable
by the local provider).</t>
      </section>
      <section anchor="convey-explicit-consent">
        <name>Convey explicit consent</name>
        <t>As discussed in <xref target="consent"/>, there are many ways that a provider could
implicitly determine consent. This section describes a mechanism by which
providers can explicitly request consent from a user of another provider,
cancel such a request, convey that consent was granted, or convey that
consent was revoked or preemptively denied.</t>
        <t>Since they are not necessarily in the context of a room, consent requests
are sent directly from the provider of the user requesting consent, to the
provider of the target user. (There is no concept of a hub outside of the
context of a room.)</t>
        <artwork><![CDATA[
POST /requestConsent/{targetDomain}
POST /updateConsent/{requesterDomain}
]]></artwork>
        <t>A <tt>requestConsent</tt> request is used by one provider to request explicit
consent from a target user at another provider to fetch the target's
KeyPackages (which is a prerequisite for adding the target to a group); or
to cancel that request.
The request body is a <tt>ConsentEntry</tt>, with a <tt>consentOperation</tt> of <tt>request</tt>
or <tt>cancel</tt> respectively. It includes the URI of requesting user in the
<tt>requesterUri</tt> and the target user URI in the <tt>targetUri</tt>. If consent is only
requested for a single room, the requester includes the <tt>roomId</tt>. The
combination of the <tt>requesterUri</tt>, <tt>targetUri</tt>, and optional <tt>roomId</tt>
represents the <tt>ConsentScope</tt>. A <tt>cancel</tt> <bcp14>MUST</bcp14> use the same <tt>ConsentScope</tt>
as a previous <tt>request</tt>.</t>
        <t>For a <tt>requestConsent</tt>, the <tt>targetUri</tt> needs to be in one of the domains of
the receiving provider, and the <tt>requesterUri</tt> needs to be in one of the
domains of the sending provider.</t>
        <t>The response to a <tt>requestConsent</tt> request is usually a 201 Accepted
(indicating the <tt>requestConsent</tt> was received), optionally a 404 Not Found
(indicating the <tt>targetUri</tt> is unknown), or a 500-class response. The
201 response code merely indicates that the request was received. A provider
that does not wish to reveal if a user is not found can respond with a 201
Accepted. Likewise in response to a <tt>cancel</tt> which has no <tt>request</tt> matching the
The response to a <tt>requestConsent</tt> request is usually a 202 Accepted
(indicating the <tt>requestConsent</tt> was received), optionally a 404 Not Found
(indicating the <tt>targetUri</tt> is unknown), or a 500-class response. The
202 response code merely indicates that the request was received. A provider
that does not wish to reveal if a user is not found can respond with a 202
Accepted. Likewise in response to a <tt>cancel</tt> which has no <tt>request</tt> matching the
<tt>ConsentScope</tt>, a 202 Accepted is sent and no further action is taken.
A <tt>requestConsent</tt> whose <tt>consentOperation</tt> is not <tt>request</tt> or <tt>cancel</tt> gets a
422 Unprocessable Content response.</t>
        <sourcecode type="tls"><![CDATA[
enum {
  cancel(0),
  request(1),
  grant(2),
  revoke(3),
  (255)
} ConsentOperation;

struct {
  ConsentOperation consentOperation;
  IdentifierUri requesterUri;
  IdentifierUri targetUri;
  optional<IdentifierUri> roomId;
  select (consentOperation) {
      case grant:
          KeyPackage clientKeyPackages<V>;
  };
  AppDataDictionary consent_extensions;
} ConsentEntry;

struct {
  IdentifierUri requesterUri;
  IdentifierUri targetUri;
  optional<IdentifierUri> roomId;
} ConsentScope;
]]></sourcecode>
        <t>An <tt>updateConsent</tt> request is used by one provider to provide explicit
notice from a target user at one provider that consent for a specific
"requester" was granted, revoked, or preemptively denied. In this context,
the requester is the party that will later request KeyPackages for the target. The request body is
a <tt>ConsentEntry</tt>, with a <tt>consentOperation</tt> of <tt>grant</tt> (for a grant), or
<tt>revoke</tt> for revocation or denial. Like a request, it includes the URI of the
"requesting user" in the <tt>requesterUri</tt> and the target user URI in the
<tt>targetUri</tt>. If consent is only granted or denied for a single room, the request includes the optional <tt>roomId</tt>.</t>
        <t>A <tt>grant</tt> or <tt>revoke</tt> does not need to be in response to an explicit request,
nor does the <tt>ConsentScope</tt> need to match a previous <tt>request</tt> for the same
<tt>targetUri</tt> and <tt>requesterUri</tt> pair.</t>
        <t>For example, in some systems there is a notion of a bilateral connection
request. The party that initiates the connection request (for example Alice)
would send a <tt>requestConsent</tt> for the target (ex: Bob), and send an
unsolicited <tt>updateConsent</tt> with Bob as the "requester" and itself (Alice)
as the target.</t>
        <t>In a <tt>grant</tt>, the sender includes a list of <tt>clientKeyPackages</tt> for the
target user, which can be empty. For the case of a bilateral connection,
a grant of consent with a matching <tt>ConsentScope</tt> often results in an
immediate Add to a group. If the list is non-empty this reduces the
number of messages which need to be sent.</t>
        <t>For <tt>updateConsent</tt> the <tt>requesterUri</tt> needs to be in one of the domains of
the receiving provider, and the <tt>targetUri</tt> needs to be in one of the
domains of the sending provider.</t>
        <t>The response to an <tt>updateConsent</tt> is usually a 201 Accepted (indicating
the <tt>updateConsent</tt> was received), optionally a 404 Not Found (indicating the
<tt>requesterUri</tt> is unknown), or a 500-class response. The response code
merely indicates that the request was received. A provider that does not
The response to an <tt>updateConsent</tt> is usually a 202 Accepted (indicating
the <tt>updateConsent</tt> was received), optionally a 404 Not Found (indicating the
<tt>requesterUri</tt> is unknown), or a 500-class response. The response code
merely indicates that the request was received. A provider that does not
wish to reveal if a user is not found can respond with a 202 Accepted.
An <tt>updateConsent</tt> whose <tt>consentOperation</tt> is not <tt>grant</tt> or <tt>revoke</tt> gets a
422 Unprocessable Content response.</t>
        <ul empty="true">
          <li>
            <t><strong>NOTE</strong>: Revoking consent for a user might be privacy sensitive. If this
is the case the target provider does not need to send a <tt>revoke</tt> to inform
the requester provider.</t>
          </li>
        </ul>
        <t>The <tt>consent_extensions</tt> field is an AppDataDictionary; it is an extension point that borrows the same syntax as the app_data_dictionary MLS extension in <xref section="4.6" sectionFormat="of" target="I-D.ietf-mls-extensions"/>.</t>
      </section>
      <section anchor="find-internal-address">
        <name>Find internal address</name>
        <t>The identifier query is to find the internal URI for a specific user on a
specific provider. It is only sent from the local provider to the target
provider (it does not transit a hub).</t>
        <t>Note that this POST request is
idempotent and safe in the sense defined by <xref section="9.2.2" sectionFormat="of" target="RFC9110"/>.</t>
        <artwork><![CDATA[
POST /identifierQuery/{domain}
]]></artwork>
        <t>Consider three users Xavier, Yolanda, and Zach all with accounts on provider
XYZ. Xavier is a sales person and wants to be contactable easily by
potential clients on the XYZ provider. He configures his profile on XYZ so
that searching for his first or last name or handle will find his profile
and allow Alice to send him a consent request (it is out of scope how
Alice verifies she has found the intended Xavier and not a different
Xavier or an impostor).
Yolanda has her XYZ handle on her business cards and the email signature
she uses with clients. She configures her profile so that a query for her
exact handle will find her profile and allow Alice to send her a consent
request. Zach does not wish to be queryable at all. He has configured his
account so even an exact handle search returns no results. He could still
send a join link out-of-band to Alice for her to join a room of Zach's
choosing.</t>
        <t>The request body is described as below. Each request can contain multiple
query elements, which all have to match for the request to match (AND
semantics). For example matching both the OpenID Connect (OIDC) <xref target="OidcCore"/>
          <tt>given_name</tt> and <tt>family_name</tt>, or matching the OIDC <tt>given_name</tt> and the
organization (from the vCard <xref target="RFC6350"/> ORG property).</t>
        <t>The <tt>id_request_extensions</tt> field is an extension point using AppDataDictionary-style components.</t>
        <sourcecode type="tls"><![CDATA[
enum {
  reserved(0),
  handle(1),
  nick(2),
  email(3),
  phone(4),
  partialName(5),
  wholeProfile(6),
  oidcStdClaim(7),
  vcardField(8),
  (255)
} SearchIdentifierType;

struct {
  SearchIdentifierType searchType;
  select(searchType) {
    case oidcStdClaim:
      opaque claimName<V>;
    case vcardField:
      opaque propertyName<V>;
  };
  opaque searchValue<V>;  /* a UTF8 string */
} QueryElement;

struct {
  QueryElement query_elements<V>;
  AppDataDictionary id_request_extensions;
} IdentifierRequest;
]]></sourcecode>
        <t>The semantics of the <tt>SearchIdentifierType</tt> values are as follows. <tt>handle</tt>
means that the entire handle URI matches exactly (for example:
<tt>im:alice.smith@a.example</tt>). <tt>nick</tt> means that the nickname or handle
user part matches exactly (for example: <tt>alice.smith</tt>). The same account or
human user may have multiple values which all match the <tt>nick</tt> field. <tt>email</tt>
means the <tt>addr-spec</tt> production from <xref target="RFC5322"/> matches the query string
exactly, for example (<tt>asmith@a.example</tt>). <tt>phone</tt> means the international
format of a telephone number with the "+" prefix matches exactly (for example:
<tt>+12125551212</tt>).</t>
        <t><tt>partialName</tt> means that the query string matches a case-insensitive substring
of any field which contains the name of a (usually human) user. For example,
<tt>mat</tt> would match first (given) or middle names Matt, Matthew, Mathias, or
Mathieu and last (family) names of Mather and Matali. <tt>wholeProfile</tt> means that
the query string matches a substring of any searchable field in
a user's profile.</t>
        <t><tt>oidcStdClaim</tt> means that the query string exactly matches the specified
UserInfo Standard Claim (defined in Section 5.1 of <xref target="OidcCore"/>).
<tt>vcardField</tt> means that the query string exactly matches the specified vCard
property listed in the vCard Properties IANA registry.</t>
        <t>As noted above, searches only return results for a user when the fields searched
are searchable according the user's and provider's search policies.</t>
        <t>The response body is described as an <tt>IdentifierResponse</tt>. It can contain
multiple matches depending on the type of query and the policy of the target
provider.</t>
        <t>The response contains a code indicating the status of the query. <tt>success</tt>
means that at least one result matched the query. <tt>notFound</tt> means that
while the request was acceptable, no results matched the query.
<tt>ambiguous</tt> means that a field (ex: handle) or combination of fields
(ex: first and last name) need to match exactly for the provider to return
any responses. <tt>forbidden</tt> means that use of this endpoint is not allowed
by the provider or that an unspecified field or combination of fields is
not allowed in an identifier query. <tt>unsupportedField</tt> means that the
provider does not support queries on one of the fields queried.</t>
        <t>The <tt>id_response_extensions</tt> field is an extension point using AppDataDictionary-style components.</t>
        <sourcecode type="tls"><![CDATA[
enum {
  success(0),
  notFound(1),
  ambiguous(2),
  forbidden(3),
  unsupportedField(4),
  (255)
} IdentifierQueryCode;

enum {
  reserved(0),
  oidcStdClaim(7),
  vcardField(8),
  (255)
} FieldSource;

struct {
  FieldSource fieldSource;
  UTF8String fieldName;
  opaque fieldValue<V>;
} ProfileField;

struct {
  IdentifierUri stableUri;
  ProfileField fields<V>;
} UserProfile;

struct {
  IdentifierQueryCode responseCode;
  IdentifierUri uri<V>;
  UserProfile foundProfiles<V>;
  AppDataDictionary id_response_extensions;
} IdentifierResponse;
]]></sourcecode>
        <ul empty="true">
          <li>
            <t><strong>TODO</strong>: The format of specific identifiers is discussed in
<xref target="I-D.mahy-mimi-identity"/>. Any specific conventions which are needed
should be merged into this document.</t>
          </li>
        </ul>
      </section>
      <section anchor="report-abuse">
        <name>Report abuse</name>
        <t>Abuse reports are only sent to the hub provider. They are sent as an HTTP
POST request.</t>
        <artwork><![CDATA[
POST /reportAbuse/{roomId}
]]></artwork>
        <t>The <tt>reportingUser</tt> optionally contains the identity of the user sending the
<tt>abuseReport</tt>, while the <tt>allegedAbuserUri</tt> contains the URI of the alleged
sender of abusive messages. The <tt>reasonCode</tt> is reserved to identify the type of
abuse, and the <tt>note</tt> is a UTF8 human-readable string, which can be empty.</t>
        <ul empty="true">
          <li>
            <t><strong>TODO</strong>: Find a standard taxonomy of reason codes to reference for
the <tt>AbuseType</tt>. The IANA Messaging Abuse Report Format parameters are
insufficient.</t>
          </li>
        </ul>
        <t>Finally, abuse reports can optionally contain a handful of allegedly
<tt>AbusiveMessage</tt>s, each of which contains an allegedly abusive
<tt>message_content</tt>, its <tt>server_frank</tt>, its <tt>franking_signature_ciphersuite</tt>,
its <tt>franking_integrity_signature</tt>, and its <tt>accepted_timestamp</tt>.</t>
        <sourcecode type="tls"><![CDATA[
struct {
  /* the message content (ex: MIMI Content message) containing */
  /* allegedly abusive content                                 */
  opaque message_content<V>;
  Frank frank;
  uint64 accepted_timestamp;
} AbusiveMessage;

enum {
  reserved(0),
  (255)
} AbuseType;

struct {
  IdentifierUri reportingUser;
  IdentifierUri allegedAbuserUri;
  AbuseType reasonCode;
  opaque note<V>;
  AbusiveMessage messages<V>;
  AppDataDictionary abuse_extensions;
} AbuseReport;
]]></sourcecode>
        <t>There is no response body. The response code only indicates if the abuse report
was accepted, not if any specific automated or human action was taken.</t>
        <t>To validate an allegedly AbusiveMessage, the hub finds the salt, sender URI, and
room URI inside the <tt>message_content</tt> and the <tt>accepted_timestamp</tt> to
recalculate the <tt>franking_tag</tt> and <tt>context</tt>. Then the hub selects its relevant
<tt>hub_key</tt> to regenerate the <tt>server_frank</tt>. Finally the hub verifies its
<tt>franking_integrity_signature</tt> using the signature algorithm embedded in the
<tt>franking_signature_ciphersuite</tt>.</t>
        <t>The <tt>abuse_extensions</tt> field is an extension point using AppDataDictionary-style components.</t>
      </section>
      <section anchor="download-files">
        <name>Download Files</name>
        <t>IM systems make extensive use of inline images, videos, and sounds, and often
include attached files, all of which will be referred to as "assets" in this
section. Assets are stored (encrypted) on various external servers, and
typically uploaded and fetched using HTTP <xref target="RFC9110"/> protected with TLS
<xref target="RFC8446"/>.</t>
        <ul empty="true">
          <li>
            <t>In a MIMI content <xref target="I-D.ietf-mimi-content"/> message, the download URI is an
<tt>https</tt> URL conveyed in the <tt>uri</tt> field in an <tt>ExternalPart</tt> in a MIMI
content message.</t>
          </li>
        </ul>
        <t>Broadly, two approaches are possibly for storage of assets in federated IM
systems. In the vast majority of deployed systems, the assets are uploaded to
the local provider of the uploader. With the other approach, the assets are
uploaded to the equivalent of the Hub system. MIMI is capable of asset
downloads for both of these approaches.</t>
        <t>The client consults the intersection of the room policy and its local policy to
determine if and how to upload assets, where to upload them, and with which
credentials. The details of the upload process are out of scope of this
document.</t>
        <t>The MIMI room policy <xref target="I-D.ietf-mimi-room-policy"/> in the group's GroupContext
includes an <tt>asset_policy</tt> component that specifies which domain name to use
for asset download for each potential asset provider. This prevents the
download proxy from using a host part associated with the same domain that is
not used for the storage of MIMI assets.</t>
        <t>For downloads, the clients can use any of three methods to download assets. The
hub is not involved in the first and is required to implement support for the
other two methods.</t>
        <section anchor="direct-download">
          <name>Direct download</name>
          <t>Without any additional MIMI protocol mechanism, MIMI clients can download assets
directly from the asset provider. Unfortunately this usually reveals sensitive
private information about the client. In this case, the asset provider learns
the IP address of the client, and timing information about when assets are
downloaded, which is strongly linked with online presence. The asset provider
can correlate other clients downloading the same assets and infer which clients
are in which rooms. For this reason, direct client downloads of assets,
especially from an asset provider which is not the download client's provider,
are <bcp14>NOT RECOMMENDED</bcp14>.</t>
        </section>
        <section anchor="download-using-a-hub-proxy">
          <name>Download using a hub proxy</name>
          <t>The hub offers the <tt>proxyDownload</tt> endpoint to proxy asset requests from
downloading providers to known asset providers. This allows clients to hide
their IP addresses from the asset provider (and the hub), although the hub and
the downloading provider are still privy to the request.</t>
          <t>The <tt>proxyDownload</tt> endpoint includes the target asset URL, but does not include
the specific room or requester. When the provider hosting the asset has several
rooms hosted by the hub, the provider also does not directly learn with which
room to associate a specific asset.</t>
          <t>As with other MIMI protocol endpoints, the actual endpoint URL is discovered
using the MIMI protocol directory <xref target="directory"/>.</t>
          <artwork><![CDATA[
GET /proxyDownload/{downloadUrl}
]]></artwork>
          <t>The downloading provider sends the request to the hub. The hub <bcp14>MUST</bcp14> verify that
the host part of the <tt>downloadUrl</tt> is associated with the asset server domain
for one of its peer providers. This prevents the hub from becoming an open
proxy.</t>
          <t>The overall flow is as shown below.</t>
          <artset>
            <artwork type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="336" width="568" viewBox="0 0 568 336" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
                <path d="M 24,48 L 24,320" fill="none" stroke="black"/>
                <path d="M 152,48 L 152,320" fill="none" stroke="black"/>
                <path d="M 280,48 L 280,320" fill="none" stroke="black"/>
                <path d="M 408,48 L 408,320" fill="none" stroke="black"/>
                <path d="M 536,48 L 536,320" fill="none" stroke="black"/>
                <path d="M 416,80 Q 418,76.8 420,80 Q 422,83.2 424,80 Q 426,76.8 428,80 Q 430,83.2 432,80 Q 434,76.8 436,80 Q 438,83.2 440,80 Q 442,76.8 444,80 Q 446,83.2 448,80 Q 450,76.8 452,80 Q 454,83.2 456,80 Q 458,76.8 460,80 Q 462,83.2 464,80 Q 466,76.8 468,80 Q 470,83.2 472,80 Q 474,76.8 476,80 Q 478,83.2 480,80 Q 482,76.8 484,80 Q 486,83.2 488,80 Q 490,76.8 492,80 Q 494,83.2 496,80 Q 498,76.8 500,80 Q 502,83.2 504,80 Q 506,76.8 508,80 Q 510,83.2 512,80 Q 514,76.8 516,80 Q 518,83.2 520,80 Q 522,76.8 524,80 Q 526,83.2 528,80 Q 530,76.8 532,80 Q 534,83.2 536,80 " fill="none" stroke="black"/>
                <path d="M 408,96 Q 410,92.8 412,96 Q 414,99.2 416,96 Q 418,92.8 420,96 Q 422,99.2 424,96 Q 426,92.8 428,96 Q 430,99.2 432,96 Q 434,92.8 436,96 Q 438,99.2 440,96 Q 442,92.8 444,96 Q 446,99.2 448,96 Q 450,92.8 452,96 Q 454,99.2 456,96 Q 458,92.8 460,96 Q 462,99.2 464,96 Q 466,92.8 468,96 Q 470,99.2 472,96 Q 474,92.8 476,96 Q 478,99.2 480,96 Q 482,92.8 484,96 Q 486,99.2 488,96 Q 490,92.8 492,96 Q 494,99.2 496,96 Q 498,92.8 500,96 Q 502,99.2 504,96 Q 506,92.8 508,96 Q 510,99.2 512,96 Q 514,92.8 516,96 Q 518,99.2 520,96 Q 522,92.8 524,96 Q 526,99.2 528,96 " fill="none" stroke="black"/>
                <path d="M 416,144 Q 418,140.8 420,144 Q 422,147.2 424,144 Q 426,140.8 428,144 Q 430,147.2 432,144 Q 434,140.8 436,144 Q 438,147.2 440,144 Q 442,140.8 444,144 Q 446,147.2 448,144 Q 450,140.8 452,144 Q 454,147.2 456,144 Q 458,140.8 460,144 Q 462,147.2 464,144 Q 466,140.8 468,144 Q 470,147.2 472,144 Q 474,140.8 476,144 Q 478,147.2 480,144 Q 482,140.8 484,144 Q 486,147.2 488,144 Q 490,140.8 492,144 Q 494,147.2 496,144 Q 498,140.8 500,144 Q 502,147.2 504,144 Q 506,140.8 508,144 Q 510,147.2 512,144 Q 514,140.8 516,144 Q 518,147.2 520,144 Q 522,140.8 524,144 Q 526,147.2 528,144 Q 530,140.8 532,144 Q 534,147.2 536,144 " fill="none" stroke="black"/>
                <path d="M 288,160 L 408,160" fill="none" stroke="black"/>
                <path d="M 160,176 L 400,176" fill="none" stroke="black"/>
                <path d="M 32,192 Q 34,188.8 36,192 Q 38,195.2 40,192 Q 42,188.8 44,192 Q 46,195.2 48,192 Q 50,188.8 52,192 Q 54,195.2 56,192 Q 58,188.8 60,192 Q 62,195.2 64,192 Q 66,188.8 68,192 Q 70,195.2 72,192 Q 74,188.8 76,192 Q 78,195.2 80,192 Q 82,188.8 84,192 Q 86,195.2 88,192 Q 90,188.8 92,192 Q 94,195.2 96,192 Q 98,188.8 100,192 Q 102,195.2 104,192 Q 106,188.8 108,192 Q 110,195.2 112,192 Q 114,188.8 116,192 Q 118,195.2 120,192 Q 122,188.8 124,192 Q 126,195.2 128,192 Q 130,188.8 132,192 Q 134,195.2 136,192 Q 138,188.8 140,192 Q 142,195.2 144,192 Q 146,188.8 148,192 Q 150,195.2 152,192 " fill="none" stroke="black"/>
                <path d="M 408,192 Q 410,188.8 412,192 Q 414,195.2 416,192 Q 418,188.8 420,192 Q 422,195.2 424,192 Q 426,188.8 428,192 Q 430,195.2 432,192 Q 434,188.8 436,192 Q 438,195.2 440,192 Q 442,188.8 444,192 Q 446,195.2 448,192 Q 450,188.8 452,192 Q 454,195.2 456,192 Q 458,188.8 460,192 Q 462,195.2 464,192 Q 466,188.8 468,192 Q 470,195.2 472,192 Q 474,188.8 476,192 Q 478,195.2 480,192 Q 482,188.8 484,192 Q 486,195.2 488,192 Q 490,188.8 492,192 Q 494,195.2 496,192 Q 498,188.8 500,192 Q 502,195.2 504,192 Q 506,188.8 508,192 Q 510,195.2 512,192 Q 514,188.8 516,192 Q 518,195.2 520,192 Q 522,188.8 524,192 Q 526,195.2 528,192 " fill="none" stroke="black"/>
                <path d="M 24,240 Q 26,236.8 28,240 Q 30,243.2 32,240 Q 34,236.8 36,240 Q 38,243.2 40,240 Q 42,236.8 44,240 Q 46,243.2 48,240 Q 50,236.8 52,240 Q 54,243.2 56,240 Q 58,236.8 60,240 Q 62,243.2 64,240 Q 66,236.8 68,240 Q 70,243.2 72,240 Q 74,236.8 76,240 Q 78,243.2 80,240 Q 82,236.8 84,240 Q 86,243.2 88,240 Q 90,236.8 92,240 Q 94,243.2 96,240 Q 98,236.8 100,240 Q 102,243.2 104,240 Q 106,236.8 108,240 Q 110,243.2 112,240 Q 114,236.8 116,240 Q 118,243.2 120,240 Q 122,236.8 124,240 Q 126,243.2 128,240 Q 130,236.8 132,240 Q 134,243.2 136,240 Q 138,236.8 140,240 Q 142,243.2 144,240 " fill="none" stroke="black"/>
                <path d="M 152,256 L 272,256" fill="none" stroke="black"/>
                <path d="M 280,272 L 400,272" fill="none" stroke="black"/>
                <path d="M 288,288 L 408,288" fill="none" stroke="black"/>
                <path d="M 160,304 L 280,304" fill="none" stroke="black"/>
                <path d="M 32,320 Q 34,316.8 36,320 Q 38,323.2 40,320 Q 42,316.8 44,320 Q 46,323.2 48,320 Q 50,316.8 52,320 Q 54,323.2 56,320 Q 58,316.8 60,320 Q 62,323.2 64,320 Q 66,316.8 68,320 Q 70,323.2 72,320 Q 74,316.8 76,320 Q 78,323.2 80,320 Q 82,316.8 84,320 Q 86,323.2 88,320 Q 90,316.8 92,320 Q 94,323.2 96,320 Q 98,316.8 100,320 Q 102,323.2 104,320 Q 106,316.8 108,320 Q 110,323.2 112,320 Q 114,316.8 116,320 Q 118,323.2 120,320 Q 122,316.8 124,320 Q 126,323.2 128,320 Q 130,316.8 132,320 Q 134,323.2 136,320 Q 138,316.8 140,320 Q 142,323.2 144,320 Q 146,316.8 148,320 Q 150,323.2 152,320 " fill="none" stroke="black"/>
                <polygon class="arrowhead" points="536,192 524,186.4 524,197.6" fill="black" transform="rotate(0,528,192)"/>
                <polygon class="arrowhead" points="536,96 524,90.4 524,101.6" fill="black" transform="rotate(0,528,96)"/>
                <polygon class="arrowhead" points="424,144 412,138.4 412,149.6" fill="black" transform="rotate(180,416,144)"/>
                <polygon class="arrowhead" points="424,80 412,74.4 412,85.6" fill="black" transform="rotate(180,416,80)"/>
                <polygon class="arrowhead" points="408,272 396,266.4 396,277.6" fill="black" transform="rotate(0,400,272)"/>
                <polygon class="arrowhead" points="408,176 396,170.4 396,181.6" fill="black" transform="rotate(0,400,176)"/>
                <polygon class="arrowhead" points="296,288 284,282.4 284,293.6" fill="black" transform="rotate(180,288,288)"/>
                <polygon class="arrowhead" points="296,160 284,154.4 284,165.6" fill="black" transform="rotate(180,288,160)"/>
                <polygon class="arrowhead" points="280,256 268,250.4 268,261.6" fill="black" transform="rotate(0,272,256)"/>
                <polygon class="arrowhead" points="168,304 156,298.4 156,309.6" fill="black" transform="rotate(180,160,304)"/>
                <polygon class="arrowhead" points="168,176 156,170.4 156,181.6" fill="black" transform="rotate(180,160,176)"/>
                <polygon class="arrowhead" points="152,240 140,234.4 140,245.6" fill="black" transform="rotate(0,144,240)"/>
                <polygon class="arrowhead" points="40,320 28,314.4 28,325.6" fill="black" transform="rotate(180,32,320)"/>
                <polygon class="arrowhead" points="40,192 28,186.4 28,197.6" fill="black" transform="rotate(180,32,192)"/>
                <g class="text">
                  <text x="36" y="36">ClientB1</text>
                  <text x="152" y="36">ServerB</text>
                  <text x="276" y="36">HubA</text>
                  <text x="400" y="36">ServerC</text>
                  <text x="532" y="36">ClientC1</text>
                  <text x="452" y="68">Upload</text>
                  <text x="504" y="68">asset</text>
                  <text x="436" y="116">send</text>
                  <text x="488" y="116">message</text>
                  <text x="428" y="132">w/</text>
                  <text x="464" y="132">asset</text>
                  <text x="508" y="132">link</text>
                  <text x="364" y="148">submit</text>
                  <text x="228" y="164">fanout</text>
                  <text x="56" y="212">fetch</text>
                  <text x="104" y="212">asset</text>
                  <text x="48" y="228">via</text>
                  <text x="72" y="228">B</text>
                  <text x="96" y="228">and</text>
                  <text x="128" y="228">hub</text>
                  <text x="216" y="244">proxyDownload</text>
                  <text x="304" y="260">GET</text>
                  <text x="344" y="260">asset</text>
                </g>
              </svg>
            </artwork>
            <artwork type="ascii-art"><![CDATA[
ClientB1       ServerB          HubA          ServerC         ClientC1
  |               |               |               |               |
  |               |               |               |  Upload asset |
  |               |               |               |<~~~~~~~~~~~~~~+
  |               |               |               +~~~~~~~~~~~~~~>|
  |               |               |               | send message  |
  |               |               |               | w/ asset link |
  |               |               |       submit  |<~~~~~~~~~~~~~~+
  |               |      fanout   |<--------------+               |
  |               |<--------------+-------------->|               |
  |<~~~~~~~~~~~~~~+               |               +~~~~~~~~~~~~~~>|
  | fetch asset   |               |               |               |
  | via B and hub |               |               |               |
  +~~~~~~~~~~~~~~>| proxyDownload |               |               |
  |               +-------------->| GET asset     |               |
  |               |               +-------------->|               |
  |               |               |<--------------+               |
  |               |<--------------+               |               |
  |<~~~~~~~~~~~~~~+               |               |               |
]]></artwork>
          </artset>
          <t>If the request succeeds, the response body contains the contents of the
downloaded URL. The hub can reject <tt>proxyDownload</tt> requests by replying with
standard HTTP error codes.</t>
          <t>In terms of the privacy of this mechanism, the hub only sees that a specific
provider requested an (opaque to the hub) URL from another provider. It does not
know the room or the specific client.
The asset provider sees requests for an (encrypted) asset coming from the hub
provider. When caching is employed, the asset provider will only see periodic
requests.
The receiver's provider will see one request to the hub, among presumably many
requests. It has no information about the sender, URL, or room associated with
that request, however it can collect the domains of specific asset providers,
and it can use timing analysis to correlate incoming messages (which are
associated with a room) and outgoing <tt>proxyDownload</tt> requests.</t>
          <t>Both the downloading provider and the hub can cache requests. This would tend to
hide from the asset provider the number of downloading participants in a
specific room, and make it more difficult for the hub to correlate a URL with a
specific room based on the number of participants.</t>
          <t>The proxy download method improves the privacy of the clients with respect to
the asset provider, and to some extent with the hub, but it still allows the
downloading provider to correlate URLs with downloading users and infer which
URLs are sent in which rooms.</t>
          <t>The hub is <bcp14>REQUIRED</bcp14> to implement this mechanism.</t>
        </section>
        <section anchor="download-using-oblivious-http">
          <name>Download using Oblivious HTTP</name>
          <t>Oblivious HTTP (OHTTP) <xref target="RFC9458"/> is a mechanism for the encapsulation of HTTP
requests that provides a variety of desirable privacy properties. It provides
the best privacy of the download mechanisms described here, but requires the
client to implement an additional protocol.</t>
          <t>Using OHTTP for asset download privacy works as follows. The clients sends an
OHTTP request to the downloading provider's OHTTP Relay which forwards the
request to the hub's OHTTP Gateway. The hub then sends a GET request for the
asset to the asset provider (the Target)</t>
          <t>The hub <bcp14>MUST</bcp14> only accept OHTTP requests to Targets which are configured as asset
storage locations for one of its peer providers.</t>
          <artset>
            <artwork type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="336" width="568" viewBox="0 0 568 336" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
                <path d="M 24,48 L 24,320" fill="none" stroke="black"/>
                <path d="M 152,48 L 152,320" fill="none" stroke="black"/>
                <path d="M 280,48 L 280,320" fill="none" stroke="black"/>
                <path d="M 408,48 L 408,320" fill="none" stroke="black"/>
                <path d="M 536,48 L 536,320" fill="none" stroke="black"/>
                <path d="M 416,80 Q 418,76.8 420,80 Q 422,83.2 424,80 Q 426,76.8 428,80 Q 430,83.2 432,80 Q 434,76.8 436,80 Q 438,83.2 440,80 Q 442,76.8 444,80 Q 446,83.2 448,80 Q 450,76.8 452,80 Q 454,83.2 456,80 Q 458,76.8 460,80 Q 462,83.2 464,80 Q 466,76.8 468,80 Q 470,83.2 472,80 Q 474,76.8 476,80 Q 478,83.2 480,80 Q 482,76.8 484,80 Q 486,83.2 488,80 Q 490,76.8 492,80 Q 494,83.2 496,80 Q 498,76.8 500,80 Q 502,83.2 504,80 Q 506,76.8 508,80 Q 510,83.2 512,80 Q 514,76.8 516,80 Q 518,83.2 520,80 Q 522,76.8 524,80 Q 526,83.2 528,80 Q 530,76.8 532,80 Q 534,83.2 536,80 " fill="none" stroke="black"/>
                <path d="M 408,96 Q 410,92.8 412,96 Q 414,99.2 416,96 Q 418,92.8 420,96 Q 422,99.2 424,96 Q 426,92.8 428,96 Q 430,99.2 432,96 Q 434,92.8 436,96 Q 438,99.2 440,96 Q 442,92.8 444,96 Q 446,99.2 448,96 Q 450,92.8 452,96 Q 454,99.2 456,96 Q 458,92.8 460,96 Q 462,99.2 464,96 Q 466,92.8 468,96 Q 470,99.2 472,96 Q 474,92.8 476,96 Q 478,99.2 480,96 Q 482,92.8 484,96 Q 486,99.2 488,96 Q 490,92.8 492,96 Q 494,99.2 496,96 Q 498,92.8 500,96 Q 502,99.2 504,96 Q 506,92.8 508,96 Q 510,99.2 512,96 Q 514,92.8 516,96 Q 518,99.2 520,96 Q 522,92.8 524,96 Q 526,99.2 528,96 " fill="none" stroke="black"/>
                <path d="M 416,144 Q 418,140.8 420,144 Q 422,147.2 424,144 Q 426,140.8 428,144 Q 430,147.2 432,144 Q 434,140.8 436,144 Q 438,147.2 440,144 Q 442,140.8 444,144 Q 446,147.2 448,144 Q 450,140.8 452,144 Q 454,147.2 456,144 Q 458,140.8 460,144 Q 462,147.2 464,144 Q 466,140.8 468,144 Q 470,147.2 472,144 Q 474,140.8 476,144 Q 478,147.2 480,144 Q 482,140.8 484,144 Q 486,147.2 488,144 Q 490,140.8 492,144 Q 494,147.2 496,144 Q 498,140.8 500,144 Q 502,147.2 504,144 Q 506,140.8 508,144 Q 510,147.2 512,144 Q 514,140.8 516,144 Q 518,147.2 520,144 Q 522,140.8 524,144 Q 526,147.2 528,144 Q 530,140.8 532,144 Q 534,147.2 536,144 " fill="none" stroke="black"/>
                <path d="M 288,160 L 408,160" fill="none" stroke="black"/>
                <path d="M 160,176 L 400,176" fill="none" stroke="black"/>
                <path d="M 32,192 Q 34,188.8 36,192 Q 38,195.2 40,192 Q 42,188.8 44,192 Q 46,195.2 48,192 Q 50,188.8 52,192 Q 54,195.2 56,192 Q 58,188.8 60,192 Q 62,195.2 64,192 Q 66,188.8 68,192 Q 70,195.2 72,192 Q 74,188.8 76,192 Q 78,195.2 80,192 Q 82,188.8 84,192 Q 86,195.2 88,192 Q 90,188.8 92,192 Q 94,195.2 96,192 Q 98,188.8 100,192 Q 102,195.2 104,192 Q 106,188.8 108,192 Q 110,195.2 112,192 Q 114,188.8 116,192 Q 118,195.2 120,192 Q 122,188.8 124,192 Q 126,195.2 128,192 Q 130,188.8 132,192 Q 134,195.2 136,192 Q 138,188.8 140,192 Q 142,195.2 144,192 Q 146,188.8 148,192 Q 150,195.2 152,192 " fill="none" stroke="black"/>
                <path d="M 408,192 Q 410,188.8 412,192 Q 414,195.2 416,192 Q 418,188.8 420,192 Q 422,195.2 424,192 Q 426,188.8 428,192 Q 430,195.2 432,192 Q 434,188.8 436,192 Q 438,195.2 440,192 Q 442,188.8 444,192 Q 446,195.2 448,192 Q 450,188.8 452,192 Q 454,195.2 456,192 Q 458,188.8 460,192 Q 462,195.2 464,192 Q 466,188.8 468,192 Q 470,195.2 472,192 Q 474,188.8 476,192 Q 478,195.2 480,192 Q 482,188.8 484,192 Q 486,195.2 488,192 Q 490,188.8 492,192 Q 494,195.2 496,192 Q 498,188.8 500,192 Q 502,195.2 504,192 Q 506,188.8 508,192 Q 510,195.2 512,192 Q 514,188.8 516,192 Q 518,195.2 520,192 Q 522,188.8 524,192 Q 526,195.2 528,192 " fill="none" stroke="black"/>
                <path d="M 24,238 L 144,238" fill="none" stroke="black"/>
                <path d="M 24,242 L 144,242" fill="none" stroke="black"/>
                <path d="M 280,272 L 400,272" fill="none" stroke="black"/>
                <path d="M 288,288 L 400,288" fill="none" stroke="black"/>
                <path d="M 32,318 L 144,318" fill="none" stroke="black"/>
                <path d="M 32,322 L 144,322" fill="none" stroke="black"/>
                <polygon class="arrowhead" points="536,192 524,186.4 524,197.6" fill="black" transform="rotate(0,528,192)"/>
                <polygon class="arrowhead" points="536,96 524,90.4 524,101.6" fill="black" transform="rotate(0,528,96)"/>
                <polygon class="arrowhead" points="424,144 412,138.4 412,149.6" fill="black" transform="rotate(180,416,144)"/>
                <polygon class="arrowhead" points="424,80 412,74.4 412,85.6" fill="black" transform="rotate(180,416,80)"/>
                <polygon class="arrowhead" points="408,272 396,266.4 396,277.6" fill="black" transform="rotate(0,400,272)"/>
                <polygon class="arrowhead" points="408,176 396,170.4 396,181.6" fill="black" transform="rotate(0,400,176)"/>
                <polygon class="arrowhead" points="296,288 284,282.4 284,293.6" fill="black" transform="rotate(180,288,288)"/>
                <polygon class="arrowhead" points="296,160 284,154.4 284,165.6" fill="black" transform="rotate(180,288,160)"/>
                <polygon class="arrowhead" points="168,176 156,170.4 156,181.6" fill="black" transform="rotate(180,160,176)"/>
                <polygon class="arrowhead" points="152,240 140,234.4 140,245.6" fill="black" transform="rotate(0,144,240)"/>
                <polygon class="arrowhead" points="40,320 28,314.4 28,325.6" fill="black" transform="rotate(180,32,320)"/>
                <polygon class="arrowhead" points="40,192 28,186.4 28,197.6" fill="black" transform="rotate(180,32,192)"/>
                <g class="text">
                  <text x="36" y="36">ClientB1</text>
                  <text x="152" y="36">ServerB</text>
                  <text x="276" y="36">HubA</text>
                  <text x="400" y="36">ServerC</text>
                  <text x="532" y="36">ClientC1</text>
                  <text x="452" y="68">Upload</text>
                  <text x="504" y="68">asset</text>
                  <text x="436" y="116">send</text>
                  <text x="488" y="116">message</text>
                  <text x="428" y="132">w/</text>
                  <text x="464" y="132">asset</text>
                  <text x="508" y="132">link</text>
                  <text x="364" y="148">submit</text>
                  <text x="228" y="164">fanout</text>
                  <text x="56" y="212">fetch</text>
                  <text x="104" y="212">asset</text>
                  <text x="56" y="228">OHTTP</text>
                  <text x="112" y="228">wrapped</text>
                  <text x="184" y="244">OHTTP</text>
                  <text x="216" y="260">::::::::::::::&gt;</text>
                  <text x="304" y="260">GET</text>
                  <text x="344" y="260">asset</text>
                  <text x="216" y="308">&lt;::::::::::::::</text>
                </g>
              </svg>
            </artwork>
            <artwork type="ascii-art"><![CDATA[
ClientB1       ServerB          HubA          ServerC         ClientC1
  |               |               |               |               |
  |               |               |               |  Upload asset |
  |               |               |               |<~~~~~~~~~~~~~~+
  |               |               |               +~~~~~~~~~~~~~~>|
  |               |               |               | send message  |
  |               |               |               | w/ asset link |
  |               |               |       submit  |<~~~~~~~~~~~~~~+
  |               |      fanout   |<--------------+               |
  |               |<--------------+-------------->|               |
  |<~~~~~~~~~~~~~~+               |               +~~~~~~~~~~~~~~>|
  | fetch asset   |               |               |               |
  | OHTTP wrapped |               |               |               |
  +==============>| OHTTP         |               |               |
  |               +::::::::::::::>| GET asset     |               |
  |               |               +-------------->|               |
  |               |               |<--------------|               |
  |               |<::::::::::::::+               |               |
  |<==============|               |               |               |
]]></artwork>
          </artset>
          <t>For the hub, an OHTTP Gateway is <bcp14>REQUIRED</bcp14> to implement. The hub <bcp14>SHOULD</bcp14> provide
the OHTTP Gateway capability for its peer providers.</t>
          <t>Other providers <bcp14>SHOULD</bcp14> implement the OHTTP Relay capability and <bcp14>SHOULD</bcp14> enable
the relay to access</t>
          <t>The main benefit of this mechanism is that the downloading provider does not
learn the domains of every asset provider.</t>
        </section>
      </section>
    </section>
    <section anchor="minimal-metadata-rooms">
      <name>Minimal metadata rooms</name>
      <t>The room state is visible to the hub and with it the room's participant list,
giving the hub access to a significant amount of user metadata.</t>
      <t>To limit the amount of metadata the hub has access to, rooms can be created as
<em>minimal metadata rooms</em> (MMR). In an MMR the participant list and the
credentials in the room's underlying MLS group consist only of pseudonyms. The
real identifiers are stored alongside the pseudonyms encrypted under a key known
only to room participants, but not the hub.</t>
      <t>MMRs requires some additional key management, which leads to restrictions in how
the MMR can be joined and which users each participant can add to the room.</t>
      <section anchor="credential-encryption">
        <name>Credential encryption</name>
        <t>Identifiers of participants and their clients occur in two locations in a room's
state: the participant list and the credentials of the room's underlying MLS
group. In an MMR, the real identifiers of clients and users are replaced by
pseudonyms in the shape of random UUIDs qualified with the domain of the user's
provider.</t>
        <t>In MMRs, all leaves of the underlying group <bcp14>MUST</bcp14> contain PseudonymousCredentials.</t>
        <sourcecode type="tls"><![CDATA[
struct {
  IdentifierUri client_pseudonym;
  IdentifierUri user_pseudonym;
  opaque signature_public_key<V>;
  opaque identity_link_ciphertext<V>;
} PseudonymousCredential
]]></sourcecode>
        <ul spacing="normal">
          <li>
            <t><tt>user_pseudonym</tt>: The pseudonym of the client's user in this group</t>
          </li>
          <li>
            <t><tt>client_pseudonym</tt>: The pseudonym of the client identified by this credential</t>
          </li>
          <li>
            <t><tt>signature_public_key</tt>: The signature public key used to authenticate MLS
messages</t>
          </li>
          <li>
            <t><tt>identity_link_ciphertext</tt>: A ciphertext containing a credential with the
clients real identifier</t>
          </li>
        </ul>
        <t>In any given room, the <tt>user_pseudonym</tt> of a client <bcp14>MUST</bcp14> be the same across all
clients of a user and it <bcp14>MUST</bcp14> be the same as the user's entry in the participant
list.</t>
        <sourcecode type="tls"><![CDATA[
struct {
  IdentifierUri client_pseudonym;
  IdentifierUri user_pseudonym;
  opaque signature_public_key<V>;
} PseudonymousCredentialTBS

struct {
  /* SignWithLabel(., "PseudonymousCredentialTBS",
    PseudonymousCredentialTBS) */
  opaque pseudonymous_credential_signature<V>;
  Credential client_credential;
} IdentityLinkTBE
]]></sourcecode>
        <t>The <tt>identity_link_ciphertext</tt> is created by encrypting the IdentityLinkTBE.
The IdentityLinkTBE contains the client's real credential, and a signature over the
PseudonymousCredentialTBS signed with the client credential's <tt>signature_public_key</tt>.</t>
        <ul empty="true">
          <li>
            <t><strong>TODO</strong>: Specify a key management scheme that ideally
- is efficient
- allows the basic MIMI flows
- ensures that all participants can learn the identities of all other
  participants at all times
- provides FS and PCS w.r.t. metadata hiding</t>
            <t>There are several options that represent different trade-offs, but are not yet
fully specified. They will be added at a later date.</t>
          </li>
        </ul>
      </section>
    </section>
    <section anchor="relation-between-mimi-state-and-cryptographic-state">
      <name>Relation between MIMI state and cryptographic state</name>
      <section anchor="room-state">
        <name>Room state</name>
        <t>The state of a room consists of its room ID, its base policy, its
participant list (including the role and participation state of each
participant), and the associated end-to-end protocol state (its MLS group
state) that anchors the room state cryptographically.</t>
        <t>While all parties involved in a room agree on the room's state during a
specific epoch, the Hub is the arbiter that decides if a state change is valid,
consistent with the room's then-current policy. All state-changing events are
sent to the Hub and checked for their validity and policy conformance, before
they are forwarded to any follower servers or local clients.</t>
        <t>As soon as the Hub accepts an event that changes the room state, its effect is
applied to the room state and future events are validated in the context of that
new state.</t>
        <t>The room state is thus changed based on events, even if the MLS proposal
implementing the event was not yet committed by a client. Note that this only
applies to events changing the room state.</t>
      </section>
      <section anchor="cryptographic-room-representation">
        <name>Cryptographic room representation</name>
        <t>Each room is represented cryptographically by an MLS group. The Hub that
manages the room also manages the list of group members, i.e. the
list of clients belonging to users currently in the room. Application state
that is stored in the MLS GroupContext is stored as application components
in the <tt>app_data_dictionary</tt> extension, as described in <xref section="4.6" sectionFormat="of" target="I-D.ietf-mls-extensions"/>.</t>
      </section>
      <section anchor="proposal-commit-paradigm">
        <name>Proposal-commit paradigm</name>
        <t>The MLS protocol follows a proposal-commit paradigm. Any
party involved in a room (follower server, Hub or clients) can send proposals
(e.g. to add/remove/update clients of a user or to re-initialize the group with
different parameters). However, only clients can send commits, which contain all
valid previously sent proposals and apply them to the MLS group state.</t>
        <t>The MIMI usage of MLS ensures that the Hub, all follower servers and the clients
of all active participants agree on the group state, which includes the client
list and the key material used for message encryption (although the latter is
only available to clients). Since the group state also includes a copy of the
room state at the time of the most recent commit, it is also covered by the
agreement.</t>
      </section>
      <section anchor="authenticating-proposals">
        <name>Authenticating proposals</name>
        <t>MLS requires that MLS proposals from the Hub and
from follower servers (external senders in MLS terminology) be authenticated
using key material contained in the <tt>external_senders</tt> extension of the MLS
group. Each MLS group associated with a MIMI room <bcp14>MUST</bcp14> therefore contain an
<tt>external_senders</tt> extension. That extension <bcp14>MUST</bcp14> contain at least the
Certificate of the Hub.</t>
        <t>When a user from a follower server becomes a participant in the room, the
Certificate of the follower server <bcp14>MAY</bcp14> be added to the extension. When the last
participant belonging to a follower server leaves the room, the certificate of
that user <bcp14>MUST</bcp14> be removed from the list. Changes to the <tt>external_senders</tt>
extension only take effect when the MLS proposal containing the event is
committed by a MIMI commit.</t>
      </section>
      <section anchor="participant-list">
        <name>Participant List</name>
        <t>The participant list is a list of "users" in a room. Within a room, each user
is assigned exactly one <em>role</em> (expressed with a <tt>role_index</tt> and described
in <xref target="I-D.ietf-mimi-room-policy"/> at any given time (specifically within any MLS
epoch). In a room that has multiple MLS clients per "user", the identifier for
each user in <tt>participants.user</tt> is the same across all that user's clients in
the room. Note that each user has a single role at any point in time, and
therefore all clients of the same user also have the same role.</t>
        <t>The participant list may include inactive participants, which currently do not
have any clients in the corresponding MLS group, for example if their clients
do not have available KeyPackages or if all of their clients are temporarily
"kicked" out of the group. The participant list can also contain participants
that are explicitly banned, by assigning them a suitable role which does not
have any capabilities.</t>
        <sourcecode type="tls-presentation"><![CDATA[
struct {
  opaque user<V>;
  uint32 role_index;
} UserRolePair;

struct {
  UserRolePair participants<V>;
} ParticipantListData;

ParticipantListData participant_list;
]]></sourcecode>
        <t>ParticipantListData is the format of the <tt>data</tt> field inside the ComponentData
struct for the Participant list Metadata component in the <tt>app_data_dictionary</tt>
GroupContext extension.</t>
        <sourcecode type="tls-presentation"><![CDATA[
struct {
  uint32 user_index;
  uint32 role_index;
} UserindexRolePair;

struct {
  UserindexRolePair changedRoleParticipants<V>;
  uint32 removedIndices<V>;
  UserRolePair addedParticipants<V>;
} ParticipantListUpdate;
]]></sourcecode>
        <t>ParticipantListUpdate is the contents of an AppDataUpdate Proposal with the
component ID for the participant list. The index of the <tt>participants</tt> vector
in the current <tt>ParticipantListData</tt> struct is referenced as the <tt>user_index</tt>
when making changes. First the <tt>changedRoleParticipants</tt> list contains
<tt>UserindexRolePair</tt>s with the index of a user who changed roles and their new
role. Next is the <tt>removedIndices</tt> list which has a list of users to remove
completely from the participant list. Finally there is a list of
<tt>addedParticipants</tt> (which contains a user and role) that is appended to the
end of the <tt>ParticipantListData</tt>.</t>
        <t>All indices in <tt>changedRoleParticipants</tt> and <tt>removedIndices</tt> refer to the
<tt>participants</tt> vector at the end of the epoch in which the proposal is sent,
as with MLS Remove proposals. This holds even when a commit contains more than
one ParticipantListUpdate. Removing one entry does not shift the indices of
the other removals. A ParticipantListUpdate is invalid if any index is out of
range, if an index appears more than once in <tt>changedRoleParticipants</tt> or in
<tt>removedIndices</tt>, if an index appears in both lists, or if a user in
<tt>addedParticipants</tt> is already in the participant list.</t>
        <t>Each of these actions (modifying a user's role, removing a user, and adding a
user) is authorized separately according to the rules specified in
<xref target="I-D.ietf-mimi-room-policy"/>. If all the changes are authorized, the
<tt>ParticipantListData</tt> is modified accordingly.</t>
        <t>A single commit is not valid if it contain any combination of Participant list
updates that operate on (add, remove, or change the role of) the same user in
the participant list more than once.</t>
      </section>
      <section anchor="room-metadata">
        <name>Room Metadata</name>
        <t>The Room Metadata component contains data about a room which might be displayed
as human-readable information for the room, such as the name of the room and a
URL pointing to its room image/avatar.</t>
        <t>It can contain a list of <tt>room_descriptions</tt>, each of which can have a specific
<tt>language_tag</tt> and <tt>media_type</tt> along with the <tt>description_content</tt>. An empty
<tt>media_type</tt> implies <tt>text/plain;charset=utf-8</tt>.</t>
        <t>RoomMetaData is the format of the <tt>data</tt> field inside the ComponentData struct
for the Room Metadata component in the <tt>app_data_dictionary</tt> GroupContext
extension.</t>
        <sourcecode type="tls-presentation"><![CDATA[
/* a valid URI (ex: MIMI URI) */
struct {
  opaque uri<V>;
} Uri;

/* a sequence of valid UTF8 without nulls */
struct {
  opaque string<V>;
} UTF8String;

struct {
  /* an empty media_type is equivalent to text/plain;charset=utf-8 */
  opaque media_type<V>;
  opaque language_tag<V>;
  opaque description_content<V>;
} RichDescription;

struct {
  Uri room_uri;
  UTF8String room_name;
  RichDescription room_descriptions<V>;
  /* an https URI resolving to an avatar image */
  Uri room_avatar;
  UTF8String room_subject;
  UTF8String room_mood;
} RoomMetaData;

RoomMetaData room_metadata;

RoomMetaData RoomMetaUpdate;
]]></sourcecode>
        <t>RoomMetaUpdate (which has the same format as RoomMetaData) is the format of the
<tt>update</tt> field inside the AppDataUpdate struct in an AppDataUpdate Proposal for
the Room Metadata component.
If the contents of the <tt>update</tt> field are valid and if the proposer is
authorized to generate such an update, the value of the <tt>update</tt> field
completely replaces the value of the <tt>data</tt> field.</t>
        <t>Only a single Room metadata update is valid per commit.</t>
      </section>
    </section>
    <section anchor="consent">
      <name>Consent</name>
      <t>Most instant messaging systems have some notion of how a user consents to be
added to a room, and how they manipulate this consent.</t>
      <t>In the connection-oriented model, once two users are connected, either user
can add the other to any number of rooms. In other systems (often with many
large and/or public rooms), a user needs to consent individually to be added
to a room.</t>
      <t>The MIMI consent mechanism supports both models and allows them to coexist.
It allows a user to request consent, grant consent, revoke consent, and
cancel a request for consent. Each of these consent operations can indicate
a specific room, or indicate any room.</t>
      <t>A connection grant or revoke does not need to specify a room if a connection
request did, or vice versa. A connection grant or revoke does not even need
to follow a connection request.</t>
      <t>For example, Alice could ask for consent to add Bob to a specific room. Bob
could send a connection grant for Alice to add him to any room, or a
connection revoke preventing Alice from adding him to any room. Similarly,
Alice might have sent a connection request to add Bob for any room (as a
connection request), which Bob ignored or did not see. Later, Bob wants to
join a specific room administered by Alice. Bob sends a connection grant for
the specific room for Alice and sends a Knock request to Alice asking to be
added. Finally, Cathy could send a connection grant for Bob (even if Bob did
not initiate a connection request to Cathy), and Alice could recognize Cathy
on the system and send a connection revoke for her preemptively.</t>
      <ul empty="true">
        <li>
          <t><strong>NOTE</strong>: Many providers use additional factors to apply default consent
within their service such as a user belonging to a specific workgroup or
employer, participating in a related room (ex: WhatsApp "communities"), or
presence of a user in the other user's contact list. MIMI does not need to
provide a way to replicate or describe these supplemental mechanisms,
since they are strongly linked to specific provider policies.</t>
        </li>
      </ul>
      <t>Consent requests have sensitive privacy implications. The sender of a
consent request should receive an acknowledgement that the request was
received by the provider of the target user. For privacy reasons, the
requester should not know if the target user received or viewed the request.
The original requester will obviously find out if the target grants consent,
but a consent revocation/rejection is typically not communicated to the
revoked/rejected user (again for privacy reasons).</t>
      <t>Consent operations are only sent directly between the acting provider
(sending the request, grant, revoke, or cancel) and the target provider (the
object of the consent). In other words, the two providers must have a direct
peering relationship.</t>
      <t>In our example, Alice requests consent from Bob for any room. Later, Bob
sends a grants consent to Alice to add him to any room. At the same time as
sending the consent request, Alice grants consent to Bob to add her to any
room.</t>
    </section>
    <section anchor="security-considerations">
      <name>Security Considerations</name>
      <ul empty="true">
        <li>
          <t><strong>TODO</strong>: Add MIMI threat model, and great expand this section.</t>
        </li>
      </ul>
      <t>The MIMI protocol incorporates several layers of security.</t>
      <t>Individual protocol actions are protected against network attackers with
mutually-authenticated TLS, where the TLS certificates authenticate the
identities that the protocol actors assert at the application layer.</t>
      <t>Messages and room state changes are protected end-to-end using MLS.  The
protection is "end-to-end" in the sense that messages sent within the group are
confidentiality-protected against all servers involved in the delivery of those
messages, and in the sense that the authenticity of room state changes is
verified by the end clients involved in the room.  The usage of MLS ensures that
the servers facilitating the exchange cannot read messages in the room or
falsify room state changes, even though they can read the room state change
messages.</t>
      <t>Each room has an authorization policy that dictates which protocol actors can
perform which actions in the room.  This policy is enforced by the hub server
for the room.  The actors for whom the policy is being evaluated authenticate
their identities to the hub server using the MLS PublicMessage signed object
format, together with the identity credentials presented in MLS.  This design
means that the hub is trusted to correctly enforce the room's policy, but this
cost is offset by the simplicity of not having multiple policy enforcement points.</t>
      <section anchor="franking">
        <name>Franking</name>
        <t>TBD.</t>
      </section>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <t>This document registers the following four MLS application components per
<xref section="7.5" sectionFormat="of" target="I-D.ietf-mls-extensions"/>.</t>
      <section anchor="iana-frank-aad">
        <name>frank_aad app component</name>
        <ul spacing="normal">
          <li>
            <t>Value: 0x0020</t>
          </li>
          <li>
            <t>Name: frank_aad</t>
          </li>
          <li>
            <t>Where: AD</t>
          </li>
          <li>
            <t>Recommended: Y</t>
          </li>
          <li>
            <t>Reference: RFCXXXX</t>
          </li>
        </ul>
      </section>
      <section anchor="iana-franking-sig-key">
        <name>franking_agent app component</name>
        <ul spacing="normal">
          <li>
            <t>Value: 0x0021</t>
          </li>
          <li>
            <t>Name: franking_agent</t>
          </li>
          <li>
            <t>Where: GC</t>
          </li>
          <li>
            <t>Recommended: Y</t>
          </li>
          <li>
            <t>Reference: RFCXXXX</t>
          </li>
        </ul>
      </section>
      <section anchor="participantlist-app-component">
        <name>participant_list app component</name>
        <ul spacing="normal">
          <li>
            <t>Value: 0x0022</t>
          </li>
          <li>
            <t>Name: participant_list</t>
          </li>
          <li>
            <t>Where: GC</t>
          </li>
          <li>
            <t>Recommended: Y</t>
          </li>
          <li>
            <t>Reference: RFCXXXX</t>
          </li>
        </ul>
      </section>
      <section anchor="roommetadata-app-component">
        <name>room_metadata app component</name>
        <ul spacing="normal">
          <li>
            <t>Value: 0x0023</t>
          </li>
          <li>
            <t>Name: room_metadata</t>
          </li>
          <li>
            <t>Where: GC</t>
          </li>
          <li>
            <t>Recommended: Y</t>
          </li>
          <li>
            <t>Reference: RFCXXXX</t>
          </li>
        </ul>
      </section>
      <section anchor="mimi-protocol-directory-well-known-uri">
        <name>mimi-protocol-directory well-known URI</name>
        <t>This document registers the following well-known URI per <xref target="RFC8615"/>.</t>
        <ul spacing="normal">
          <li>
            <t>URI suffix: mimi-protocol-directory</t>
          </li>
          <li>
            <t>Change controller: IETF</t>
          </li>
          <li>
            <t>Specification document(s): RFCXXXX, <xref target="directory"/></t>
          </li>
          <li>
            <t>Status: permanent</t>
          </li>
          <li>
            <t>Related information: None</t>
          </li>
        </ul>
      </section>
      <section anchor="iana-media-type">
        <name>application/mimi-protocol media type</name>
        <t>This document registers the <tt>application/mimi-protocol</tt> media type per
<xref target="RFC6838"/>. The request and response bodies of the endpoints in
<xref target="mimi-endpoints-and-framing"/> use this media type. The exceptions are the
directory document, which is <tt>application/json</tt>, and the response to
<tt>proxyDownload</tt>, which carries the downloaded content.</t>
        <ul spacing="normal">
          <li>
            <t>Type name: application</t>
          </li>
          <li>
            <t>Subtype name: mimi-protocol</t>
          </li>
          <li>
            <t>Required parameters: none</t>
          </li>
          <li>
            <t>Optional parameters: none</t>
          </li>
          <li>
            <t>Encoding considerations: binary</t>
          </li>
          <li>
            <t>Security considerations: See <xref target="security-considerations"/> of RFCXXXX</t>
          </li>
          <li>
            <t>Interoperability considerations: none</t>
          </li>
          <li>
            <t>Published specification: RFCXXXX</t>
          </li>
          <li>
            <t>Applications that use this media type: MIMI providers exchanging messages for
rooms that span providers</t>
          </li>
          <li>
            <t>Fragment identifier considerations: N/A</t>
          </li>
          <li>
            <t>Additional information:
            </t>
            <ul spacing="normal">
              <li>
                <t>Deprecated alias names for this type: N/A</t>
              </li>
              <li>
                <t>Magic number(s): N/A</t>
              </li>
              <li>
                <t>File extension(s): N/A</t>
              </li>
              <li>
                <t>Macintosh file type code(s): N/A</t>
              </li>
            </ul>
          </li>
          <li>
            <t>Person &amp; email address to contact for further information: IETF MIMI Working
Group (mimi@ietf.org)</t>
          </li>
          <li>
            <t>Intended usage: COMMON</t>
          </li>
          <li>
            <t>Restrictions on usage: none</t>
          </li>
          <li>
            <t>Author: See the Authors' Addresses section of RFCXXXX</t>
          </li>
          <li>
            <t>Change controller: Internet Engineering Task Force (iesg@ietf.org)</t>
          </li>
        </ul>
      </section>
    </section>
  </middle>
  <back>
    <references anchor="sec-combined-references">
      <name>References</name>
      <references anchor="sec-normative-references">
        <name>Normative References</name>
        <reference anchor="OidcCore" target="https://openid.net/specs/openid-connect-core-1_0.html">
          <front>
            <title>OpenID Connect Core 1.0 incorporating errata set 2</title>
            <author initials="N." surname="Sakimura" fullname="Nat Sakimura">
              <organization/>
            </author>
            <author initials="J." surname="Bradley" fullname="John Bradley">
              <organization/>
            </author>
            <author initials="M. B." surname="Jones" fullname="Michael B. Jones">
              <organization/>
            </author>
            <author initials="B. de" surname="Medeiros" fullname="Breno de Medeiros">
              <organization/>
            </author>
            <author initials="C." surname="Mortimore" fullname="Chuck Mortimore">
              <organization/>
            </author>
            <date year="2023" month="December" day="15"/>
          </front>
        </reference>
        <reference anchor="I-D.ietf-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="6" month="July" year="2026"/>
            <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-ietf-mimi-arch-03"/>
        </reference>
        <reference anchor="RFC9420" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9420.xml">
          <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="RFC2119" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml">
          <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" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml">
          <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="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="RFC7231">
          <front>
            <title>Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content</title>
            <author fullname="R. Fielding" initials="R." role="editor" surname="Fielding"/>
            <author fullname="J. Reschke" initials="J." role="editor" surname="Reschke"/>
            <date month="June" year="2014"/>
            <abstract>
              <t>The Hypertext Transfer Protocol (HTTP) is a stateless \%application- level protocol for distributed, collaborative, hypertext information systems. This document defines the semantics of HTTP/1.1 messages, as expressed by request methods, request header fields, response status codes, and response header fields, along with the payload of messages (metadata and body content) and mechanisms for content negotiation.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="7231"/>
          <seriesInfo name="DOI" value="10.17487/RFC7231"/>
        </reference>
        <reference anchor="I-D.ietf-mls-extensions">
          <front>
            <title>The Messaging Layer Security (MLS) Extensions</title>
            <author fullname="Raphael Robert" initials="R." surname="Robert">
              <organization>Phoenix R&amp;D</organization>
            </author>
            <date day="6" month="July" year="2026"/>
            <abstract>
              <t>   The Messaging Layer Security (MLS) protocol is an asynchronous group
   authenticated key exchange protocol.  MLS provides a number of
   capabilities to applications, as well as several extension points
   internal to the protocol.  This document provides a consolidated
   application API, guidance for how the protocol's extension points
   should be used, and a few concrete examples of both core protocol
   extensions and uses of the application API.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ietf-mls-extensions-10"/>
        </reference>
        <reference anchor="RFC3986" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3986.xml">
          <front>
            <title>Uniform Resource Identifier (URI): Generic Syntax</title>
            <author fullname="T. Berners-Lee" initials="T." surname="Berners-Lee"/>
            <author fullname="R. Fielding" initials="R." surname="Fielding"/>
            <author fullname="L. Masinter" initials="L." surname="Masinter"/>
            <date month="January" year="2005"/>
            <abstract>
              <t>A Uniform Resource Identifier (URI) is a compact sequence of characters that identifies an abstract or physical resource. This specification defines the generic URI syntax and a process for resolving URI references that might be in relative form, along with guidelines and security considerations for the use of URIs on the Internet. The URI syntax defines a grammar that is a superset of all valid URIs, allowing an implementation to parse the common components of a URI reference without knowing the scheme-specific requirements of every possible identifier. This specification does not define a generative grammar for URIs; that task is performed by the individual specifications of each URI scheme. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="STD" value="66"/>
          <seriesInfo name="RFC" value="3986"/>
          <seriesInfo name="DOI" value="10.17487/RFC3986"/>
        </reference>
        <reference anchor="I-D.ietf-mimi-room-policy">
          <front>
            <title>Room Policy for the More Instant Messaging Interoperability (MIMI) Protocol</title>
            <author fullname="Rohan Mahy" initials="R." surname="Mahy">
              <organization>Rohan Mahy Consulting Services</organization>
            </author>
            <date day="6" month="July" year="2026"/>
            <abstract>
              <t>   This document describes a set of concrete room policies for the More
   Instant Messaging Interoperability (MIMI) Working Group.  It
   describes several independent properties and policy attributes which
   can be combined to model a wide range of chat and multimedia
   conference types.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ietf-mimi-room-policy-04"/>
        </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="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="I-D.ietf-mls-ratchet-tree-options">
          <front>
            <title>Ways to convey the Ratchet Tree in Messaging Layer Security</title>
            <author fullname="Rohan Mahy" initials="R." surname="Mahy">
              <organization>Rohan Mahy Consulting Services</organization>
            </author>
            <date day="1" month="November" year="2026"/>
            <abstract>
              <t>   The Messaging Layer Security (MLS) protocol needs to share its
   ratchet_tree object to welcome new clients into a group and in
   external joins.  While the protocol only defines a mechanism for
   sharing the entire tree, most implementations use various
   optimizations to avoid sending this structure repeatedly in large
   groups.  This document describes a way to convey these improvements
   in a standardized way and to convey the parts of a GroupInfo object
   that are not visible to an intermediary server.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ietf-mls-ratchet-tree-options-02"/>
        </reference>
        <reference anchor="I-D.mahy-mls-semiprivatemessage">
          <front>
            <title>Semi-Private Messages in the Messaging Layer Security (MLS) Protocol</title>
            <author fullname="Rohan Mahy" initials="R." surname="Mahy">
              <organization>Rohan Mahy Consulting Services</organization>
            </author>
            <date day="19" month="April" year="2026"/>
            <abstract>
              <t>   This document defines a SemiPrivateMessage for the Messaging Layer
   Security (MLS) protocol.  It allows members to share otherwise
   private commits and proposals with a designated list of external
   receivers rather than send these handshakes in a PublicMessage.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-mahy-mls-semiprivatemessage-07"/>
        </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>Rohan Mahy Consulting Services</organization>
            </author>
            <date day="4" month="July" year="2026"/>
            <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-09"/>
        </reference>
        <reference anchor="RFC6350" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6350.xml">
          <front>
            <title>vCard Format Specification</title>
            <author fullname="S. Perreault" initials="S." surname="Perreault"/>
            <date month="August" year="2011"/>
            <abstract>
              <t>This document defines the vCard data format for representing and exchanging a variety of information about individuals and other entities (e.g., formatted and structured name and delivery addresses, email address, multiple telephone numbers, photograph, logo, audio clips, etc.). This document obsoletes RFCs 2425, 2426, and 4770, and updates RFC 2739. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="6350"/>
          <seriesInfo name="DOI" value="10.17487/RFC6350"/>
        </reference>
        <reference anchor="RFC5322">
          <front>
            <title>Internet Message Format</title>
            <author fullname="P. Resnick" initials="P." role="editor" surname="Resnick"/>
            <date month="October" year="2008"/>
            <abstract>
              <t>This document specifies the Internet Message Format (IMF), a syntax for text messages that are sent between computer users, within the framework of "electronic mail" messages. This specification is a revision of Request For Comments (RFC) 2822, which itself superseded Request For Comments (RFC) 822, "Standard for the Format of ARPA Internet Text Messages", updating it to reflect current practice and incorporating incremental changes that were specified in other RFCs. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="5322"/>
          <seriesInfo name="DOI" value="10.17487/RFC5322"/>
        </reference>
        <reference anchor="RFC9458">
          <front>
            <title>Oblivious HTTP</title>
            <author fullname="M. Thomson" initials="M." surname="Thomson"/>
            <author fullname="C. A. Wood" initials="C. A." surname="Wood"/>
            <date month="January" year="2024"/>
            <abstract>
              <t>This document describes Oblivious HTTP, a protocol for forwarding encrypted HTTP messages. Oblivious HTTP allows a client to make multiple requests to an origin server without that server being able to link those requests to the client or to identify the requests as having come from the same client, while placing only limited trust in the nodes used to forward the messages.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="9458"/>
          <seriesInfo name="DOI" value="10.17487/RFC9458"/>
        </reference>
        <reference anchor="RFC8615">
          <front>
            <title>Well-Known Uniform Resource Identifiers (URIs)</title>
            <author fullname="M. Nottingham" initials="M." surname="Nottingham"/>
            <date month="May" year="2019"/>
            <abstract>
              <t>This memo defines a path prefix for "well-known locations", "/.well-known/", in selected Uniform Resource Identifier (URI) schemes.</t>
              <t>In doing so, it obsoletes RFC 5785 and updates the URI schemes defined in RFC 7230 to reserve that space. It also updates RFC 7595 to track URI schemes that support well-known URIs in their registry.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8615"/>
          <seriesInfo name="DOI" value="10.17487/RFC8615"/>
        </reference>
        <reference anchor="RFC6838">
          <front>
            <title>Media Type Specifications and Registration Procedures</title>
            <author fullname="N. Freed" initials="N." surname="Freed"/>
            <author fullname="J. Klensin" initials="J." surname="Klensin"/>
            <author fullname="T. Hansen" initials="T." surname="Hansen"/>
            <date month="January" year="2013"/>
            <abstract>
              <t>This document defines procedures for the specification and registration of media types for use in HTTP, MIME, and other Internet protocols. This memo documents an Internet Best Current Practice.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="13"/>
          <seriesInfo name="RFC" value="6838"/>
          <seriesInfo name="DOI" value="10.17487/RFC6838"/>
        </reference>
      </references>
      <references anchor="sec-informative-references">
        <name>Informative References</name>
        <reference anchor="SecretConversations" target="https://about.fb.com/wp-content/uploads/2016/07/messenger-secret-conversations-technical-whitepaper.pdf">
          <front>
            <title>Messenger Secret Conversations: Technical Whitepaper, Version 2.0</title>
            <author>
              <organization>Facebook</organization>
            </author>
            <date year="2017" month="May" day="18"/>
          </front>
        </reference>
        <reference anchor="Grubbs2017" target="https://eprint.iacr.org/2017/664.pdf">
          <front>
            <title>Message Franking via Committing Authenticated Encryption</title>
            <author initials="P." surname="Grubbs" fullname="Paul Grubbs">
              <organization>Cornell Tech</organization>
            </author>
            <author initials="J." surname="Lu" fullname="Jiahui Lu">
              <organization>Shanghai Jiao Tong University</organization>
            </author>
            <author initials="T." surname="Ristenpart" fullname="Thomas Ristenpart">
              <organization>Cornell Tech</organization>
            </author>
            <date year="2017"/>
          </front>
        </reference>
        <reference anchor="InvisibleSalamanders" target="https://link.springer.com/content/pdf/10.1007/978-3-319-96884-1_6.pdf">
          <front>
            <title>Fast Message Franking: From Invisible Salamanders to Encryptment</title>
            <author initials="Y." surname="Dodis" fullname="Yevgeniy Dodis">
              <organization>New York University</organization>
            </author>
            <author initials="P." surname="Grubbs" fullname="Paul Grubbs">
              <organization>Cornell Tech</organization>
            </author>
            <author initials="T." surname="Ristenpart" fullname="Thomas Ristenpart">
              <organization>Cornell Tech</organization>
            </author>
            <author initials="J." surname="Woodage" fullname="Joanne Woodage">
              <organization>Royal Holloway, University of London</organization>
            </author>
            <date year="2018"/>
          </front>
        </reference>
        <reference anchor="RFC8555">
          <front>
            <title>Automatic Certificate Management Environment (ACME)</title>
            <author fullname="R. Barnes" initials="R." surname="Barnes"/>
            <author fullname="J. Hoffman-Andrews" initials="J." surname="Hoffman-Andrews"/>
            <author fullname="D. McCarney" initials="D." surname="McCarney"/>
            <author fullname="J. Kasten" initials="J." surname="Kasten"/>
            <date month="March" year="2019"/>
            <abstract>
              <t>Public Key Infrastructure using X.509 (PKIX) certificates are used for a number of purposes, the most significant of which is the authentication of domain names. Thus, certification authorities (CAs) in the Web PKI are trusted to verify that an applicant for a certificate legitimately represents the domain name(s) in the certificate. As of this writing, this verification is done through a collection of ad hoc mechanisms. This document describes a protocol that a CA and an applicant can use to automate the process of verification and certificate issuance. The protocol also provides facilities for other certificate management functions, such as certificate revocation.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8555"/>
          <seriesInfo name="DOI" value="10.17487/RFC8555"/>
        </reference>
        <reference anchor="I-D.mahy-mimi-identity">
          <front>
            <title>More Instant Messaging Interoperability (MIMI) Identity Concepts</title>
            <author fullname="Rohan Mahy" initials="R." surname="Mahy">
              <organization>Rohan Mahy Consulting Services</organization>
            </author>
            <date day="6" month="July" year="2026"/>
            <abstract>
              <t>   This document explores the problem space in instant messaging (IM)
   identity interoperability when using end-to-end encryption, for
   example with the MLS (Message Layer Security) Protocol.  It also
   describes naming schemes for different types of IM identifiers.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-mahy-mimi-identity-05"/>
        </reference>
      </references>
    </references>
    <?line 2604?>

<section numbered="false" anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>Thanks to Paul Grubbs, Jon Millican, and Julia Len for their reviews of the
franking mechanism and suggested changes. Thanks to Felix Linker for his
preliminary <eref target="https://github.com/felixlinker/mimi-franking-tamarin/">formal methods
analysis</eref> of MIMI
franking. Thanks to Mark Atwood for the detailed review.</t>
    </section>
  </back>
  <!-- ##markdown-source:
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
yNwg/BnsqMTb7mX/AlmQrEkZswEA

-->

</rfc>
