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

<t>The MIMI Policy Envelope describes a <em>policy control protocol</em> and
<em>participation control protocol</em> for use in a room, applied at the user
participation level, as described by <xref target="I-D.barnes-mimi-arch"/>.</t>
    </abstract>
    <note removeInRFC="true">
      <name>About This Document</name>
      <t>
        The latest revision of this draft can be found at <eref target="https://turt2live.github.io/ietf-mimi-policy/draft-ralston-mimi-policy.html"/>.
        Status information for this document may be found at <eref target="https://datatracker.ietf.org/doc/draft-ralston-mimi-policy/"/>.
      </t>
      <t>
        Discussion of this document takes place on the
        More Instant Messaging Interoperability Working Group mailing list (<eref target="mailto:mimi@ietf.org"/>),
        which is archived at <eref target="https://mailarchive.ietf.org/arch/browse/mimi/"/>.
        Subscribe at <eref target="https://www.ietf.org/mailman/listinfo/mimi/"/>.
      </t>
      <t>Source for this draft and an issue tracker can be found at
        <eref target="https://github.com/turt2live/ietf-mimi-policy"/>.</t>
    </note>
  </front>
  <middle>
    <?line 50?>

<section anchor="introduction">
      <name>Introduction</name>
      <t>The primary objective for the More Instant Messaging Interoperability (MIMI)
working group is to specify the needed protocols to achieve interoperability
among modern messaging providers. The protocols which make up the "MIMI stack"
are described by <xref target="I-D.barnes-mimi-arch"/>.</t>
      <t>In the stack are a policy control protocol and a participation control protocol.
These two control protocols are described by this document, supported by
<strong>TODO(TR): Link to I-D.ralston-mimi-signaling</strong>.</t>
      <t>Policy control is handled through permissions, while participation is managed
primarily through the rules governing <tt>m.room.user</tt>. Together, these control
protocols create this policy document.</t>
      <t>When an action is impossible for a server to enforce, such as when a client
operated by a user sends an encrypted instant message, the receiving clients
are responsible for enforcing the remainder of the policy. This may mean, for
example, decrypting a message but not rendering it due to a policy violation.</t>
      <t>The concepts of permissions and participation state for a user are deliberately
separated in this policy document. A user's participation state might affect
which permissions they can use, but a user's permissions do not change their
participation in a room.</t>
    </section>
    <section anchor="conventions-and-definitions">
      <name>Conventions and Definitions</name>
      <t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
appear in all capitals, as shown here.</t>
      <?line -18?>

<t>Terms from <xref target="I-D.barnes-mimi-arch"/> and <xref target="I-D.ralston-mimi-terminology"/> are
used throughout this document. <xref target="I-D.barnes-mimi-arch"/> takes precedence where
there's conflict.</t>
      <t>Terms from <strong>TODO(TR): Link to I-D.ralston-mimi-signaling</strong> are used throughout
this document.</t>
      <t>Other terms include:</t>
      <t><em>Rejected</em>: The action being performed ceases to continue through the remainder
of the send/rendering steps. For a hub server, this means the event being sent
is not added to the room and is not sent to any other server. For a client, this
equates to not rendering or respecting the action.</t>
      <t><em>Allowed</em>: The opposite of Rejected. The action is expressly permitted to occur.</t>
      <t><em>"Engaging with the room"</em>: The user is able to take some actions and send
messages in the room, provided the remainder of the policy allows them to do
that. The encryption/security layer <bcp14>MAY</bcp14> further restrict a user's ability to
take action. For example, the user might need 1 or more clients to be able to
successfully send a message.</t>
      <section anchor="permissions-definitions">
        <name>Permissions Definitions</name>
        <t><em>Action</em>: Something a user does in the context of a room. For example, invite
another user or send a message to the room.</t>
        <t><em>Permission</em>: A flag which allows (or rejects) execution of an action.</t>
        <t><em>Role</em>: A user-defined set of permissions. Users are added to roles to gain the
