<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.1 (Ruby 3.2.2) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-robert-mimi-delivery-service-05" category="info" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.18.2 -->
  <front>
    <title abbrev="MIMI">MIMI Delivery Service</title>
    <seriesInfo name="Internet-Draft" value="draft-robert-mimi-delivery-service-05"/>
    <author initials="R." surname="Robert" fullname="Raphael Robert">
      <organization>Phoenix R&amp;D</organization>
      <address>
        <email>ietf@raphaelrobert.com</email>
      </address>
    </author>
    <author initials="K." surname="Kohbrok" fullname="Konrad Kohbrok">
      <organization>Phoenix R&amp;D</organization>
      <address>
        <email>konrad.kohbrok@datashrine.de</email>
      </address>
    </author>
    <date year="2023" month="October" day="23"/>
    <area>Security</area>
    <keyword>Internet-Draft</keyword>
    <abstract>
      <?line 24?>

<t>This document describes the MIMI Delivery Service.</t>
    </abstract>
  </front>
  <middle>
    <?line 28?>

<section anchor="introduction">
      <name>Introduction</name>
      <t>The MLS protocol document specifies a protocol between two or more clients. The
MLS architecture document introduces an abstract concept of a "Delivery Service"
(DS) that is specifically responsible for ordering handshake messages and more
generally for delivering messages to the intended recipients.</t>
      <t>This document describes a Delivery Service that performs the mandated ordering
of handshake messages and uses MLS to implement a variety of other features:</t>
      <ul spacing="normal">
        <li>
          <t>A protocol between clients and the Delivery Service that allows clients to
interact with the Delivery Service, including the specific wire format of the
messages. The protocol is specifically designed to be operated in a
decentralized, federated architecture but can be used in single instances as
well.</t>
        </li>
        <li>
          <t>Assistance for new joiners of a group: The Delivery Service can keep and
update state such as the public ratchet tree, group extensions, etc.</t>
        </li>
        <li>
          <t>Message validation: The Delivery Service can inspect and validate handshake
messages and reject malformed, invalid or malicious messages.</t>
        </li>
        <li>
          <t>Built-in authentication of group members and policy enforcement: The Delivery
Service can authenticate group members and reject messages from non-members.
Additionally, the Delivery Service can be linked to the Authentication
Service to enforce more policies and validation rules.</t>
        </li>
        <li>
          <t>Scalability: The protocol makes no assumption about whether the Delivery Service
runs as a single instance or as a cluster of instances.</t>
        </li>
        <li>
          <t>Network fluid: While the Delivery Service would typically run as a
server-side component, the only requirement is that it is accessible by all
clients.</t>
        </li>
        <li>
          <t>Transport agnostic: Messages between clients and the Delivery Service can be
sent via an arbitrary transport protocol. Additionally, in the federated
case, client messages to a guest Delivery Service can be forwarded by a
client's local instance of this service.</t>
        </li>
      </ul>
      <t>TODO: Make use of MUST/SHOULD, etc. throughout.</t>
    </section>
    <section anchor="terminology">
      <name>Terminology</name>
      <t>This document uses the terminology defined in <xref target="RFC9420"/> with the following
additions:</t>
      <ul spacing="normal">
        <li>
          <t>DS Domain: Fully qualified domain name as defined in <xref target="RFC2181"/> that
represents the DS. This does not necessarily have to be the domain under which
the DS is reachable on the network. Discovering that domain is the
responsibility of the transport protocol over which the MIMI DS protocol runs.
TODO: client identifiers definitions are preliminary.</t>
        </li>
        <li>
          <t>Client: An MLS client with a unique client identifier.</t>
        </li>
        <li>
          <t>Client identifier: An octet string that uniquely identifies the client and
that maps to the DS domain of the client's DS.</t>
        </li>
      </ul>
    </section>
    <section anchor="interfaces">
      <name>Interfaces</name>
      <t>The MIMI DS tracks the state of individual MLS groups on a hub by processing
group operations. The MIMI DS can process the following requests originating
from clients:</t>
      <ul spacing="normal">
        <li>
          <t>Add clients to a group</t>
        </li>
        <li>
          <t>Inject the sending client into a group (external join)</t>
        </li>
        <li>
          <t>Remove clients from a group</t>
        </li>
        <li>
          <t>Updates their MLS key material</t>
        </li>
        <li>
          <t>Send application messages</t>
        </li>
      </ul>
      <t>TODO: This list will either grow longer if we want to keep distinct operations,
or shorter, if we don't. In the latter case, we'll need more extensive commit
validation.</t>
      <t>Follower servers can send requests the following:</t>
      <ul spacing="normal">
        <li>
          <t>Retrieve the group state required for a client to (re-)join a group</t>
        </li>
        <li>
          <t>Retrieve KeyPackages for one or more client associated with this DS</t>
        </li>
        <li>
          <t>Propose adding a client to a group</t>
        </li>
        <li>
          <t>Propose removing a client from a group</t>
        </li>
        <li>
          <t>Propose re-initializing of a group</t>
        </li>
      </ul>
      <t>TODO: Probably more proposals.</t>
      <t>Regardless if a request came from a client or a follower server, the MIMI DS
will process in two steps: Staging and merging. The first step consists of
authentication and validation checks, after which the MIMI DS stages the changes
to the group state that result from the requested operation. In a second step,
the MIMI DS merges the staged changes into the MLS group state.</t>
      <t>Locally, the MIMI DS thus provides the following interface:</t>
      <ul spacing="normal">
        <li>
          <t>Provide a Membership list (and associated metadata)</t>
        </li>
        <li>
          <t>Process a query from a client and stage the corresponding changes</t>
        </li>
        <li>
          <t>Process a query from a follower server and stage the corresponding changes</t>
        </li>
        <li>
          <t>Merge the changes resulting from a previously processed query</t>
        </li>
      </ul>
      <t>Naturally, the local interface allows the same operations as for follower
servers.</t>
    </section>
    <section anchor="architecture-and-protocol-overview">
      <name>Architecture and protocol overview</name>
      <t>The MIMI DS protocol allows interoperability between a hub which hosts a
group conversation and one or more guest DSs which are home to one or more of
the conversation's group members. Underlying each group conversation is an MLS
group that facilitates end-to-end encryption and authentication between group
members.</t>
      <t>The main purpose of the MIMI DS protocol thus is to ensure that guest clients
can participate in the group. With MLS as the underlying protocol, this means
that the MIMI DS protocol is primarily concerned with the fan-out of MLS
messages (both from and to guest clients), as well the assistance of guest
clients in joining MLS groups.</t>
      <t>The MIMI DS protocol requires clients to send MLS messages as PublicMessages
(with the exception of messages with content type <tt>application</tt>). This allows
the hub to track the MLS group state in the same way as a client would,
enabling it to keep an up-to-date and fully authenticated list of members, as
well as provide the full MLS group state to joining group members, even for
those joining via external commit. In addition, the DS can verify messages and
enforce access control policies on group operations.</t>
      <section anchor="c2s">
        <name>Client to server and server to server protocol</name>
        <t>MLS being a protocol for end-to-end encryption, the MLS protocol messages that
many of the MIMI DS protocol messages have to originate from the clients rather
than the interoperating delivery services.</t>
        <t>The MIMI DS protocol consists of two parts: A client-to-server part that allows
guest clients to interact with the hub of one of their groups and a
server-to-server protocol that allows a hub to fan out messages to guest
DSs, which can subsequently store and forward messages to their respective
clients.</t>
        <t>Note that the client-to-server part of the protocol can optionally be proxied
via the guest DS of the sending client.</t>
      </section>
      <section anchor="transport-for-the-mimi-ds-protocol">
        <name>Transport for the MIMI DS protocol</name>
        <t>The MIMI DS protocol requires a transport protocol that provides confidentiality
of messages and that allows the discovery of a DS based on the DS domain in a
client identifier.</t>
        <t>The client-to-server part of the MIMI DS protocol provide sender authentication.
Recipient authentication, as well as mutual server-to-server authentication is
left to the MIMI transport protocol.</t>
      </section>
      <section anchor="flow">
        <name>Flow</name>
        <figure anchor="full-sending-flow">
          <name>Architecture overview</name>
          <artset>
            <artwork type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="416" width="480" viewBox="0 0 480 416" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
                <path d="M 8,32 L 8,112" fill="none" stroke="black"/>
                <path d="M 120,32 L 120,112" fill="none" stroke="black"/>
                <path d="M 240,32 L 240,112" fill="none" stroke="black"/>
                <path d="M 240,176 L 240,256" fill="none" stroke="black"/>
                <path d="M 240,320 L 240,400" fill="none" stroke="black"/>
                <path d="M 264,112 L 264,168" fill="none" stroke="black"/>
                <path d="M 264,256 L 264,312" fill="none" stroke="black"/>
                <path d="M 336,120 L 336,176" fill="none" stroke="black"/>
                <path d="M 336,264 L 336,320" fill="none" stroke="black"/>
                <path d="M 360,32 L 360,112" fill="none" stroke="black"/>
                <path d="M 360,176 L 360,256" fill="none" stroke="black"/>
                <path d="M 360,320 L 360,400" fill="none" stroke="black"/>
                <path d="M 8,32 L 120,32" fill="none" stroke="black"/>
                <path d="M 240,32 L 360,32" fill="none" stroke="black"/>
                <path d="M 120,48 L 232,48" fill="none" stroke="black"/>
                <path d="M 128,96 L 240,96" fill="none" stroke="black"/>
                <path d="M 8,112 L 120,112" fill="none" stroke="black"/>
                <path d="M 240,112 L 360,112" fill="none" stroke="black"/>
                <path d="M 240,176 L 360,176" fill="none" stroke="black"/>
                <path d="M 240,256 L 360,256" fill="none" stroke="black"/>
                <path d="M 240,320 L 360,320" fill="none" stroke="black"/>
                <path d="M 240,400 L 360,400" fill="none" stroke="black"/>
                <polygon class="arrowhead" points="344,264 332,258.4 332,269.6" fill="black" transform="rotate(270,336,264)"/>
                <polygon class="arrowhead" points="344,120 332,114.4 332,125.6" fill="black" transform="rotate(270,336,120)"/>
                <polygon class="arrowhead" points="272,312 260,306.4 260,317.6" fill="black" transform="rotate(90,264,312)"/>
                <polygon class="arrowhead" points="272,168 260,162.4 260,173.6" fill="black" transform="rotate(90,264,168)"/>
                <polygon class="arrowhead" points="240,48 228,42.4 228,53.6" fill="black" transform="rotate(0,232,48)"/>
                <polygon class="arrowhead" points="136,96 124,90.4 124,101.6" fill="black" transform="rotate(180,128,96)"/>
                <g class="text">
                  <text x="48" y="68">Sending</text>
                  <text x="180" y="68">(proprietary</text>
                  <text x="272" y="68">Guest</text>
                  <text x="308" y="68">DS</text>
                  <text x="44" y="84">Client</text>
                  <text x="184" y="84">protocol)</text>
                  <text x="216" y="148">DSRequest</text>
                  <text x="388" y="148">DSResponse</text>
                  <text x="264" y="212">Hub</text>
                  <text x="192" y="292">DSFanoutRequest</text>
                  <text x="412" y="292">DSFanoutResponse</text>
                  <text x="272" y="356">Guest</text>
                  <text x="308" y="356">DS</text>
                </g>
              </svg>
            </artwork>
            <artwork type="ascii-art"><![CDATA[
+-------------+              +--------------+
|             +------------->+              |
| Sending     | (proprietary | Guest DS     |
| Client      |   protocol)  |              |
|             +<-------------+              |
+-------------+              +--+--------+--+
                                |        ^
                      DSRequest |        | DSResponse
                                v        |
                             +--+--------+--+
                             |              |
                             | Hub          |
                             |              |
                             |              |
                             +--+--------+--+
                                |        ^
                DSFanoutRequest |        | DSFanoutResponse
                                v        |
                             +--+--------+--+
                             |              |
                             | Guest DS     |
                             |              |
                             |              |
                             +--------------+
]]></artwork>
          </artset>
        </figure>
        <t><xref target="full-sending-flow"/> shows an example protocol flow, where a client sends a