included permissions.</t>
      </section>
      <section anchor="participation-definitions">
        <name>Participation Definitions</name>
        <t><em>Target</em>: The user affected by a participation state.</t>
        <t><em>Sender</em>: The user affecting a target user with a participation state.</t>
        <t><em>Invited</em>: The target is given the choice to accept the invite (join the room)
or decline (leave the room).</t>
        <t><em>Joined</em>: The target is capable of engaging with the room.</t>
        <t><em>Left</em>: The target has either voluntarily chosen to leave the room, or has been
removed with a kick.</t>
        <t><em>Banned</em>: The target is kicked and cannot be invited, joined, or knock on the
room until unbanned.</t>
        <t><em>Knocking</em>: The sender is requesting an invite into the room. They can either
be welcomed in (invited) or declined (kicked).</t>
        <t><em>Kicked</em>: Involuntary leave. The target and sender are not the same user.</t>
      </section>
    </section>
    <section anchor="event-authorization">
      <name>Event Authorization</name>
      <t>When a hub server receives an event, and before it adds it to the room, it <bcp14>MUST</bcp14>
ensure the event passes the policy for the room. In the case of this document,
the server <bcp14>MUST</bcp14> ensure the following checks are performed:</t>
      <ol spacing="normal" type="1"><li>The event is correctly signed and hashed.</li>
        <li>The event's <tt>authEvents</tt> include the appropriate event types
(<xref target="int-auth-selection"/>).</li>
        <li>The <tt>sender</tt> has permission (<xref target="int-calc-permissions"/>) to send the event.</li>
        <li>Any event type-specific checks are performed, as described throughout this
document.</li>
      </ol>
      <section anchor="int-auth-selection">
        <name>Auth Events Selection</name>
        <t>When a server is populating <tt>authEvents</tt>, it <bcp14>MUST</bcp14> include the event IDs for the
following event types. These <bcp14>SHOULD</bcp14> be the most recent event IDs for the event
types.</t>
        <t>Note: <tt>m.room.create</tt> <bcp14>MUST</bcp14> always have an empty <tt>authEvents</tt> array.</t>
        <ul spacing="normal">
          <li>The <tt>m.room.create</tt> event.</li>
          <li>The <tt>m.room.user</tt> event for the <tt>sender</tt>, if applicable.</li>
          <li>The <tt>m.room.role_map</tt> event (<xref target="int-permissions"/>), if set.</li>
          <li>The <tt>m.room.role</tt> events (<xref target="int-permissions"/>) assigned to the user <tt>sender</tt>,
if any.</li>
          <li>
            <t>If the event type is <tt>m.room.user</tt>:  </t>
            <ul spacing="normal">
              <li>The target user's <tt>m.room.user</tt> event, if any.</li>
              <li>If the <tt>participation</tt> state is <tt>join</tt> or <tt>invite</tt>, the <tt>m.room.join_rules</tt>
event (<xref target="int-ev-join-rules"/>), if any.</li>
            </ul>
          </li>
        </ul>
        <t><strong>TODO(TR): Restricted joins join_authorised_via_users_server?
(<eref target="https://github.com/turt2live/ietf-mimi-policy/issues/1">GH issue</eref>)</strong></t>
        <t>If an event is missing from <tt>authEvents</tt> but should have been included with the
above selection algorithm, the event is rejected.</t>
        <t>If events not intended to be selected using the above algorithm above are
included in <tt>authEvents</tt>, the event is rejected. This extends to events which
aren't known or are malformed in <tt>authEvents</tt>.</t>
        <t>If an event uses non-current events in its <tt>authEvents</tt>, it is rejected.</t>
      </section>
    </section>
    <section anchor="types-of-senders">
      <name>Types of Senders</name>
      <t><strong>TODO(TR): Do we want to send as not-users?
(<eref target="https://github.com/turt2live/ietf-mimi-policy/issues/2">GH issue</eref>)</strong></t>
      <t>Currently this document only supports <tt>sender</tt> being a user ID.</t>
    </section>
    <section anchor="int-permissions">
      <name>Permissions</name>
      <t>Rooms are capable of defining their own roles for grouping permissions to apply