request to its own guest DS, which in turn makes a request to the hub. The
hub then fans out a message to another guest DS.</t>
        <t>Both the message sending and the fanout parts of the protocol are designed in a
request/response pattern. In the first protocol part, the client sends a
DSRequest message to the Delivery Service and the Delivery Service responds with
a DSResponse message. This pattern can easily be used over e.g. RESTful APIs.</t>
        <figure>
          <name>Delivery Service Request/Response scheme</name>
          <artset>
            <artwork type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="160" width="168" viewBox="0 0 168 160" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
                <path d="M 8,48 L 8,144" fill="none" stroke="black"/>
                <path d="M 144,48 L 144,144" fill="none" stroke="black"/>
                <path d="M 8,80 L 136,80" fill="none" stroke="black"/>
                <path d="M 16,128 L 144,128" fill="none" stroke="black"/>
                <polygon class="arrowhead" points="144,80 132,74.4 132,85.6" fill="black" transform="rotate(0,136,80)"/>
                <polygon class="arrowhead" points="24,128 12,122.4 12,133.6" fill="black" transform="rotate(180,16,128)"/>
                <g class="text">
                  <text x="28" y="36">Client</text>
                  <text x="152" y="36">Hub</text>
                  <text x="56" y="68">DSRequest</text>
                  <text x="60" y="116">DSResponse</text>
                </g>
              </svg>
            </artwork>
            <artwork type="ascii-art"><![CDATA[
Client           Hub
|                |
| DSRequest      |
+--------------->|
|                |
| DSResponse     |
|<---------------+
|                |
]]></artwork>
          </artset>
        </figure>
        <t>For the second part of the protocol the Delivery Service sends a DSFanoutRequest
to each guest DS. This happens whenever a message needs to be fanned out to all
other members of a group as a result of an incoming DSRequest. The guest DS in
turn responds with a DSFanoutResponse.</t>
        <figure>
          <name>Client/Delivery Service communication with fanout</name>
          <artset>
            <artwork type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="240" width="592" viewBox="0 0 592 240" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
                <path d="M 8,48 L 8,224" fill="none" stroke="black"/>
                <path d="M 144,48 L 144,224" fill="none" stroke="black"/>
                <path d="M 416,48 L 416,224" fill="none" stroke="black"/>
                <path d="M 8,80 L 136,80" fill="none" stroke="black"/>
                <path d="M 16,128 L 144,128" fill="none" stroke="black"/>
                <path d="M 144,160 L 408,160" fill="none" stroke="black"/>
                <path d="M 152,208 L 416,208" fill="none" stroke="black"/>
                <polygon class="arrowhead" points="416,160 404,154.4 404,165.6" fill="black" transform="rotate(0,408,160)"/>
                <polygon class="arrowhead" points="160,208 148,202.4 148,213.6" fill="black" transform="rotate(180,152,208)"/>
                <polygon class="arrowhead" points="144,80 132,74.4 132,85.6" fill="black" transform="rotate(0,136,80)"/>
                <polygon class="arrowhead" points="24,128 12,122.4 12,133.6" fill="black" transform="rotate(180,16,128)"/>
                <g class="text">
                  <text x="28" y="36">Client</text>
                  <text x="152" y="36">Hub</text>
                  <text x="432" y="36">Guest</text>
                  <text x="492" y="36">Delivery</text>
                  <text x="560" y="36">Service</text>
                  <text x="56" y="68">DSRequest</text>
                  <text x="60" y="116">DSResponse</text>
                  <text x="216" y="148">DSFanoutRequest</text>
                  <text x="220" y="196">DSFanoutResponse</text>
                </g>
              </svg>
            </artwork>
            <artwork type="ascii-art"><![CDATA[
Client           Hub                               Guest Delivery Service
|                |                                 |
| DSRequest      |                                 |
+--------------->|                                 |
|                |                                 |
| DSResponse     |                                 |
|<---------------+                                 |
|                | DSFanoutRequest                 |
|                +-------------------------------->|
|                |                                 |
|                | DSFanoutResponse                |
|                |<--------------------------------+
|                |                                 |
]]></artwork>
          </artset>
        </figure>
      </section>
      <section anchor="serialization-format">
        <name>Serialization format</name>
        <t>MLS messages use the presentation language and encoding format defined in
<xref target="RFC8446"/> with the extensions defined in the MLS protocol specification. The
MIMI DS protocol uses the same serialization format, as both clients and DS
already have to support it to process MLS messages.</t>
        <t>Octet strings resulting from serialization in this format are unambiguous and
require no further canonicalization.</t>
      </section>
      <section anchor="keypackages">
        <name>KeyPackages</name>
        <t>Clients have to upload KeyPackages such that others can add them to groups. In
the context of interoperability, this means that clients have to be able to
download KeyPackages of clients belonging to other DSs.</t>
        <t>The MIMI DS protocol allows clients to download the KeyPackages of other
clients. Uploading KeyPackages is outside of the scope of this protocol, as it
is not relevant for interoperability.</t>
        <t>TODO: KeyPackages of last resort should be marked. Ideally by using a KeyPackage
extension.</t>
      </section>
      <section anchor="enqueue-authorization">
        <name>Enqueue authorization</name>
        <t>TODO: This section sketches an authorization mechanism based on a KeyPackage
extension. That extension would have to be defined in the context of the MLS WG.</t>
        <t>Each KeyPackage that a client publishes also carries a FanoutAuthToken inside
a FanoutAuth KeyPackage extension.</t>
        <sourcecode type="tls"><![CDATA[
struct {
  opaque token<V>;
} FanoutAuthToken
]]></sourcecode>
        <t>Whenever a client is added to a group (or when a new group is created), the DS
checks that the KeyPackages of all joiners contain a FanoutAuth extension and
stores the contained token alongside the group state.</t>
        <t>The FanoutAuthToken is included in DSFanoutRequests and allows the receiving
DS to check whether the sender is authorized to enqueue messages for the
recipient.</t>
        <t>Clients can change their FanoutAuthToken by sending a new token with an
update operation.</t>
        <t>TODO: Details on the cryptographic scheme underlying the token.</t>
      </section>
      <section anchor="version-agility">
        <name>Version agility</name>
        <t>MLS provides version, ciphersuite and extension agility. The versions,
ciphersuites and extensions a client supports are advertised in its LeafNodes,
both in all of the client's groups, as well as in its KeyPackages through the
Capabilities field (Section 7.2 of <xref target="I-D.ietf-mls-protocol"/>).</t>
        <t>MLS DS protocol clients MUST make use of a LeafNode extension to advertise the
MIMI DS protocol versions they support.</t>
        <t>TODO: Such an extension would have to be specified in the context of the MLS WG.</t>
      </section>
      <section anchor="group-lifecycle">
        <name>Group lifecycle</name>
        <t>Upon creation MLS groups are parameterized by a GroupID, an MLS version number,
as well as a ciphersuite. All three parameters are fixed and cannot be changed
throughout the lifetime of a group.</t>
        <t>Groups capable of interoperability with the MIMI DS protocol MUST use a
GroupContext extension that indicates the MIMI DS protocol version with which it
was created. This extension MUST NOT be changed throughout the lifetime of the
group.</t>
        <t>While all these parameters cannot be changed throughout a group's lifetime, the
group can be re-initialized as described in Section 11.2. of <xref target="RFC9420"/> to
create a new group with a new set of parameters.</t>
        <t>The MIMI DS protocol supports re-initializations of groups using the
corresponding ReInitialization operation under the condition that all MLS
parameters are compatible with the MIMI DS protocol version.</t>
        <t>If a group is no longer used, it can be deleted either by a client or the DS
itself.</t>
        <t>TODO: Each MIMI DS protocol version should probably fix a set of ciphersuites,
MLS protocol versions and maybe even extensions it supports. New ones can be
added with protocol version upgrades.</t>
      </section>
    </section>
    <section anchor="security-properties-overview">
      <name>Security properties overview</name>
      <t>The MIMI DS protocol provides a number of security guarantees.</t>
      <section anchor="mls-based-security-properties">
        <name>MLS-based security properties</name>
        <t>The MLS protocol underlying the MIMI DS protocol provides a number of security
guarantees that primarily affect end-to-end communication between clients such
as authentication and confidentiality with forward- as well as post-compromise
security (although the latter only holds for application messages). While the
MIMI DS protocol acts as a layer around the MLS protocol it inherits some of
MLSs security guarantees.</t>
        <t>More concretely, the DS can verify client signatures on MLS messages and thus
ensure that end-to-end authentication holds. Since the DS uses MLS messages to
track the group state (including group membership), it is guaranteed to have the
same view of that state as the group members.</t>
      </section>
    </section>
    <section anchor="framing-and-processing-overview">
      <name>Framing and processing overview</name>
      <section anchor="client-to-server-requests">
        <name>Client to server requests</name>
        <t>All client to server requests consist of a MIMI DS specific protocol wrapper
called DSRequst. DSRequest contains the MIMI DS protocol version, a body with
operation-specific data, as well as authentication information.</t>
        <sourcecode type="tls"><![CDATA[
enum {
  ds_delete_group(0),
  ...
} DSRequestType;

struct {
  DSRequestType request_type;
  select (DSRequestBody.request_type) {
    case ds_delete_group:
      DeleteGroupRequest delete_group_request;
    ...
  }
} DSRequestBody;

struct {
  DSProtocolVersion version;
  DSRequestBody request_body;
  DSAuthData authentication_data;
} DSRequest;
]]></sourcecode>
        <t>A DS supports a variety of operations. For presentational reasons, we only
define DSRequestType and the corresponding <tt>case</tt> statement in DSRequestBody
partially here. The full definition with all operations relevant for the
normal DS operating mode can be found in <xref target="operations"/>.</t>
        <t>The <tt>authentication_data</tt> field of a DSRequest depends on the request type and
contains the data necessary for the DS to authenticate the request.</t>
        <sourcecode type="tls"><![CDATA[
enum {
  Anonymous,
  ClientSignature,
} DSAuthType;

struct {
  DSAuthType auth_type;
  select (DSAuthData.auth_type) {
    case Anonymous:
      struct {};
    case ClientSignature:
      uint32 sender_index;
      opaque signature<0..255>;
  }
} DSAuthData;
]]></sourcecode>
        <t>Before the DS performs the requested operation, it performs an authentication
operation depending on the DSAuthType.</t>
        <ul spacing="normal">
          <li>
            <t>Anonymous: No authentication required</t>
          </li>
          <li>
            <t>ClientSignature: The DS uses the public signature key of the MLS client in
leaf with the leaf index <tt>sender_index</tt> to verify the signature over the
following struct:</t>
          </li>
        </ul>
        <sourcecode type="tls"><![CDATA[
struct {
  DSProtocolVersion protocol_version;
  DSRequestBody request_body;
  u32 sender_index
} ClientSignatureTBS
]]></sourcecode>
        <t>Note that all group operations additionally contain an MLSMessage the content of
which mirrors the request type, e.g., an AddClients request wraps an MLS commit
that in turn contains the Add proposals for the clients to be added. In that
case, the DS uses the GroupID inside the MLSMessage to determine which group the
request refers to and verifies the MLSMessage in the same way an MLS client
would (including the signature).</t>
        <t>Depending on the nature of the request, clients can also include data in the AAD
field of the MLSMessage, where it can be read and authenticated by both DS and
all other group members.</t>
        <t>After performing the desired operation using the data in DSRequestBody the DS