to users. These roles do not currently have aesthetic characteristics, such as
a display name, badge color, or avatar.</t>
      <t>Roles are described by an <tt>m.room.role</tt> state event. The state key for the event
is the "role ID", and is not intended to be human readable.</t>
      <t>The content for the event has the following structure in TLS presentation
language format (<xref section="3" sectionFormat="of" target="RFC8446"/>):</t>
      <artwork><![CDATA[
enum {
   // Iterated later in the document.
} Permission;

struct {
   select (Permission) {
      // cases defined later in the document.
   } permission;
} PermissionValue;

struct {
   PermissionValue permissions[];
} MRoomRoleEventContent;
]]></artwork>
      <t>Users are assigned to roles using an <tt>m.room.role_map</tt> state event, with empty
string for a state key. The content being as follows:</t>
      <artwork><![CDATA[
struct {
   // The role's ID.
   opaque roleId;

   // The user IDs who are assigned this role.
   opaque userIds[];

   // The power level for the role. This is used in cases of tiebreak and to
   // override permissions from another role.
   uint32 order;
} RoleConfig;

struct {
   RoleConfig roles[];
} MRoomRoleMapEventContent;
]]></artwork>
      <t>Each role ID <bcp14>MUST</bcp14> only appear once in <tt>MRoomRoleMapEventContent.roles</tt>. Each
<tt>RoleConfig.order</tt> <bcp14>MUST</bcp14> be distinct from all other entries. If either of these
checks fail when a server receives the event, the event is rejected.</t>
      <section anchor="int-calc-permissions">
        <name>Calculating Permissions</name>
        <t>A user's permissions is the sum of the permissions described by their assigned
roles. When two roles define the same permission (but with different values),
the higher <tt>order</tt> role takes precedence.</t>
        <t>For example, if given the following role structure...</t>
        <ul spacing="normal">
          <li>
            <t>Role A, order 1.
            </t>
            <ul spacing="normal">
              <li>Permission A = true</li>
              <li>Permission B = false</li>
            </ul>
          </li>
          <li>
            <t>Role B, order 2.
            </t>
            <ul spacing="normal">
              <li>Permission A = false</li>
              <li>Permission C = false</li>
            </ul>
          </li>
          <li>
            <t>Role C, order 3.
            </t>
            <ul spacing="normal">
              <li>Permission B = true</li>
              <li>Permission C = false</li>
            </ul>
          </li>
        </ul>
        <t>... and a user assigned all three roles, the user's resolved set of permissions