responds to the client (or the proxying guest DS) with a DSResponse.</t>
        <sourcecode type="tls"><![CDATA[
struct {
  DSProtocolVersion protocol_version;
  DSResponseBody response_body;
} DSResponse

enum DSResponseType {
  Ok,
  Error,
  WelcomeInfo,
  ExternalCommitInfo
  KeyPackages,
}

struct DSResponseBody {
  DSResponseType response_type;
  select (DSResponseBody.response_type) {
    case Ok:
      struct {};
    case Error:
      DSError error;
    case WelcomeInfo:
      optional<Node> ratchet_tree<V>;
    case ExternalCommit:
      MLSMessage: group_info;
      optional<Node> ratchet_tree<V>;
    case KeyPackages:
      KeyPackage key_packages<V>;
  }
}

struct {
  TODO: Operation specific errors.
} DSError
]]></sourcecode>
      </section>
      <section anchor="server-to-server-requests">
        <name>Server to server requests</name>
        <t>After sending the response, and depending on the operation the DS might fan out
messages to one or more guest DSs.</t>
        <t>To that end, it wraps the MLSMessage to be fanned out into a DSFanoutRequest. In
addition to the MLSMessage, the DSFanoutRequest contains the protocol version, a
list of client ids representing the clients for which the payload is meant, a
FanoutAuthToken (see <xref target="enqueue-authorization"/>) for each of the clients, as well
as the payload to be fanned out.</t>
        <sourcecode type="tls"><![CDATA[
struct {
  DSProtocolVersion protocol_version;
  opaque recipient_ids<V>;
  FanoutAuthToken fanout_auth_tokens<V>;
  MLSMessage mls_message;
} DSFanoutRequest
]]></sourcecode>
        <t>The receiving DS first verifies the signature using the sending DS' public
signature key and then further validates the message by performing the following
checks:</t>
        <ul spacing="normal">
          <li>
            <t>That the protocol version is compatible with its configuration</t>
          </li>
          <li>
            <t>That the <tt>recipient_ids</tt> are all clients of this DS</t>
          </li>
          <li>
            <t>The the <tt>fanout_auth_tokens</tt> are all valid tokens for the individual
recipients</t>
          </li>
        </ul>
        <t>The recieving DS can then store and forward the contained MLS message to the
clients indicated in the <tt>recipient_ids</tt> field and send a DSFanoutResponse.</t>
        <sourcecode type="tls"><![CDATA[
enum {
  Ok,
  Error,
} DSFanoutResponseType

struct {
  TODO: Fanout error types
} DSFanoutError

struct DSFanoutResponseBody {
  DSFanoutResponseType response_type;
  select (DSFanoutResponseBody.response_type) {
    case Ok:
      struct {};
    case Error:
      DSFanoutError error;
  }
}

struct {
  DSProtocolVersion protocol_version;
  DSResponseBody response_body;
} DSFanoutResponse
]]></sourcecode>
      </section>
    </section>
    <section anchor="ds-assisted-joining">
      <name>DS assisted joining</name>
      <t>To verify and deliver messages, authenticate clients as members of a group and
to assist clients that want to join a group, the DS keeps track of the state of
each group for which it is the hub. More specifically, it keeps track of the
group's ratchet tree, the group's GroupContext and other information required to
produce a valid GroupInfo for the current group epoch. It does this by
processing incoming MLS messages in the same way a member of that group would,
except of course that the DS doesn't hold any private key material.</t>
      <t>While MLS messages are sufficient to keep track of most of the group information,
it is not quite enough to create a GroupInfo. To allow the DS to provide a valid
GroupInfo to externally joining clients, it additionally requires clients to
provide the remaining required information. Concretely, it requires clients to
upload the Signature and the GroupInfo extensions. Clients need to send this
information whenever they send an MLS message (i.e. an MLSMessage struct) that
contains a commit.</t>
      <sourcecode type="tls"><![CDATA[
struct {
  Extension group_info_extensions<V>;
  opaque Signature<V>;
} PartialGroupInfo
]]></sourcecode>
      <t>The combination of a commit and a partial group info is called an
MLSGroupUpdate.</t>
      <sourcecode type="tls"><![CDATA[
struct {
  MLSMessage commit;
  PartialGroupInfo partial_group_info;
} MLSGroupUpdate
]]></sourcecode>
      <t>Whenever the DS receives an MLSGroupUpdate, it must verify that the
MLSMessage contains a PublicMessage with a commit and that commit and partial
group info are valid relative to the existing group state according to the MLS
specification.</t>
      <t>TODO: For now there is no distinct endpoint to obtain authentication material
that allows the DS to authenticate clients. This would be part of the AS design.</t>
      <t>By tracking the group information in this way, the DS can help clients that join
via external commit by providing them with a ratchet tree and a group into.</t>
      <t>Similary, clients that wish to join a group via a regular invite (i.e. a Welcome
message) have already received a GroupInfo and can obtain a ratchet tree from
the DS.</t>
      <t>In the time between a client being added to a group by a commit and the client
wanting to join the group, the group state can have progressed by one or more
epochs. As a consequence, the DS MUST keep track of epochs in which clients are
added and store the corresponding group states until each client has
successfully joined.</t>
    </section>
    <section anchor="proposals-by-reference">
      <name>Proposals and DS-initiated operations</name>
      <t>MLS relies on a proposal-commit logic, where the proposals encode the specific
action the sending client intends to take and the commit then performs the
actions of a set of commits.</t>
      <t>The advantage of this approach is that the sender of the proposal does not have
to be the committer, which allows, for example, the DS to propose the removal of
a client, or a client to propose that it be removed from the group. Note that
the latter example is the only way that a client can remove itself (i.e. leave)
from a group.</t>
      <t>Such proposals, where the original sender differs from the sender of the commit
are called "proposal by reference", or "proposal by value" if the proposal is
sent by the committer as part of the commit itself.</t>
      <t>The following sections detail operations that can be performed by clients, so
each operation that entails a change to the group state (with the exception of
the self remove operation) require the sender to perform a commit, where the
semantics of the operation are reflected as proposals by value. For example, the
commit in the AddClientsRequest must only contain Add proposals.</t>
      <t>If a client receives a valid standalone proposal, it MUST store it and verify