would be:</t>
        <ul spacing="normal">
          <li>Permission A = false (takes Role B's value)</li>
          <li>Permission B = true (takes Role C's value)</li>
          <li>Permission C = false (defined by Role B, no conflict with Role C)</li>
        </ul>
        <t>These permissions are then used to define whether a user can "send" the event.</t>
      </section>
      <section anchor="int-effective-power">
        <name>Effective Power Level</name>
        <t>In some cases it is required to know the "power level" for a user to solve
tiebreaks. The power level of a user is the highest <tt>order</tt> role they are
assigned with the desired permission set, regardless of value for that
permission.</t>
        <t>Using the example from <xref target="int-calc-permissions"/>, a user with all three roles
would have the following effective power levels for each permission in question:</t>
        <ul spacing="normal">
          <li>Permission A = 2</li>
          <li>Permission B = 3</li>
          <li>Permission C = 3</li>
        </ul>
      </section>
      <section anchor="list-of-permissions">
        <name>List of Permissions</name>
        <t>The full definitions for <tt>Permission</tt> and <tt>PermissionValue</tt> in
<xref target="int-permissions"/> is:</t>
        <artwork><![CDATA[
enum {
   // Whether other users can be invited to the room by the role.
   // Default: false.
   invite(1),

   // Whether other users can be kicked from the room by the role.
   // Default: false.
   kick(2),

   // Whether other users can be banned from the room by the role.
   // Default: false.
   ban(3),

   // Whether another user's events can be redacted by the role.
   // Senders can always redact their own events regardless of this permission.
   // Default: false.
   redact(4), // TODO(TR): Do we need this one?

   // The event types the role is able to send.
   // Default: None.
   events(5),

   // The actions this role can take against roles. For example, adding or
   // removing permissions.
   // Default: None.
   roles(6),
} Permission;

struct {
   select (Permission) {
      case invite: BooleanPermission;
      case kick: BooleanPermission;
      case ban: BooleanPermission;
      case redact: BooleanPermission;
      case events: EventTypePermission;
      case roles: RolePermission;
   } permission;
} PermissionValue;

struct {
   // When false, the permission is explicitly not granted.
   byte granted;
} BooleanPermission;

struct {
   // The event type being gated by a permission.
   opaque eventType;

   // When false, the permission to send the event is explicitly not granted.
   byte granted;
} EventTypePermissionRecord;

struct {
   // The event type restrictions. If there are duplicates, the lastmost entry
   // takes priority.
   EventTypePermissionRecord eventTypes[];
} EventTypePermission;

struct {
   // The role IDs that can be affected by this role. This includes adding,
   // removing, and changing permissions.
   // TODO(TR): We might want something more comprehensive.
   opaque affectRoleId[];
} RolePermission;
]]></artwork>
      </section>
      <section anchor="event-sending-permissions">
        <name>Event Sending Permissions</name>
        <t>The <tt>sender</tt> for an event <bcp14>MUST</bcp14> have permission (<xref target="int-calc-permissions"/>) to
send that event type, unless the event type is <tt>m.room.user</tt>. User participation
events are handled specifically in <xref target="int-user-participation"/>.</t>
        <t>The <tt>sender</tt> <bcp14>MUST</bcp14> also be in the joined state to send such events.</t>
      </section>
      <section anchor="role-changes">
        <name>Role Changes</name>
        <t><strong>TODO(TR): I believe we need words to describe how to use the role permissions
described above. Probably something using effective power levels and talking
about what "add", "remove", and "change" actually mean.</strong></t>
        <t><strong>TODO(TR): We also need to specify that the creator has superuser permissions
until a role is defined/assigned.</strong></t>
      </section>
    </section>
    <section anchor="int-user-participation">
      <name>User Participation</name>
      <t>User participation is tracked as <tt>m.room.user</tt> state events. The <tt>content</tt> for
such an event has the following structure in TLS presentation language format
(<xref section="3" sectionFormat="of" target="RFC8446"/>):</t>
      <artwork><![CDATA[
enum {
   invite,  // "Invited" state.
   join,    // "Joined" state.
   leave,   // "Left" state (including Kicked).
   ban,     // "Banned" state.
   knock    // "Knocking" state.
} ParticipationState;

struct {
   ParticipationState participation;
   opaque reason;  // optional reason for the participation state
} MRoomUserEventContent;
]]></artwork>
      <t>A user is considered to be "joined" to a room if they have a participation state
of <tt>join</tt>. All servers with users in the joined state are considered to be "in"
the room.</t>
      <t>Servers which are in the room can send events for their users directly. The
signaling protocol is able to assist servers (and therefore users) in sending
the appropriate participation events until they are able complete the join
process.</t>
      <section anchor="general-conditions">
        <name>General Conditions</name>
        <t><strong>TODO(TR): This is where we'd put server ACLs.
(<eref target="https://github.com/turt2live/ietf-mimi-policy/issues/3">GH issue</eref>)</strong></t>
      </section>
      <section anchor="invite-conditions">
        <name>Invite Conditions</name>
        <t>The target user for an invite <bcp14>MUST</bcp14>:</t>
        <ul spacing="normal">
          <li>NOT already be in the banned state.</li>
          <li>NOT already be in the joined state.</li>
        </ul>
        <t>The sender for an invite <bcp14>MUST</bcp14>:</t>
        <ul spacing="normal">
          <li>Already be in the joined state.</li>
          <li>Have permission (<xref target="int-calc-permissions"/>) to invite users.</li>
        </ul>
        <t>Otherwise, reject.</t>
      </section>
      <section anchor="join-conditions">
        <name>Join Conditions</name>
        <t>The target and sender of a join <bcp14>MUST</bcp14> be the same.</t>
        <t>Whether a user can join without invite is dependent on the join rules
(<xref target="int-ev-join-rules"/>).</t>
        <t>If the join rule is <tt>invite</tt> or <tt>knock</tt>, the user <bcp14>MUST</bcp14> already be in the joined
or invite state.</t>
        <t>If the join rule is <tt>public</tt>, the user <bcp14>MUST NOT</bcp14> already be in the banned state.</t>
        <t>Otherwise, reject.</t>
      </section>
      <section anchor="knock-conditions">
        <name>Knock Conditions</name>
        <t>The target and sender of a knock <bcp14>MUST</bcp14> be the same.</t>
        <t>If the current join rule (<xref target="int-ev-join-rules"/>) for the room is <tt>knock</tt>, the
user <bcp14>MUST NOT</bcp14> already be in the banned or joined state.</t>
        <t>Otherwise, reject.</t>
      </section>
      <section anchor="ban-conditions">
        <name>Ban Conditions</name>
        <t>The sender for a ban <bcp14>MUST</bcp14>:</t>
        <ul spacing="normal">
          <li>Already be in the joined state.</li>
          <li>Have permission (<xref target="int-calc-permissions"/>) to ban users.</li>
        </ul>
        <t>Otherwise, reject.</t>
        <t>Note that a ban implies kick.</t>
      </section>
      <section anchor="leave-conditions">
        <name>Leave Conditions</name>
        <t>Leaves in a room come in two varieties: voluntary and kicks. Voluntary leaves
are when the user no longer wishes to be an active participant in the room. A
kick is done to remove a user forcefully.</t>
        <t>When the target and sender of a leave is the same, it is a voluntary leave.</t>
        <section anchor="voluntary">
          <name>Voluntary</name>
          <t>The user <bcp14>MUST</bcp14> be in the invited, joined, or knocking state.</t>
          <t>Otherwise, reject.</t>
        </section>
        <section anchor="kicks">
          <name>Kicks</name>
          <t>The target user for a kick <bcp14>MUST</bcp14>:</t>
          <ul spacing="normal">
            <li>Already be in the joined state.</li>
          </ul>
          <t>The sender for a kick <bcp14>MUST</bcp14>:</t>
          <ul spacing="normal">
            <li>Already be in the joined state.</li>
            <li>Have permission (<xref target="int-calc-permissions"/>) to kick users.</li>
            <li>Have a higher (and NOT equal to) effective power level with respect to the
kick permission (<xref target="int-effective-power"/>) than the target user.</li>
          </ul>
          <t>If the target user is in the banned state, the sender requires permission to
ban users instead (as to ban means to unban as well). This additionally extends
to the effective power level check.</t>
          <t>Otherwise, reject.</t>
        </section>
      </section>
      <section anchor="int-ev-join-rules">
        <name><tt>m.room.join_rules</tt></name>
        <t><strong>State key</strong>: Empty string.</t>
        <t><strong>Content</strong>:</t>
        <artwork><![CDATA[
enum {
   invite,
   knock,
   public,
} JoinRule;

struct {
  // The current join rule for the room. Defaults to `invite` if no join rules
  // event is in the room.
  JoinRule rule;
} MRoomJoinRulesEventContent;
]]></artwork>
        <t><strong>Redaction considerations</strong>: <tt>rule</tt> under <tt>content</tt> is protected from
redaction.</t>
      </section>
    </section>
    <section anchor="eventhistory-visibility">
      <name>Event/History Visibility</name>
      <t>Unless otherwise specified by the event type, non-state events <bcp14>MUST NOT</bcp14> be sent
to a user's client if the history visibility rules prohibit it. State events
are always visible to clients.</t>
      <t>When a server is fetching events it is missing to build history, the returned
events are redacted unless the server has at least one user which is able to
see the event under the history visibility rules. The server must then further
filter the events before sending them to clients.</t>
      <t>History visibility rules are defined by <tt>m.room.history_visibility</tt>
(<xref target="int-ev-history-viz"/>), and can only affect future events. Events sent before
the history visibility rule change are not retroactively affected.</t>
      <t>Taking into consideration the <tt>m.room.history_visibility</tt> event that is current
at the time an event was sent, a user's visibility of a that event is described
as:</t>
      <ul spacing="normal">
        <li>If the visibility rule was <tt>world</tt>, show.</li>
        <li>If the user was in the joined state, show.</li>
        <li>If the visibility rule was <tt>shared</tt> and the user was in the joined state at
any point after the event was sent, show.</li>
        <li>If the user was in the invited state, and the visibility rule was <tt>invited</tt>,
show.</li>
        <li>Otherwise, don't show.</li>
      </ul>
      <section anchor="int-ev-history-viz">
        <name><tt>m.room.history_visibility</tt></name>
        <t><strong>State key</strong>: Empty string.</t>
        <t><strong>Content</strong>:</t>
        <artwork><![CDATA[
enum {
   invited,
   joined,
   shared,
   world,
} Visibility;

struct {
  // The current join rule for the room. Defaults to `shared` if no history
  // visibility event is present in the room.
  Visibility visibility;
} MRoomHistoryVisibilityEventContent;
]]></artwork>
        <t><strong>Redaction considerations</strong>: <tt>visibility</tt> under <tt>content</tt> is protected from
redaction.</t>
      </section>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <t>This document as a whole makes up the <tt>m.0</tt> policy ID, as per
<strong>TODO(TR): Link to I-D.ralston-mimi-signaling</strong>.</t>
      <t>This document's descriptions for the following event types are registered to the
event types registry in <strong>TODO(TR): Link to I-D.ralston-mimi-signaling</strong>:</t>
      <ul spacing="normal">
        <li>
          <tt>m.room.role</tt> (<xref target="int-permissions"/>)</li>
        <li>
          <tt>m.room.role_map</tt> (<xref target="int-permissions"/>)</li>
        <li>
          <tt>m.room.join_rules</tt> (<xref target="int-ev-join-rules"/>)</li>
        <li>
          <tt>m.room.history_visibility</tt> (<xref target="int-ev-history-viz"/>)</li>
      </ul>
    </section>
  </middle>
  <back>
    <references>
      <name>References</name>
      <references>
        <name>Normative References</name>
        <reference anchor="I-D.barnes-mimi-arch">
          <front>
            <title>An Architecture for More Instant Messaging Interoperability (MIMI)</title>
            <author fullname="Richard Barnes" initials="R." surname="Barnes">
              <organization>Cisco</organization>
            </author>
            <date day="22" month="September" year="2023"/>
            <abstract>
              <t>   The More Instant Messaging Interoperability (MIMI) working group is
   defining a suite of protocols that allow messaging providers to
   interoperate with one another.  This document lays out an overall
   architecture enumerating the MIMI protocols and how they work
   together to enable an overall messaging experience.

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

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ralston-mimi-terminology-02"/>
        </reference>
      </references>
      <references>
        <name>Informative References</name>
        <reference anchor="RFC8446">
          <front>
            <title>The Transport Layer Security (TLS) Protocol Version 1.3</title>
            <author fullname="E. Rescorla" initials="E." surname="Rescorla"/>
            <date month="August" year="2018"/>
            <abstract>
              <t>This document specifies version 1.3 of the Transport Layer Security (TLS) protocol. TLS allows client/server applications to communicate over the Internet in a way that is designed to prevent eavesdropping, tampering, and message forgery.</t>
              <t>This document updates RFCs 5705 and 6066, and obsoletes RFCs 5077, 5246, and 6961. This document also specifies new requirements for TLS 1.2 implementations.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8446"/>
          <seriesInfo name="DOI" value="10.17487/RFC8446"/>
        </reference>
      </references>
    </references>
  </back>
  <!-- ##markdown-source:
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

-->

</rfc>