that the next commit includes said proposal.</t>
      <t>TODO: Be more specific about proposal validation. Also, we might want to allow
the server to rescind a proposal.</t>
      <t>Whenever a client sends a commit as part of an operation, it MUST include all
stored proposals by reference, such as server-initiated Remove proposals, or
proposals sent as part of a self-remove operation.</t>
      <t>TODO: Proposals by reference pose a problem in the context of external commits,
as, even if the external committer had access to all proposals in an epoch, it
wouldn't be able to verify them, thus potentially leading to an invalid external
commit. A solution could be introduced either as part of the MIMI DS protocol,
or as an MLS extension. The latter would be preferable, as other users of MLS
are likely going to encounter the same problem.</t>
      <t>To allow the DS to send proposals, all groups MUST contain an <tt>external_senders</tt>
extension as defined in Section 12.1.8.1. of <xref target="RFC9420"/> that includes the DS'
credential and its signature public key.</t>
      <t>TODO: We might also want to mandate that the group includes credentials of guest
DSs involved in the group. However, for them to be able to send proposals, we'd
need an additional operation/endpoint that the DS exposes.</t>
      <t>TODO: Details of the DS credential, distribution, etc. A BasicCredential with
the FQDN of the DS would probably be sufficient.</t>
      <t>The DS can simply create such proposals itself based on the group information
and distribute it to all group members via regular DSFanoutRequests.</t>
      <section anchor="client-removals">
        <name>Client removals</name>
        <t>The DS can propose that one or more clients be removed from a given group. To
that end, it issues a remove proposal for each client it wants removed, where
each remove proposal targets the leaf of one of the clients in question.</t>
      </section>
      <section anchor="client-additions">
        <name>Client additions</name>
        <t>The DS can propose that one or more clients be added to the group. It does so by
issueing an add proposal for each client, where each add proposal contains a
KeyPackage of the respective client.</t>
        <t>TODO: If the DS should be allowed to add clients that belong to another DS, we
need an endpoint that allows DSs to fetch KeyPackages from one-another.</t>
      </section>
    </section>
    <section anchor="operations">
      <name>Client-initiated operations</name>
      <t>The DS supports a number of operations, each of which is represented by a
variant of the DSRequestType enum and has its own request body.</t>
      <sourcecode type="tls"><![CDATA[
enum {
  ds_delete_group,
  ds_add_clients,
  ds_remove_clients,
  ds_self_remove_client,
  ds_update_client,
  ds_external_join,
  ds_send_message,
  ds_key_packages,
} DSRequestType;

struct {
  DSRequestType request_type;
  select (DSRequestBody.request_type) {
    case ds_delete_group:
      DeleteGroupRequest delete_group_request;
    case ds_add_clients:
      AddClientsRequest add_clients_request;
    case ds_remove_clients:
      RemoveClientsRequest remove_clients_request;
    case ds_self_remove_clients:
      SelfRemoveClientsRequest self_remove_clients_request;
    case ds_update_client:
      UpdateClientRequest update_client_request;
    case ds_external_join:
      ExternalJoinRequest external_join_request;
    case ds_send_message:
      SendMessageRequest send_message_request;
    case ds_key_packages:
      KeyPackagesRequest key_packages_request;
  }
} DSRequestBody;
]]></sourcecode>
      <section anchor="request-group-id">
        <name>Request group id</name>
        <t>Clients can use this operation to request a group id. This group ID can
subsequently used to create a group on this DS.</t>
        <t>After receiving this request, the DS generates a unique group id and responds
with a DSResponse struct of type GroupID.</t>
      </section>
      <section anchor="delete-group">
        <name>Delete group</name>
        <t>A request from the client to delete a group from the Delivery Service. This
operation allows clients to delete a group from the DS. Clients can of course
keep a copy of the group state locally for archival purposes.</t>
        <sourcecode type="tls"><![CDATA[
struct {
  MLSGroupUpdate group_update;
} DeleteGroupRequest;
]]></sourcecode>
        <t><strong>Validation:</strong></t>
        <t>The Delivery Service validates the request as follows:</t>
        <ul spacing="normal">
          <li>
            <t>The MLSGroupUpdate MUST contain a PublicMessage with a commit that contains
Remove proposals for every member of the group except the committer.</t>
          </li>
        </ul>
      </section>
      <section anchor="add-clients-to-a-group">
        <name>Add clients to a group</name>
        <t>A request from a client to add one or more clients. This operation allows
clients to add other clients to an existing group. Alternatively, new clients
can add themselves by joining via external commit.</t>
        <sourcecode type="tls"><![CDATA[
struct {
  MLSGroupUpdate group_update;
  MLSMessage welcome_messages<V>;
} AddClientsRequest;
]]></sourcecode>
        <t><strong>Validation:</strong></t>
        <ul spacing="normal">
          <li>
            <t>The MLSGroupUpdate MUST contain a PublicMessage with a commit that contains
only Add proposals with the possible exception of Remove proposals as detailed
in <xref target="proposals-by-reference"/>.</t>
          </li>
          <li>
            <t>The commit MUST NOT change the sender's client credential.</t>
          </li>
          <li>
            <t>All KeyPackages included in Add proposals MUST include a FanoutAuth extension.</t>
          </li>
        </ul>
      </section>
      <section anchor="remove-clients-from-a-group">
        <name>Remove clients from a group</name>
        <t>A request from a client to remove one or more other clients. Note that this
operation cannot be used by a client to remove itself from the group. For that
purpose, the SelfRemoveClientRequest should be used instead.</t>
        <sourcecode type="tls"><![CDATA[
struct {
  MLSGroupUpdate group_update;
} RemoveClientsRequest;
]]></sourcecode>
        <t><strong>Validation:</strong></t>
        <ul spacing="normal">
          <li>
            <t>The MLSGroupUpdate MUST contain a PublicMessage with a commit that contains only
Remove proposals.</t>
          </li>
          <li>
            <t>The commit MUST NOT change the sender's client credential.</t>
          </li>
        </ul>
      </section>
      <section anchor="self-remove-a-client-from-a-group">
        <name>Self remove a client from a group</name>
        <t>A request from a client to remove itself from the group. Note that this request
only contains a proposal, so the client is not effectively removed from the
group until another group member commits that proposal. See
<xref target="proposals-by-reference"/> for more details.</t>
        <sourcecode type="tls"><![CDATA[
struct {
  MLSMessage proposal;
} SelfRemoveClientRequest;
]]></sourcecode>
        <t><strong>Validation:</strong></t>
        <ul spacing="normal">
          <li>
            <t>The MLSMessage MUST contain a PublicMessage that contains a single
Remove proposal.</t>
          </li>
          <li>
            <t>The Remove proposal MUST target the sending client.</t>
          </li>
        </ul>
      </section>
      <section anchor="update-a-client-in-a-group">
        <name>Update a client in a group</name>
        <t>A request from a client to update its own leaf in an MLS group. This operation
can be used to update any information in the sender's leaf node. For example,
the sender could use this operation to update its key material to achieve
post-compromise security, update its Capabilities extension, or its leaf
credential.</t>
        <t>The sending client can also choose to send a FanoutAuthToken, which the DS uses
to replace the client's existing token.</t>
        <sourcecode type="tls"><![CDATA[
struct {
  MLSGroupUpdate group_update;
  optional<FanoutAuthToken> token;
} UpdateClientRequest;
]]></sourcecode>
        <t><strong>Validation:</strong></t>
        <ul spacing="normal">
          <li>
            <t>The MLSGroupUpdate MUST contain a PublicMessage that contains a commit with an
UpdatePath, but no other proposals by value.</t>
          </li>
          <li>
            <t>If the leaf credential is changed by the update, the DS MUST validate the new
credential.</t>
          </li>
        </ul>
        <t>TODO: The discussion around identity and credentials should yield a method to
judge if a new credential is a valid update to an existing one.</t>
      </section>
      <section anchor="join-the-group-using-an-external-commit">
        <name>Join the group using an external commit</name>
        <t>A request from a client to join a group using an external commit, i.e. without
the help of an existing group member. This operation can be used, for example,
by existing group members that have to recover from state loss.</t>
        <t>To retrieve the information necessary to create the external commit, the joiner
has to fetch the external commit information from the DS.</t>
        <sourcecode type="tls"><![CDATA[
struct {
  MLSGroupUpdate group_update;
} ExternalJoinRequest;
]]></sourcecode>
        <t><strong>Validation:</strong></t>
        <ul spacing="normal">
          <li>
            <t>The MLSGroupUpdate MUST contain a PublicMessage that contains a commit with sender
type NewMemberCommit.</t>
          </li>
        </ul>
      </section>
      <section anchor="send-an-application-message-to-a-group">
        <name>Send an application message to a group</name>
        <t>A request from a client to fan out an application message to a group. This
operation is meant to send arbitrary data to the rest of the group. Since the
application message is a PrivateMessage, the DS can not verify its content or
authenticate its sender (even though it does authenticate the sender of the
surrounding DSRequest).</t>
        <artwork><![CDATA[
struct {
  MLSMessage application_message;
} SendMessageRequest;
]]></artwork>
        <t><strong>Validation:</strong></t>
        <ul spacing="normal">
          <li>
            <t>The MLSMessage MUST contain a PrivateMessage with ContentType application.</t>
          </li>
        </ul>
      </section>
      <section anchor="fetch-keypackages-of-one-or-more-clients">
        <name>Fetch KeyPackages of one or more clients</name>
        <t>A request from a client to retrieve the KeyPackage(s) of one or more clients of
this DS. KeyPackages are required to add other clients (and thus other users) to
a group.</t>
        <artwork><![CDATA[
struct {
  ClientID client_identifiers<V>;
} KeyPackagesRequest;
]]></artwork>
        <t>The DS responds with the KeyPackages of all clients listed in the request.</t>
        <t><strong>Validation:</strong></t>
        <ul spacing="normal">
          <li>
            <t>All client identifiers MUST refer to clients native to this DS.</t>
          </li>
          <li>
            <t>The DS SHOULD verify that the sender of the request is authorized to retrieve
the DSKeyPackages of the clients in question.</t>
          </li>
        </ul>
      </section>
      <section anchor="reinitialize-a-group">
        <name>ReInitialize a group</name>
        <t>A request from a client to re-initialize a group with different parameters as
outlined in <xref target="group-lifecycle"/>.</t>
        <sourcecode type="tls"><![CDATA[
struct {
  MLSGroupUpdate commit;
} ReInitializeGroupRequest;
]]></sourcecode>
        <t><strong>Validation:</strong></t>
        <ul spacing="normal">
          <li>
            <t>The MLSGroupUpdate MUST contain a PublicMessage that contains a commit with a
re-init proposal.</t>
          </li>
          <li>
            <t>The GroupID in the re-init proposal MUST point to another group on this hub,
which has a MIMI DS protocol version that is greater or equal than this group.</t>
          </li>
        </ul>
      </section>
    </section>
    <section anchor="dsfanoutrequests">
      <name>DSFanoutRequests</name>
      <t>After the DS has processed an incoming MLSMessage, it prepares a DSFanoutRequest
as described in <xref target="framing-and-processing-overview"/>.</t>
      <t>For DS to DS communication, the MIMI DS protocol relies on the underlying
transport protocol to provide mutual authentication.</t>
    </section>
    <section anchor="rate-limiting-and-spam-prevention">
      <name>Rate-limiting and spam prevention</name>
      <t>All requests (with the exception of the VerificationKeyRequest) can be
explicitly authenticated by the recipient through the verification of a
signature. This means that recipients can follow a rate-limiting strategy of
their choice based on the sender's identity.</t>
      <t>For DSRequests, the DS can rate-limit on a per group-level, per-DS level
(reducing the messages from all clients belonging to a single DS), or even based
on individual clients.</t>
      <t>For DSFanoutRequests, rate-limiting or blocking can happen based on the identity
of the sending DS, or it can happen on a per-group basis, where the recipient
only blocks messages from a particular group.</t>
      <t>Such rate-limiting can happen by decision of the DS itself, or on the request of
its local clients. For example, a client might wish to block connection requests
from one specific other client without blocking connection requests from all other
clients of that DS.</t>
    </section>
    <section anchor="abusive-and-illegal-content">
      <name>Abusive and illegal content</name>
      <t>As all application messages are encrypted, the DS has no way of analyzing their
content for illegal or abusive content. It may make use of a message franking
scheme to allow its clients to report such content, although this is beyond the
scope of this document.</t>
      <t>Additionally, in the same way as a DS might allow its clients to block certain
messages from specific clients in the context of spam prevention, it may do the
same based on abusive or illegal content.</t>
    </section>
    <section anchor="security-considerations">
      <name>Security considerations</name>
      <t>TODO: There is currently no consensus in the MIMI w.r.t. the security goals we
want to reach.</t>
      <t>The underlying MLS protocol provides end-to-end encryption and authentication
for all MLSMessages, as well as group state agreement.</t>
      <section anchor="transport-security">
        <name>Transport Security</name>
        <t>Transport of DSFanoutRequests, as well as their responses MUST use a recipient
authenticated transport. This is to ensure that these messages are mutually
authenticated.</t>
        <t>To protect the metadata in all request-response flows, requests and responses
SHOULD be secured using an encrypted transport channel.</t>
      </section>
    </section>
  </middle>
  <back>
    <references anchor="sec-normative-references">
      <name>Normative References</name>
      <reference anchor="RFC9420">
        <front>
          <title>The Messaging Layer Security (MLS) Protocol</title>
          <author fullname="R. Barnes" initials="R." surname="Barnes"/>
          <author fullname="B. Beurdouche" initials="B." surname="Beurdouche"/>
          <author fullname="R. Robert" initials="R." surname="Robert"/>
          <author fullname="J. Millican" initials="J." surname="Millican"/>
          <author fullname="E. Omara" initials="E." surname="Omara"/>
          <author fullname="K. Cohn-Gordon" initials="K." surname="Cohn-Gordon"/>
          <date month="July" year="2023"/>
          <abstract>
            <t>Messaging applications are increasingly making use of end-to-end security mechanisms to ensure that messages are only accessible to the communicating endpoints, and not to any servers involved in delivering messages. Establishing keys to provide such protections is challenging for group chat settings, in which more than two clients need to agree on a key but may not be online at the same time. In this document, we specify a key establishment protocol that provides efficient asynchronous group key establishment with forward secrecy (FS) and post-compromise security (PCS) for groups in size ranging from two to thousands.</t>
          </abstract>
        </front>
        <seriesInfo name="RFC" value="9420"/>
        <seriesInfo name="DOI" value="10.17487/RFC9420"/>
      </reference>
      <reference anchor="RFC2181">
        <front>
          <title>Clarifications to the DNS Specification</title>
          <author fullname="R. Elz" initials="R." surname="Elz"/>
          <author fullname="R. Bush" initials="R." surname="Bush"/>
          <date month="July" year="1997"/>
          <abstract>
            <t>This document considers some areas that have been identified as problems with the specification of the Domain Name System, and proposes remedies for the defects identified. [STANDARDS-TRACK]</t>
          </abstract>
        </front>
        <seriesInfo name="RFC" value="2181"/>
        <seriesInfo name="DOI" value="10.17487/RFC2181"/>
      </reference>
      <reference anchor="RFC8446">
        <front>
          <title>The Transport Layer Security (TLS) Protocol Version 1.3</title>
          <author fullname="E. Rescorla" initials="E." surname="Rescorla"/>
          <date month="August" year="2018"/>
          <abstract>
            <t>This document specifies version 1.3 of the Transport Layer Security (TLS) protocol. TLS allows client/server applications to communicate over the Internet in a way that is designed to prevent eavesdropping, tampering, and message forgery.</t>
            <t>This document updates RFCs 5705 and 6066, and obsoletes RFCs 5077, 5246, and 6961. This document also specifies new requirements for TLS 1.2 implementations.</t>
          </abstract>
        </front>
        <seriesInfo name="RFC" value="8446"/>
        <seriesInfo name="DOI" value="10.17487/RFC8446"/>
      </reference>
      <reference anchor="I-D.ietf-mls-protocol">
        <front>
          <title>The Messaging Layer Security (MLS) Protocol</title>
          <author fullname="Richard Barnes" initials="R." surname="Barnes">
            <organization>Cisco</organization>
          </author>
          <author fullname="Benjamin Beurdouche" initials="B." surname="Beurdouche">
            <organization>Inria &amp; Mozilla</organization>
          </author>
          <author fullname="Raphael Robert" initials="R." surname="Robert">
            <organization>Phoenix R&amp;D</organization>
          </author>
          <author fullname="Jon Millican" initials="J." surname="Millican">
            <organization>Meta Platforms</organization>
          </author>
          <author fullname="Emad Omara" initials="E." surname="Omara">
            <organization>Google</organization>
          </author>
          <author fullname="Katriel Cohn-Gordon" initials="K." surname="Cohn-Gordon">
            <organization>University of Oxford</organization>
          </author>
          <date day="27" month="March" year="2023"/>
          <abstract>
            <t>Messaging applications are increasingly making use of end-to-end security mechanisms to ensure that messages are only accessible to the communicating endpoints, and not to any servers involved in delivering messages.  Establishing keys to provide such protections is challenging for group chat settings, in which more than two clients need to agree on a key but may not be online at the same time.  In this document, we specify a key establishment protocol that provides efficient asynchronous group key establishment with forward secrecy (FS) and post-compromise security (PCS) for groups in size ranging from two to thousands.
            </t>
          </abstract>
        </front>
        <seriesInfo name="Internet-Draft" value="draft-ietf-mls-protocol-20"/>
      </reference>
    </references>
  </back>
  <!-- ##markdown-source:
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
coO2iNwnStvRx5nQA1VbUNb+H6e5pl5/hQAA

-->

</rfc>
