From 6e4f5ad566ad2328ff6d16e02f04275cb95186ec Mon Sep 17 00:00:00 2001 From: Micke Nordin Date: Tue, 9 Jun 2026 23:49:52 +0200 Subject: [PATCH 1/4] OCM-MLS: I-D for MLS over OCM --- .gitignore | 2 + IETF-OCM-MLS.md | 1914 +++++++++++++ IETF-OCM-MLS.xml | 2665 ++++++++++++++++++ work/mls-over-ocm/cm-mls-federated-groups.md | 883 ------ 4 files changed, 4581 insertions(+), 883 deletions(-) create mode 100644 IETF-OCM-MLS.md create mode 100644 IETF-OCM-MLS.xml delete mode 100644 work/mls-over-ocm/cm-mls-federated-groups.md diff --git a/.gitignore b/.gitignore index 487cffc..8d868a6 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ *-design.md +draft-nordin-*.txt +IETF-OCM-MLS.txt diff --git a/IETF-OCM-MLS.md b/IETF-OCM-MLS.md new file mode 100644 index 0000000..1d12777 --- /dev/null +++ b/IETF-OCM-MLS.md @@ -0,0 +1,1914 @@ +--- +title: >- + Federated Groups in Open Cloud Mesh using Messaging Layer Security +abbrev: "OCM MLS Federated Groups" +docname: draft-nordin-ocm-mls-federated-groups-00 +category: std + +ipr: trust200902 +area: Applications and Real-Time +keyword: Internet-Draft + +stand_alone: yes +stream: IETF + +author: + - ins: M. Nordin + name: Micke Nordin + organization: SUNET + email: kano@sunet.se + uri: https://code.smolnet.org/micke + + - ins: G. Lo Presti + name: Giuseppe Lo Presti + organization: CERN + email: giuseppe.lopresti@cern.ch + uri: https://cern.ch/lopresti + + - ins: M. Baghbani + name: Mahdi Baghbani + organization: Ponder Source + email: mahdi@pondersource.org + uri: https://pondersource.com + +--- abstract + +This document defines an extension to the Open Cloud Mesh (OCM) protocol +to support federated groups as Receiving Parties of shares. This is +achieved using the Messaging Layer Security (MLS) protocol (RFC 9420) as +a group management layer. MLS is used for establishing and rotating a +shared group key across federated group members, as well as for +maintaining group state. This gives not only a way of federating group +membership, but also a standardized way of distributing encryption keys +in a cryptographically secure way, so that files shared with a group can +optionally be encrypted and decrypted. MLS usage in OCM acts as a +vehicle for group management that gives users optional encryption +capabilities for resources shared with federated groups. + +--- middle + +# Introduction + +Open Cloud Mesh [OCM] currently supports sharing resources with +individual users across federated servers and with groups on a single +server. The specification also defines a `shareType` of `"federation"` +but does not further specify its semantics. This document gives +`"federation"` a concrete definition: a federated group identified by an +OCM Address such as `research-group@receiver.example.org` whose membership +spans multiple OCM servers, with group state managed through the MLS +[RFC9420] epoch mechanism. + +In many Enterprise File Sync and Share (EFSS) systems, which constitute +the vast majority of all OCM Servers, there is a tight coupling between +a client and a server, because the server offers a built-in web +interface as its primary client. In addition to this, a sync client is +often offered as a way of syncing files between the EFSS system and the +user's devices. + +In MLS, a client is defined as an agent that establishes shared +cryptographic state with other clients, defined by the cryptographic +keys it holds. An EFSS server meets this definition directly. For +deployments where the primary user interface is a web client, the OCM +Server fulfils the MLS client role server-side, holding key material on +behalf of its users, and the word "client" as used in this document +should not necessarily be taken to mean the user's file sync client. +Implementations that do provide a native client application SHOULD +perform cryptographic operations in the native client on the user's +devices, rather than on the server, because this provides stronger +isolation of key material from the server. In either case the same MLS +client model applies. + +Each user who is a member of a federated group has their own MLS leaf +node, enabling individual users to be added and removed independently. +The OCM Server can act as the MLS client on behalf of its users. For +implementations where the primary interface is a web client, the OCM +Server holds and uses key material server-side. Implementations with a +native client application SHOULD perform cryptographic operations in the +native client, with the server acting as a relay for MLS messages. + +Throughout this document, actions described as being performed by an OCM +server are understood to be performed by that server in its capacity as +an MLS client, on behalf of one of its users. The server holds no group +membership or cryptographic state independent of its users. + +The group and its membership exist and evolve independently of any +sharing activity. A user that wants to share a resource with a group +can do so without the need to know the current membership details of +that group. The MLS Delivery Service role is distributed: proposals are +delivered to the home servers of all admins, the Group Owner Server +arbitrates Commits, and File Key (FK) distribution messages are sent +directly from sending servers to member servers, just like OCM share +notifications. Group membership changes are managed entirely through +MLS group lifecycle operations. + +Every group has one or more admins: users who administer the group. The +user who creates a group is its first admin. Adding a member, or +removing a member other than oneself, requires the approval of an admin, +placing a human in the loop for changes that grant or revoke access. +Any member can remove themselves from a group without admin approval, +though the Commit is still performed by an admin client. All Commits +that advance the MLS epoch are constructed by the MLS clients of admins +and arbitrated by the Group Owner Server. + +The group's OCM Address is a stable label. It is minted under the +domain of the server where the group was created, which guarantees its +uniqueness, but it carries no routing semantics: all protocol messages +are routed using the OCM Addresses of individual members and admins, +never the group's. + +Files shared with a group can optionally be encrypted with a per-file +key (FK), wrapped with the current group key. The group key is derived +from the MLS epoch secret and rotates with every epoch transition. On +every epoch transition the sending server re-wraps the FK under the new +group key and redistributes it, so that the current group key is always +sufficient to unwrap the current FK. When a member is added to a group, +their MLS client receives the new group key and the re-wrapped FKs, and +can immediately decrypt all resources shared with the group. + +When a member is removed from the group, sending servers MAY +additionally generate a new FK and re-encrypt affected resources, +depending on their policy and the nature of the shared data. + +# Terminology + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and +"OPTIONAL" in this document are to be interpreted as described in BCP 14 +[RFC2119] [RFC8174] when, and only when, they appear in all capitals, as +shown here. + +This document uses terminology from [OCM] and [RFC9420]. Additional +definitions: + +- **Group** - A Receiving Party identified by an OCM Address whose +identifier resolves to a set of members spanning multiple OCM servers, +with group state managed through MLS. The Group's OCM Address is a +stable label assigned at creation and MUST NOT change for the lifetime +of the Group; it carries no routing semantics. In [RFC9420] a group is +defined as: "a logical collection of clients that share a common secret +value at any given time. Its state is represented as a linear sequence +of epochs in which each epoch depends on its predecessor." +- **MLS Client** - As defined in [RFC9420]: an agent that establishes +shared cryptographic state with other clients, defined by the +cryptographic keys it holds. In this protocol an OCM Server can fulfill +this role. +- **Member Server** - An OCM server with one or more users who are +members of a given Group, acting as MLS client on their behalf. +- **Group Owner Server** - The server currently arbitrating Commits for +the Group: the home server of the first Admin in the admin set. +Initially this is the server at which the Group was created. +- **Admin** - A user who administers the Group membership. The user who +creates a Group is its first Admin. Only the MLS clients of Admins +(admin clients) construct Commits. The admin set is part of the group +state ({{admin-set}}). +- **Admin Server** - The home server of an Admin. Admin Servers +collectively queue proposals for the Group. +- **Group Key** - A symmetric key derived from the current MLS epoch +secret via the MLS Exporter, with the key length of the AEAD algorithm +of the group's cipher suite. Rotates with every epoch transition. +- **File Key (FK)** - A random symmetric key used to encrypt a single +shared resource. Wrapped with the current Group Key and distributed to +Member Servers via MLS Application Messages. Re-wrapped under the new +Group Key on every epoch transition ({{fk-rewrap}}). Member Servers +always store the most current wrapped FK for each resource. +- **Re-encryption mode** - On member removal, the sending server +generates a new FK, re-encrypts the resource, and distributes the new +wrapped key. Provides strong cryptographic guarantees independent of +trust assumptions. +- **Key-reuse mode** - On member removal, the existing FK is kept and +only the standard re-wrap on epoch change ({{fk-rewrap}}) is performed, +without re-encrypting the resource. Appropriate only within formally +trusted federations and where re-encryption is impractical. Mode is not +a binary choice; sending servers can choose one mode for one epoch and +another mode for another epoch, depending on policy and other +circumstances. +- **KeyPackage** - As defined in [RFC9420]. A signed object that +enables adding an MLS client to a group asynchronously. KeyPackages +MUST be used only once, except for a designated last resort KeyPackage +([RFC9420] Section 16.8). + +# MLS Roles in OCM + +MLS is designed to operate with two supporting services: an +Authentication Service (AS) and a Delivery Service (DS) ([RFC9420] +Section 3; see also the MLS architecture [RFC9750]). This section +describes how those roles are fulfilled by OCM. + +## Authentication Service + +The AS role is fulfilled by each user's home OCM server. Credentials in +this protocol are MLS basic credentials ([RFC9420] Section 5.3) whose +identity field is the UTF-8 encoded OCM Address of the user. Each user +has their own distinct signing key pair so that individual users can be +identified and addressed independently within the MLS group, for example +to add or remove a specific user. In web-client deployments the key +pair is generated and held by the OCM Server on the user's behalf. In +native client deployments the key pair is held on the user's device and +the server's role is limited to publishing the user's KeyPackages. + +A basic credential carries no verifiable binding of its own; the binding +between a user's OCM Address and their signature key is attested by +authenticated delivery from the user's home server. A KeyPackage +fetched over TLS from the `/mls-key-packages` endpoint of the +server named in the credential's OCM Address, with the response signed +using HTTP Signatures [RFC9421] verifying against that server's JWKS +endpoint at `/.well-known/jwks.json` [RFC7517], is considered validated +with the AS. The full validation procedure, including how credentials +introduced later in the life of a group are validated, is specified in +{{trust-and-authentication}}. + +## Delivery Service + +The DS role is distributed across the servers of the group rather than +centralised on a single server. MLS places no constraints on how the DS +is arranged, as long as messages are delivered ([RFC9420] Section 3). + +- Proposal delivery: `MLS_PROPOSAL` notifications are sent to the home +server of every admin ({{admins}}), derived from the admin set and the +OCM Addresses in the ratchet tree's leaf credentials. Admin Servers +queue proposals, deduplicated by ProposalRef ([RFC9420] Section 5.2), +and make them available to their admin clients. +- Commit arbitration: the Group Owner Server, the home server of the +first admin in the admin set, accepts exactly one Commit per epoch from +an admin client and broadcasts it to all Member Servers. +- FK distribution: `MLS_APPLICATION` messages carrying wrapped file keys +are sent directly from the sending server to all current Member Servers, +exactly like OCM share notifications; credential updates are sent to a +single Member Server ({{credential-update}}). + +All MLS messages are delivered to the `/notifications` +endpoint of each recipient server, authenticated with HTTP Signatures +[RFC9421]. + +Commits are constructed and signed by admin clients, but only the Commit +accepted by the Group Owner Server takes effect; competing Commits for +the same epoch are discarded by their senders. Designating a single +arbiter of Commits eliminates conflicting Commits for the same epoch +during normal operation, satisfying the sequencing requirement of +[RFC9420] Section 14; conflicting Commits can arise only during failover +and are then resolved deterministically ({{failover}}). Per [RFC9420] +Section 14, generating a Commit does not modify the sender's state, so +an admin client whose Commit is rejected simply discards it and +constructs a new Commit on the new epoch. + +OCM share notifications are sent directly from the sending server to +each Member Server. Since sending servers must be group members, they +hold the current MLS ratchet tree after processing each `MLS_COMMIT`, +and can derive the current membership - specifically the OCM Address in +each leaf node's credential - to determine which Member Servers to +contact. No proxying through the Group Owner Server is required for +OCM-level communication. + +MLS is designed to protect confidentiality and integrity even against a +misbehaving DS. No single server in this design carries the full DS +role, and no server holds key material by virtue of its DS duties; the +MLS security properties with respect to message confidentiality hold +regardless. + +# How MLS is implemented over OCM + +- **MLS for group key management only.** MLS establishes and rotates a +shared group key. The only MLS application messages used in this +protocol carry wrapped file keys ({{key-distribution}}) and per-server +transport credential updates ({{credential-update}}). + +- **At least one MLS leaf per user.** Each user who is a member of a +federated group has at least one MLS leaf node, enabling individual +users to be added and removed independently. In web-client deployments +the OCM Server manages a single leaf node per user on their behalf. In +native client deployments each user may have a leaf node per device. + +- **The OCM Server is a MLS client.** An OCM Server meets the MLS +definition of a client. For web-client deployments this means key +material is held server-side. For native client deployments +cryptographic operations SHOULD be performed in the native client. + +- **Admins approve membership changes.** Every group has one or more +admins ({{admins}}). Commits are constructed by admin clients and +arbitrated by the Group Owner Server. Add proposals and Remove +proposals targeting another user require admin approval; any member may +remove themselves, and Update proposals are committed automatically. + +- **Encryption is optional.** MLS group management is useful +independently of whether encryption is used. A federation share MAY be +unencrypted, in which case the `encryption` field is omitted from the +Share Creation Notification and the MLS layer provides only group +membership management. + +- **FK re-wrap on every epoch change.** After processing an `MLS_COMMIT` +for a group, a sending server MUST re-wrap the current FK of every +resource it shares with that group under the new Group Key and +distribute it via `MLS_APPLICATION` ({{fk-rewrap}}). This maintains the +invariant that the current Group Key is always sufficient to unwrap the +current wrapped FK. + +- **FK rotation on member removal.** On member removal, a sending server +SHOULD additionally rotate the FK for affected resources: generate a new +FK, re-encrypt the resource, and distribute the new wrapped FK to all +groups that share those resources. FK rotation may also be triggered by +other factors such as periodic key rotation policy or suspected key +compromise. Member addition does not require FK rotation; the standard +re-wrap is sufficient. + +- **Key-reuse mode as an alternative.** Where re-encryption on removal +is impractical and where participating servers are mutually trusted +within a formal federation, a sending server MAY instead keep the +existing FK, relying on the standard per-epoch re-wrap alone. + +- **Sending servers must have group members.** To share a resource with +a group, the sending server must have at least one user who is a member +of that group, allowing it to work out the members to share with, and to +be able to wrap the FK for encrypted shares. This is by design, to +mitigate spam shares and other abusive behaviour. + +- **OCM messages are still just OCM messages.** Proposals flow to the +servers of all admins, Commits are arbitrated by the Group Owner Server, +and FK distribution and OCM share notifications flow directly from the +sending server to each Member Server, derived from the sending server's +local view of group membership from the MLS ratchet tree. No message is +proxied through a single central server. + +- **Sending servers derive membership from the ratchet tree.** Since +sending servers must have group members, they process all `MLS_COMMIT` +messages and hold the current ratchet tree. The OCM Address in each +leaf node's credential identifies the corresponding Member Server. The +sending server uses this to determine which Member Servers to contact +directly for share notifications and FK distribution. + +- **Push-based FK distribution.** Wrapped file keys are distributed via +`MLS_APPLICATION` directly from the sending server to all current Member +Servers, at share creation and after every epoch transition +({{fk-rewrap}}). Member Servers always hold the current wrapped FK for +each resource and use their current Group Key to unwrap it at access +time. + +- **Minimal protocol surface.** The `shareType: "federation"` value +already defined in the OCM specification is used without modification, +with `shareWith` carrying the group's OCM Address. A federation share +is otherwise a standard OCM share, carrying every field REQUIRED by +[OCM] including the `protocol` object. All new server-to-server +messages use the existing `/notifications` endpoint with new +`notificationType` values. A single new field is added to the Share +Creation Notification: `encryption` (optional, present only for +encrypted resources), carrying all encryption-related parameters, +including the `resourceId`. + +# Discovery + +A server signals support for federation shares by including +`"federation"` in the `shareTypes` array for a given resource type in +its OCM discovery document at `/.well-known/ocm`: + +~~~ json +{ + "enabled": true, + "apiVersion": "1.4.0", + "endPoint": "https://cloud.example.org/ocm", + "provider": "Example Cloud", + "resourceTypes": [ + { + "name": "file", + "shareTypes": ["user", "group", "federation"], + "protocols": { "webdav": "/webdav/", "webdav-receive": {} } + } + ] +} +~~~ + +No additional discovery fields are introduced. The notifications +endpoint is derived as `/notifications` per the base OCM +specification. The KeyPackage endpoint is derived as +`/mls-key-packages`. + +A server that advertises `"federation"` MUST be able to receive OCM +Notifications, since all MLS lifecycle messages are delivered as +notifications, and SHOULD include `"notifications"` in its +`capabilities` array. + +# KeyPackage Distribution + +Each OCM Server acting as an MLS client generates and maintains +KeyPackages for its users and exposes them at: + +~~~ +GET /mls-key-packages?userId={userId} +~~~ + +Response: + +~~~ json +{ + "userId": "alice@cloud.example.org", + "keyPackages": [ + { + "mediaType": "message/mls", + "encoding": "base64", + "content": "" + } + ] +} +~~~ + +Requests to this endpoint MUST be signed using HTTP Message Signatures +[RFC9421] ({{security-considerations}}). + +In native client deployments, the user's device generates KeyPackages +and publishes them to the home server, which exposes them at the same +endpoint without interpreting them. + +Each KeyPackage contains an MLS Credential identifying the user by their +OCM Address, signed by the user's own signing key pair. Users who +require stronger isolation of key material from their server should use +a native client implementation. + +KeyPackages MUST be one-time use, with the exception of a designated +"last resort" KeyPackage ([RFC9420] Section 16.8). The server MUST +remove a KeyPackage after it has been delivered. Servers SHOULD +pre-generate multiple KeyPackages per user to support concurrent group +additions, MAY designate a last resort KeyPackage per user to be +returned when all single-use KeyPackages are exhausted, and SHOULD +rate-limit KeyPackage requests, so that an attacker cannot block a +user's addition to groups by exhausting their KeyPackages. KeyPackages +carry a leaf node lifetime, and applications MUST define a maximum total +lifetime they accept ([RFC9420] Section 7.2). + +The `userId` fields defined in this document carry the user's full OCM +Address, not the bare identifier that [OCM] calls `userID`; the full +address is required because these messages routinely cross server +boundaries. + +# Group Lifecycle + +The group lifecycle is entirely independent of other OCM lifecycles +(token-exchange, shares, invitations etc.). Members are added and +removed through MLS group operations conveyed via the `/notifications` +endpoint. + +## Group Creation + +The creating server creates an MLS group on behalf of one of its users +and initialises leaf nodes for each of its users who are initial +members. The creating user becomes the group's first admin +({{admins}}), making the creating server the initial Group Owner Server. +No notifications are required for this step. The group becomes +addressable at its OCM Address immediately upon creation. + +The group's OCM Address is minted under the creating server's domain, +which guarantees its uniqueness, and MUST NOT change for the lifetime of +the group. It is a label only: no protocol message is routed based on +it, and it remains valid even after the Group Owner Server role has +moved to another server. The MLS `group_id` SHOULD be a fresh random +value, as recommended by [RFC9420] Section 11. + +The creator selects the group's MLS cipher suite based on the +capabilities advertised in the prospective members' KeyPackages +([RFC9420] Section 11). Implementations of this document MUST support +the mandatory-to-implement MLS cipher suite +MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519 ([RFC9420] Section 17.1). + +## Group Admins {#admins} + +Every group has a set of admins: users who administer the group +membership. The user who creates the group is its first admin, and an +admin MAY appoint further admins. Admins are ordinary group members and +MAY be homed on any Member Server. An admin's MLS clients are referred +to as admin clients. + +Commits MUST be constructed and signed by admin clients. This is an +application-level policy on top of MLS, as anticipated by [RFC9420] +Section 16.11, and it is enforced at two points. First, the Group Owner +Server MUST reject Commits submitted by any other client. Second, every +Member Server processing an `MLS_COMMIT` MUST verify that the Commit is +signed by an admin client: a Commit is signed by the leaf indicated in +its sender field ([RFC9420] Section 6.1), and the credential at that +leaf, in the ratchet tree of the epoch in which the Commit was created, +must identify a user listed in `admins` ({{admin-set}}) as of that same +epoch. A Commit that fails this check MUST be rejected, regardless of +which server broadcast it. Because the admin set is part of the +GroupContext, every member performs this check locally; acceptance of a +Commit does not rely on trusting the Group Owner Server. + +Proposals are handled according to the following policy: + +- An Add proposal, or a Remove proposal targeting a leaf that does not +belong to the proposing user, MUST be explicitly approved by an admin +before an admin client commits it, unless both are part of a rejoin pair +as described below. This places a human in the loop for changes that +grant or revoke another party's access. +- A Remove proposal targeting a leaf that belongs to the proposing user +(self-removal) does not require admin approval. Any member MAY leave a +group at any time, and admin clients SHOULD commit self-removal +proposals automatically. +- A rejoin pair - a Remove of a leaf together with an Add of a fresh +KeyPackage whose credential carries the same OCM Address as the removed +leaf's credential ({{rejoin}}) - is identity-preserving and grants no +new party access. It does not require explicit admin approval, and +admin clients SHOULD commit rejoin pairs automatically. +- Update proposals do not require admin approval, and admin clients +SHOULD commit pending Update proposals automatically whenever they are +online. + +The group MUST have at least one admin at all times. A proposal that +would remove the last admin, including a self-removal, MUST be rejected +by the Group Owner Server until another admin has been appointed. + +Removing an admin from the group and removing an admin from the admin +set are distinct operations; when an admin's membership ends, a single +Commit combines them ({{admin-set}}). An admin MAY instead resign from +the admin set while remaining a member: this is a GroupContextExtensions +proposal only, and the resigning admin's own client MAY commit it. +Removing an admin's membership is constrained by MLS: a Commit that +removes its own committer is invalid ([RFC9420] Section 12.2). A Commit +that removes some but not all of an admin's leaves MAY be committed by +one of that admin's remaining clients, but a Commit that removes an +admin's last leaf is necessarily committed by an admin client of a +different admin. + +### Group OCM Address and Admin Set {#admin-set} + +The group's OCM Address and the admin set are part of the group state, +carried in a GroupContext extension `ocm_federated_group` ([RFC9420] +Section 13.4): + +~~~ +struct { + opaque ocm_address; +} Admin; + +struct { + opaque group_ocm_address; + Admin admins; +} OCMFederatedGroup; +~~~ + +All addresses are UTF-8 encoded OCM Addresses. The `group_ocm_address` +field carries the group's OCM Address and MUST NOT change for the +lifetime of the group. + +The `admins` list is ordered by appointment: a newly appointed admin is +appended at the end, a departing admin is deleted by the same Commit +that ends their membership or admin role (see below), and the list MUST +NOT otherwise be reordered. The home server of the first admin in the +list is the current Group Owner Server. Succession is therefore +automatic: when the first admin leaves the group or resigns as admin, +the home server of the next admin in the list becomes the Group Owner +Server. For example, if alice on server1 creates the group and appoints +bob on server2 and then charlie on server3, the list is (alice, bob, +charlie) and server1 is the Group Owner Server; after bob leaves it is +(alice, charlie); after alice then leaves it is (charlie,) and server3 +is the Group Owner Server. + +An admin client is any MLS client whose leaf credential identifies a +user listed in `admins`. Because this extension is part of the +GroupContext, it is agreed upon by all members through the MLS key +schedule, every member can verify which clients are entitled to +construct Commits and which server arbitrates them, and new members +learn the group's OCM Address and admin set from the GroupInfo in their +Welcome. Changes to the admin set are made with a +GroupContextExtensions proposal ([RFC9420] Section 12.1.7); such +proposals MUST be explicitly approved by an admin, MUST be committed by +an admin client, and MUST NOT change `group_ocm_address`. + +The admin set and the group membership are coupled: an entry in `admins` +is only meaningful while that admin has at least one leaf in the ratchet +tree. A Commit after whose application an admin would no longer have +any leaf in the ratchet tree MUST therefore also include a +GroupContextExtensions proposal deleting that admin from `admins`, and +the Group Owner Server and all Member Servers MUST reject a Commit that +would leave an entry in `admins` with no corresponding leaf in the tree. +(A rejoin pair ({{rejoin}}) that replaces an admin's leaf does not +trigger this rule, since the admin retains a leaf after the Commit.) +Because a GroupContextExtensions proposal replaces the extension list +wholesale ([RFC9420] Section 12.1.7), the proposal carries the complete +new `OCMFederatedGroup` value, with the departing admin deleted and +`group_ocm_address` unchanged. A GroupContextExtensions proposal whose +only change to the admin set is deleting admins whose leaves are removed +in the same Commit requires no separate admin approval; it follows the +approval status of the Remove proposals it accompanies, so that the +self-removal of an admin can still be committed automatically. + +Clients implementing this document MUST list the `ocm_federated_group` +extension type in the `capabilities.extensions` field of their +KeyPackages, since GroupContext extensions must be supported by every +member of the group ([RFC9420] Section 13.4). + +## Group Owner Server Failover {#failover} + +The Group Owner Server can become unavailable, leaving the group without +an arbiter and therefore unable to advance its epoch. Leaf staleness +({{leaf-key-updates}}) anchors the failover trigger: the absence of +committed Updates from a leaf is part of the group state that all +members observe identically. The other trigger condition, the absence +of broadcast Commits, is necessarily observer-dependent - a server that +missed a broadcast cannot distinguish silence from loss - which is why +divergent failover decisions are tolerated and resolved +deterministically in step 3 below. + +In addition to the update deadline, groups MUST define a takeover time +T. T MUST be longer than the update deadline, so that the staleness of +the first admin's leaf is observable before takeover is permitted. +Failover proceeds as follows: + +1. Trigger: no `MLS_COMMIT` has been broadcast for time T, and the + first admin's leaf is stale. +2. Takeover: the home server of the next admin in the admin set MAY + begin arbitrating Commits. The first Commit it arbitrates SHOULD +cover Remove proposals evicting the stale first admin's leaves, together +with the GroupContextExtensions proposal deleting them from the admin +set required by {{admin-set}}, constructed by one of its own admin +clients. This makes the takeover permanent through the normal +succession rule. +3. Conflict resolution: if a Member Server receives two different + Commits for the same epoch from two arbiters, it MUST process the +one arbitrated by the server of the admin listed earlier in the admin +set and discard the other. +4. Hold-back: a Member Server that has observed the trigger conditions + of step 1 SHOULD retain the previous epoch's group state when +processing a Commit, so that it can revert and reprocess the winning +Commit if conflict resolution later discards the one it processed first. +Retained state MUST be deleted after a bounded time, per [RFC9420] +Section 14; the security trade-off is discussed in Security +Considerations. +5. Rejoin: a Member Server that processed a discarded Commit and no + longer holds the state needed to reprocess the winning Commit has +drifted from the group. It recovers through the rejoin procedure +({{rejoin}}). Wrapped FKs are re-wrapped and redistributed by their +sending servers in the new epoch as usual ({{fk-rewrap}}). + +Since an unavailable arbiter only pauses membership changes, while +sharing, resource access, and FK distribution continue to operate, the +takeover time T MAY be generous, for example several hours. Loose time +synchronisation between servers is sufficient and is already assumed by +MLS for leaf node lifetimes ([RFC9420] Section 7.2). + +## MLS Notification Types + +All MLS group lifecycle messages are sent as OCM Notifications to +`/notifications` using HTTP POST with `Content-Type: +application/json` and HTTP Signatures [RFC9421]. + +Proposals and Commits MUST be encoded as PublicMessage objects +([RFC9420] Section 6.2), and Application Messages as PrivateMessage +objects ([RFC9420] Section 6.3). Handshake messages are sent in the +clear at the MLS layer because the servers that route and arbitrate them +are required to track the public group state - the ratchet tree and +GroupContext - in order to derive membership for share routing, resolve +shares to local users, and verify that Commits are signed by admin +clients; in native client deployments those servers do not hold the +group's secrets. A recipient that holds the group's secrets MUST verify +the membership_tag on a PublicMessage ([RFC9420] Section 6.2); a server +relaying or arbitrating without group secrets verifies what it can, +namely the signature against the sender's leaf in its copy of the +ratchet tree and the policy checks of {{admins}}. The confidentiality +trade-off relative to encrypted handshake messages is discussed in +Security Considerations. + +The notification types defined in this document are group-scoped rather +than share-scoped. [OCM] requires a `providerId` field in notifications +because the notification types it defines all refer to a Share; the MLS +notification types refer to a group instead, so this document updates +that requirement: `providerId` is REQUIRED only for notification types +that refer to a Share, and the MLS notification types omit it. All +MLS-specific parameters are carried inside the `notification` object +that [OCM] provides for type-specific parameters. The `mlsGroupId` +field carries the base64-encoded MLS `group_id` as advisory routing +information, used to dispatch the message to the right group state +without parsing the MLS message; the authoritative `group_id` is the one +inside the MLS message itself, and a mismatch between the two MUST be +treated as an error. At the OCM layer, groups are otherwise identified +by their OCM Address: in particular, the `groupId` field of the +application data carried inside `MLS_APPLICATION` messages +({{key-distribution}}, {{credential-update}}) is the group's OCM +Address, never the MLS `group_id`. + +Since `MLS_PROPOSAL` is delivered only to Admin Servers and never +broadcast to other Member Servers, Member Servers never observe pending +proposals. Proposals covered by a Commit are instead redistributed +together with that Commit, as described under `MLS_COMMIT` below. Admin +clients, as the only committers ({{admins}}), MUST satisfy all +considerations of [RFC9420] Section 12.4. + +### MLS_WELCOME + +Sent to a Member Server when one of its users is added to the group. +The Welcome is constructed by the admin client that created the +corresponding Commit ([RFC9420] Section 12.4.3.1) and delivered by that +admin's home server directly to the added user's server, after the Group +Owner Server has accepted the Commit. Delivers the MLS Welcome message +for the added user, enabling the receiving MLS client to initialise its +state and derive the current Group Key. A single `MLS_COMMIT` covering +multiple Add proposals will result in one `MLS_WELCOME` notification per +added user. + +~~~ json +{ + "notificationType": "MLS_WELCOME", + "notification": { + "mlsGroupId": "", + "userId": "bob@othercloud.example.org", + "content": "" + } +} +~~~ + +The Welcome message MUST include the group's ratchet tree in a +`ratchet_tree` extension ([RFC9420] Section 12.4.3.3). By default a +Welcome carries only a hash of the tree, and this document defines no +other channel through which a newly added Member Server could obtain it. +Member Servers depend on holding the current ratchet tree, both to +derive the group membership and to process subsequent Commits. Carrying +the tree inside the Welcome also gives it the same confidentiality +protection as the rest of the group state, as recommended by [RFC9420] +Section 12.4.3.3. + +A Member Server processing a Welcome learns the group's OCM Address from +the `ocm_federated_group` extension in the GroupContext ({{admin-set}}). +It MUST reject a Welcome whose `group_ocm_address` is already bound to a +different MLS `group_id`, unless the Welcome reinitialises the group as +described in {{reinit}}. This keeps the local wrapped FK store, keyed +by `(resourceId, groupId)`, unambiguous. + +### MLS_PROPOSAL + +Sent by a Member Server to the home server of every admin to propose a +group change (for example Add, Remove, Update, GroupContextExtensions, +or ReInit) on behalf of one of its users. This notification is NOT +broadcast to other Member Servers. Each Admin Server queues received +proposals, deduplicated by ProposalRef ([RFC9420] Section 5.2), for +handling by its admin clients according to the policy in {{admins}}. +Sending the proposal to all Admin Servers removes the dependency on any +single server being available and lets whichever admin is online next +act on it. + +~~~ json +{ + "notificationType": "MLS_PROPOSAL", + "notification": { + "mlsGroupId": "", + "content": "" + } +} +~~~ + +### MLS_COMMIT + +Constructed and signed by an admin client ({{admins}}) and submitted to +the Group Owner Server, which accepts at most one Commit per epoch, MUST +reject Commits submitted by non-admin clients, and broadcasts the +accepted Commit to all Member Servers to advance the group epoch. An +admin client whose Commit is rejected discards it and MAY construct a +new Commit on the resulting epoch ([RFC9420] Section 14). A Member +Server receiving a broadcast `MLS_COMMIT` MUST verify that the Commit is +signed by an admin client before processing it, as specified in +{{admins}}, and MUST reject it otherwise, regardless of which server +broadcast it. Commits are ordered by the MLS epoch itself: each Commit +advances the epoch by exactly one, so Member Servers MUST process +Commits in epoch order, and a Commit arriving for an epoch later than +the next expected one indicates one or more missed Commits. Member +Servers MUST apply the new epoch secret before sending any application +data, per [RFC9420] Section 15.2. + +~~~ json +{ + "notificationType": "MLS_COMMIT", + "notification": { + "mlsGroupId": "", + "proposals": [""], + "content": "" + } +} +~~~ + +A Commit covers each proposal either by value or by reference ([RFC9420] +Section 12.4). Proposals included by value are carried inside the +Commit itself and are necessarily proposals originated by the committing +admin client, since a by-value proposal carries no sender of its own. +Proposals received from Member Servers via `MLS_PROPOSAL` - in +particular Update proposals, which can only be applied relative to their +original sender's leaf - are covered by reference, and receiving Member +Servers need the original proposal messages in order to validate and +apply the Commit ([RFC9420] Sections 12.1 and 12.4.2). The `proposals` +array therefore carries every proposal covered by reference, verbatim as +originally sent by their proposers, in the order in which the +corresponding references appear in the Commit. It MUST be present +whenever the Commit covers at least one proposal by reference and MAY be +omitted otherwise. A Member Server processing an `MLS_COMMIT` MUST +process the carried proposals before processing the Commit itself. + +The `MLS_COMMIT` serves as the signal to all sending servers that the +epoch has advanced: each sending server then re-wraps and redistributes +the FKs of the resources it shares with the group ({{fk-rewrap}}), and +on member removal MAY additionally rotate them according to its policy +({{fk-rotation}}). Any Commit covering a Remove, Update, or +GroupContextExtensions proposal MUST include an UpdatePath ([RFC9420] +Section 12.4). + +### MLS_APPLICATION + +Sent by a sending server directly to Member Servers, derived from the +ratchet tree, to deliver updated wrapped file keys and, optionally, +updated per-server transport credentials ({{credential-update}}). No +central relay is involved. Messages carrying wrapped FKs are sent to +all current Member Servers; messages carrying a transport credential are +sent only to the affected Member Server. The `content` is a +`PrivateMessage` carrying application data encrypted in the current +epoch ([RFC9420] Section 15). + +~~~ json +{ + "notificationType": "MLS_APPLICATION", + "notification": { + "mlsGroupId": "", + "content": "" + } +} +~~~ + +Ordering is provided by authenticated MLS metadata rather than a +transport counter: the `PrivateMessage` carries the epoch in the clear, +and the sender's leaf and generation counter are learned upon decryption +([RFC9420] Section 6.3). Since all FK updates for a given `(resourceId, +groupId)` originate from the resource's sending server, the `(epoch, +generation)` pair totally orders them; see {{key-distribution}}. A +Member Server that receives an `MLS_APPLICATION` encrypted in an epoch +it has not yet entered SHOULD queue it until the corresponding +`MLS_COMMIT` has been processed. + +Because credential-bearing messages are delivered to a single Member +Server, other Member Servers will observe a gap in the sending leaf's +generation counter on the next message they do receive. Such gaps are +expected and MUST NOT be treated as an error; receivers ratchet forward +past skipped generations as described in [RFC9420] Section 15.3. +Deployments MUST limit the number of generations a receiver will advance +a sender ratchet in response to a single message and reject messages +beyond that limit, bounding the key derivation work a malicious sender +can trigger ([RFC9420] Section 15.3). + +### MLS_REJOIN + +Sent by a drifted Member Server to the home server of every admin to +request re-admission of its users after local MLS state loss +({{rejoin}}). Unlike the other notification types, the content is not +an MLS message: a drifted server holds no usable MLS state, so the +request is authenticated only at the OCM layer, by the HTTP Signature of +the sending server. Each entry in `keyPackages` carries a fresh MLS +KeyPackage for one affected user, in the same format as entries served +by the KeyPackage endpoint. + +~~~ json +{ + "notificationType": "MLS_REJOIN", + "notification": { + "mlsGroupId": "", + "keyPackages": [ + { + "userId": "bob@othercloud.example.org", + "mediaType": "message/mls", + "encoding": "base64", + "content": "" + } + ] + } +} +~~~ + +Admin Servers queue rejoin requests alongside proposals and make them +available to their admin clients, which handle them as described in +{{rejoin}}. A later rejoin request for the same group and user +supersedes an earlier one; admin clients act on the most recent request. + +## Leaf Key Updates {#leaf-key-updates} + +To maintain post-compromise security ([RFC9420] Section 16.6), Member +Servers SHOULD periodically send `MLS_PROPOSAL` (Update) to the Admin +Servers to rotate their users' leaf keys. Admin clients SHOULD commit +pending Update proposals automatically whenever they are online, without +user interaction; an Update only achieves post-compromise security once +it has been committed ([RFC9420] Section 16.6). + +Groups MUST define an update deadline: the maximum time allowed between +committed Updates of a leaf. A leaf that has not been updated within +the deadline is stale. Members with stale leaves SHOULD be removed from +the group per [RFC9420] Section 3.2, and stale admins in particular +SHOULD be removed promptly: an admin whose clients no longer update +cannot commit, and a stale first admin additionally blocks Commit +arbitration until failover ({{failover}}). + +## Rejoin After State Loss {#rejoin} + +A Member Server can lose its MLS state for a group: it may have +processed a Commit that was later discarded during failover conflict +resolution ({{failover}}) and already deleted the superseded epoch's +secrets per the deletion schedule ([RFC9420] Section 9.2), or its stored +state may be lost or corrupted for any other reason. Such a server has +drifted from the group: it can no longer process Commits or decrypt +Application Messages, and because MLS messages are bound to the current +GroupContext, it cannot sign a valid Proposal with which to recover. A +drifted server detects its condition when an `MLS_COMMIT` fails to +process against its local state, for example through a confirmation tag +mismatch, or arrives for an epoch it cannot reach after Commit +retransmission has been exhausted. + +Recovery is mediated by an admin client through the normal Commit path: + +1. The drifted server discards its MLS state for the group and + generates a fresh KeyPackage for each of its users who are members +of the group. +2. It sends an `MLS_REJOIN` notification carrying those KeyPackages to + the home server of every admin. The notification is authenticated +at the OCM layer with HTTP Signatures [RFC9421], the same trust anchor +that authenticates KeyPackage distribution itself, so a rejoin request +is exactly as trustworthy as a freshly fetched KeyPackage. +3. An admin client verifies that each KeyPackage's credential carries + the OCM Address of a leaf currently in the ratchet tree, and that +the notification was signed by the server named in those OCM Addresses. +A rejoin MUST NOT admit a user without a leaf in the tree; it can only +replace existing members. +4. The admin client constructs a single Commit containing, by value, a + Remove proposal for each stale leaf and an Add proposal for the +corresponding fresh KeyPackage. This rejoin pair preserves the OCM +Address of every affected leaf and grants no new party access, so admin +clients SHOULD commit it automatically, per the policy in {{admins}}. +5. The Commit is arbitrated and broadcast as usual, and the drifted + server receives one `MLS_WELCOME` per re-added user, restoring clean +state from the Welcome's `ratchet_tree` extension. + +A single Commit recovers all of the drifted server's users at once. +Until the rejoin completes, the drifted server can continue to serve +resources whose wrapped FKs it received before the fork, using the Group +Key of the last epoch it processed; wrapped FKs distributed after the +fork become accessible when the re-wrap following the rejoin Commit +({{fk-rewrap}}) arrives. + +## Group Reinitialisation {#reinit} + +Reinitialisation ([RFC9420] Section 11.2) replaces a group with a new +MLS group with the same membership and the same OCM Address but +different parameters: a new MLS version, cipher suite, or extension set, +and necessarily a fresh MLS `group_id`. It is the migration path for +cryptographic agility, for example moving a long-lived group to a +stronger cipher suite. + +A ReInit proposal is a group parameter change and is handled like other +group-changing proposals: it MUST be explicitly approved by an admin and +MUST be committed by an admin client. Per [RFC9420] Section 12.2, a +ReInit proposal is committed alone. The `extensions` field of the +ReInit proposal MUST include an `ocm_federated_group` extension with +`group_ocm_address` unchanged; the admin set is normally carried over +unchanged. + +After the ReInit Commit is processed, the old group MUST NOT be used to +send messages ([RFC9420] Section 12.4.2). In particular, sending +servers MUST NOT send `MLS_APPLICATION` messages in the old group; the +per-epoch re-wrap obligation ({{fk-rewrap}}) arising from the ReInit +Commit is deferred to the new group. + +The admin client that committed the ReInit SHOULD create the new group: +it fetches fresh KeyPackages, valid for the new version and cipher +suite, for every member of the old group, creates the new group with an +initial Commit re-admitting them, and sends each member a Welcome +carrying a PreSharedKeyID of type resumption with usage reinit, as +specified by [RFC9420] Section 11.2. The Add proposals of this initial +Commit re-admit the old group's members and require no separate admin +approval. If the committing admin client fails to complete this step in +reasonable time, any other admin client MAY do so instead. If a Member +Server receives competing reinitialisation Welcomes for the same +`group_ocm_address`, it MUST accept the one whose new group was created +by the admin listed earliest in the old group's admin set and reject the +others. + +A Member Server processing a reinitialisation Welcome MUST perform the +verifications of [RFC9420] Section 12.4.3.1 for usage reinit: the last +Commit of the old group contains the ReInit proposal, the new group's +parameters match it, and every member of the old group is a member of +the new group, where members are equivalent if their leaf credentials +carry the same OCM Address. It MUST additionally verify that the +`group_ocm_address` of the new group equals that of the old group. On +success it rebinds the OCM Address from the old `group_id` to the new +one; this is the only case in which that binding may change. Because +the local wrapped FK store is keyed by the group's OCM Address, stored +entries carry over unchanged. + +After joining the new group, a sending server MUST re-wrap the FK of +every resource it shares with the group under the new group's Group Key +and redistribute the wrapped FKs to all Member Servers, exactly as for +an epoch change ({{fk-rewrap}}). The new group's Group Key differs from +any key of the old group both through the fresh epoch secret and through +the new `group_id` in the Exporter context, so no wrapped FK from the +old group can be unwrapped in the new one. Until the re-wrapped FKs +arrive, Member Servers retain the old group's last Group Key under the +same retention rule as for an epoch change. Members SHOULD retain the +resumption PSK of the old group's final epoch until the reinitialisation +has completed ([RFC9420] Section 8.6). + +# Encryption Model + +## Group Key Derivation + +After processing any MLS Welcome or Commit, the MLS client MUST apply +the new epoch secret before encrypting any application data, then +derives the current Group Key: + +~~~ +group_key = MLS-Exporter("ocm-group-key", group_id_bytes, AEAD.Nk) +~~~ + +`AEAD.Nk` is the length in bytes of a key for the AEAD algorithm of the +group's negotiated MLS cipher suite ([RFC9420] Section 9.1). Deriving +the Group Key at exactly this length makes it a valid key for the wrap +AEAD ({{file-key-wrapping}}), which is the AEAD algorithm of the group's +cipher suite, for every cipher suite, including those whose AEAD takes a +16-byte key such as AES-128-GCM. + +The MLS Exporter ([RFC9420] Section 8.5) produces application-specific +key material from the epoch secret without exposing the epoch secret +itself. The label `"ocm-group-key"` scopes the output to this +application. The `group_id_bytes` context, the raw MLS `group_id` of +the group, further binds the output to this specific group. The Group +Key therefore changes with every epoch transition and cannot be derived +by any party that did not participate in that epoch. + +Per [RFC9420] Section 8.5, the Group Key SHOULD be refreshed after each +processed Commit. Security-sensitive values derived from the epoch +secret MUST be deleted as soon as they are consumed, per [RFC9420] +Section 9.2. + +All MLS clients in the group independently derive the same Group Key for +a given epoch. + +## Resource Id {#resource-id} + +The `resourceId` used in the AEAD associated data MUST be a stable +identifier for the underlying file, consistent across all groups it is +shared with. It identifies the resource, not a particular version of +it. This ensures that the FK unwrapped by members of any group correctly +decrypts the same ciphertext. The `providerId` values in separate share +notifications, for the same resource, MUST differ, per the `providerId` +definition in [OCM], but the `resourceId` in the AEAD associated data +MUST be the same. This means that the `providerId` MUST NOT be reused +as `resourceId`. The sending server is responsible for maintaining this +stable `resourceId` and MUST send it in the `encryption` object of the +share payload ({{share-creation}}). + +## File Key Wrapping {#file-key-wrapping} + +Two AEAD algorithms are involved in protecting a resource, and they are +deliberately decoupled. The content AEAD encrypts the resource itself: +it is chosen by the sending server from the AEAD algorithms defined for +HPKE ([RFC9180] Section 7.3), it is fixed for the lifetime of a +ciphertext and identical across all groups the resource is shared with, +and it is identified explicitly by the `cipher` field of the +`encryption` object ({{share-creation}}). The wrap AEAD protects the FK +in transit: it is always the AEAD algorithm of the respective group's +MLS cipher suite, keyed with that group's Group Key, and may therefore +differ between groups that share the same resource. + +When sharing an encrypted resource with a group, the sending MLS client +acts on behalf of a user who is a member of that group: + +1. Chooses the content AEAD and generates a random per-file key (FK) + whose length is the key length of that algorithm. +2. Encrypts the resource with FK using the content AEAD. + Implementations supporting native client decryption of large files +SHOULD use a chunked AEAD construction to enable streaming decryption. +3. Derives the current Group Key from the user's local MLS state. +4. Wraps FK using the wrap AEAD: + + ~~~ + wrapped_file_key = AEAD-Encrypt( + key = group_key, + nonce = random_nonce, + plaintext = FK, + aad = FKWrapAAD + ) + ~~~ + + where the associated data is the serialisation of the following + structure, in the presentation language of [RFC9420]: + + ~~~ + struct { + opaque group_ocm_address; + opaque resource_id; + } FKWrapAAD; + ~~~ + + The `group_ocm_address` field is the UTF-8 encoding of the group's + OCM Address (the same value carried in the `shareWith` field of the + share notification) and `resource_id` is the UTF-8 encoding of the + `resourceId` field of the `encryption` object. The length-prefixed + encoding makes the pair unambiguous; raw concatenation of the two + strings would allow distinct (address, identifier) pairs to produce + identical associated data. The MLS `group_id` is NOT used in the + associated data. + +5. Sends an `MLS_APPLICATION` notification directly to all current + Member Servers, carrying the wrapped FK keyed by `(resourceId, +groupId)`. + +## FK Re-wrap on Epoch Change {#fk-rewrap} + +The Group Key changes with every epoch transition, whatever the reason +for the transition: a Commit covering Add, Remove, Update, or +GroupContextExtensions proposals, or an empty Commit, all advance the +epoch. To maintain the invariant that the current Group Key is always +sufficient to unwrap the current wrapped FK, a sending server MUST, +after processing an `MLS_COMMIT` for a group, or after joining the +successor group of a reinitialisation via its Welcome ({{reinit}}), for +every resource it shares with that group: + +1. Re-wrap the resource's current FK under the new Group Key, following + the procedure in {{file-key-wrapping}}. +2. Distribute the new wrapped FK to all current Member Servers, derived + from the new ratchet tree, via `MLS_APPLICATION`. + +Note that the FK itself is unchanged by this procedure; only its +wrapping is refreshed. Whether the FK is also rotated is a separate, +removal-triggered policy decision ({{fk-rotation}}). + +If the Commit added one or more members, the set of Member Servers may +have grown. The sending server MUST identify Member Servers that are +new to the group and send them the Share Creation Notifications for its +federation shares with the group, as described in {{share-creation}}, in +addition to the wrapped FKs. A server that joins the group after a +share was created thereby receives both the share itself and a wrapped +FK it can decrypt, since the `MLS_APPLICATION` is encrypted in an epoch +in which it is a member. + +Between processing a Commit and receiving the re-wrapped FK for a +resource, a Member Server holds a wrapped FK produced under the previous +epoch's Group Key. To remain able to serve access requests in this +window, a Member Server SHOULD retain the previous epoch's Group Key +until it has received a strictly newer wrapped FK ({{key-distribution}}) +for every locally stored `(resourceId, groupId)` pair of that group, or +until a bounded time has elapsed, whichever comes first, and MUST delete +it at that point. The security trade-off of this retention window is +discussed in Security Considerations. + +The volume of `MLS_APPLICATION` traffic produced by this rule grows with +the number of shared resources and the frequency of epoch transitions; +see the batching item in Open Issues. + +## Key Distribution via MLS Application Messages {#key-distribution} + +Wrapped file keys are distributed to Member Servers via MLS Application +Messages, `PrivateMessage` objects carrying application data ([RFC9420] +Section 15). Wrapped FKs are distributed at share creation and +re-distributed after every epoch transition ({{fk-rewrap}}). A sending +server MUST process the `MLS_COMMIT` and derive the new Group Key before +sending an `MLS_APPLICATION` with updated wrapped keys, per [RFC9420] +Section 15.2. + +The `PrivateMessage` application data is a JSON object carrying the +current wrapped FK for each `(resourceId, groupId)` pair in a `keys` +array, and MAY also carry a `credentials` array ({{credential-update}}): + +~~~ json +{ + "keys": [ + { + "resourceId": "3a02538b-aa54-42f2-8853-a38996e211b1", + "groupId": "research-group@receiver.example.org", + "wrappedKey": "" + } + ] +} +~~~ + +The `groupId` field carries the group's OCM Address, matching the +`shareWith` of the corresponding share notification, and the +`resourceId` field matches the `resourceId` in the `encryption` object +of that notification. + +The `PrivateMessage` is encrypted using the current epoch's keys, so +only current group members can decrypt it. A just-removed member cannot +decrypt the Application Message even if they receive the notification, +as they do not hold the new epoch's key material. + +Member Servers store the received wrapped FKs locally, keyed by +`(resourceId, groupId)`, always replacing any previous wrapped FK for +the same pair with the latest one. "Latest" is defined by the +authenticated `(epoch, generation)` of the enclosing `PrivateMessage`, +compared lexicographically, not by arrival order: a stored wrapped FK +MUST only be replaced by one with a strictly higher `(epoch, +generation)`. A sending server MUST send all FK updates for a given +group through a single MLS leaf within any given epoch, since generation +counters are maintained per leaf; updates from a later epoch always +supersede updates from an earlier epoch regardless of leaf. MLS +Application Messages may be delayed or reordered in transit ([RFC9420] +Section 15.3); a Member Server that receives an out-of-order +`MLS_APPLICATION` simply ignores wrapped FKs that are not newer than +those it already holds. At access time, the Member Server uses its +current Group Key, derived from its current MLS state for the identified +group, to unwrap the FK. + + +## Transport Credential Updates {#credential-update} + +The per-server transport credential of a share ({{share-creation}}) may +need to be rotated during the lifetime of the share. In particular, in +native client deployments the user's device interacts directly with the +sending server and therefore holds its server's credential, so when such +a user is removed from the group, the credential of their server can no +longer be considered private to that server's remaining users. On +removal of a member whose clients may have held a server's transport +credential, the sending server SHOULD rotate that server's credential +for every share affected. Rotation MAY also be triggered by policy or +suspected leakage. + +A rotated credential is delivered in an `MLS_APPLICATION` message sent +only to the affected Member Server, carrying a `credentials` array in +the application data: + +~~~ json +{ + "credentials": [ + { + "providerId": "7c084226-d9a1-11e6-bf26-cec0c932ce01", + "groupId": "research-group@receiver.example.org", + "recipient": "othercloud.example.org", + "sharedSecret": "" + } + ] +} +~~~ + +Each entry identifies the share by its `providerId`, the group by its +OCM Address in `groupId`, and the intended Member Server by its FQDN in +`recipient`. A Member Server MUST ignore entries whose `recipient` does +not name itself. Upon accepting an entry, the Member Server replaces +the stored transport credential for that share; replacement follows the +same `(epoch, generation)` supersede rule as wrapped FKs +({{key-distribution}}). The sending server invalidates the old +credential once the rotation has been delivered. + +Encrypting the credential update in the current epoch guarantees that +the removed member cannot read it, independent of transport protection: +they do not hold the new epoch's key material. Confidentiality with +respect to other Member Servers, by contrast, rests on targeted +delivery: the `PrivateMessage` is decryptable by any group member that +obtains it, so delivering it to the affected server only is a routing +measure, not a cryptographic one (see Security Considerations). + +A `keys` array and a `credentials` array MAY appear in the same +application data object when both are destined for the same single +Member Server. + +## Resource Access + +To access a resource: + +1. The resource is fetched from the sending server using the standard + OCM resource access procedure ([OCM]), with the protocol details and +per-server credential from the `protocol` object of the share +notification. For an encrypted resource, what is fetched is ciphertext. +2. The MLS client identifies the relevant group from the `shareWith` + field of the share notification and looks up the locally stored +`wrapped_file_key` for the `(resourceId, groupId)` pair. +3. The MLS client derives the current Group Key from its local MLS + state for that group and unwraps FK using the wrap AEAD of the +group's cipher suite. +4. The MLS client decrypts the resource using FK and the content AEAD + named in the `cipher` field of the `encryption` object. + +In web-client deployments, decryption happens server-side and the +plaintext is served to the user through whatever access protocol is in +use (WebDAV [RFC4918], SFTP, webapp, etc.). In native client +deployments, decryption happens on the user's device and the client +interacts directly with the sending server, which serves only +ciphertext. + +## Resource Modification by Member Servers + +A common operation is for a user on a Member Server to open a shared +encrypted resource, modify it, and save it back. The cryptographic flow +is as follows: + +1. The Member Server fetches the encrypted resource from the sending + server using the standard OCM resource access procedure, with the +credential from the share's `protocol` object. +2. The Member Server identifies the relevant group from the `shareWith` + field of the share notification, looks up the locally stored +`wrapped_file_key` for the `(resourceId, groupId)` pair, derives the +current Group Key from its local MLS state for that group, and unwraps +FK. +3. The Member Server decrypts the resource using FK and presents the + plaintext to the user. +4. The user modifies the resource. +5. The Member Server re-encrypts the modified resource using the same + FK and the same content AEAD, but a fresh random nonce. The nonce +MUST NOT be reused with the same key, as required by AEAD security. +6. The Member Server uploads the re-encrypted resource to the sending + server. This requires the share to grant `write` permission in its +`protocol` object. + +The FK is reused across modifications of the same resource because it is +bound to the group's OCM Address and `resourceId` in the AEAD associated +data, making it specific to that resource. No new `MLS_APPLICATION` +message is needed, as the wrapped FK in all Member Servers' local stores +remains valid for the updated ciphertext. + +FK rotation for a resource is only necessary on member removal in +re-encryption mode ({{fk-rotation}}). + + + +## Sharing a Resource with Multiple Groups + +A sending server MAY share the same encrypted resource with more than +one group. The file is encrypted once, with a single FK and a single +content AEAD; the `cipher` field in every group's share notification +names that same algorithm. Each group receives its own wrapped FK, +produced with that group's wrap AEAD, Group Key, and OCM Address: + +~~~ +wrapped_file_key_group1 = AEAD-Encrypt(group_key_1, nonce_1, FK, + FKWrapAAD(group_ocm_address_1, resource_id)) +wrapped_file_key_group2 = AEAD-Encrypt(group_key_2, nonce_2, FK, + FKWrapAAD(group_ocm_address_2, resource_id)) +~~~ + +A separate Share Creation Notification is sent to each Member Server of +each group. A separate `MLS_APPLICATION` carrying the respective +wrapped FK is broadcast to each group's Member Servers. Members of each +group can only unwrap the FK using their own group's Group Key and +cannot access the other group's wrapped FK or Group Key. + +The sending server MUST maintain a mapping from each resource to all +groups it has been shared with. This mapping is required to correctly +handle member removal in re-encryption mode, as described in the +following section. + +## FK Rotation (RECOMMENDED) {#fk-rotation} + +FK rotation is distinct from the re-wrap performed on every epoch change +({{fk-rewrap}}): rotation generates a new FK and re-encrypts the +resource, whereas a re-wrap only refreshes the wrapping of the existing +FK. A sending server SHOULD rotate the FK for a resource when a member +is removed from any group that has access to it. FK rotation may also +be triggered by other factors, such as periodic key rotation policy, +regulatory requirements, or a suspected compromise of key material. +Applications SHOULD define a policy for the frequency of FK rotation +independent of membership changes. + +When rotating the FK for a resource, the sending server: + +1. Generates a new FK for the resource. +2. Re-encrypts the resource with the new FK. +3. For every group that has access to the resource, wraps the new FK + using that group's current Group Key: + + ~~~ + new_wrapped_file_key_groupN = AEAD-Encrypt(group_key_N, nonce_N, + new_FK, FKWrapAAD(group_ocm_address_N, resource_id)) + ~~~ + +4. Broadcasts an `MLS_APPLICATION` notification carrying the respective + new wrapped FK directly to each group's Member Servers. + +Distributing the new wrapped FK to all groups that share the resource is +necessary because all groups share the same ciphertext. If only one +group received the new wrapped FK, members of other groups would hold a +wrapped FK that no longer decrypts the current ciphertext. + +A member removed from one group but still a member of another group that +shares the same resource retains the ability to decrypt that resource +through the second group. This is correct and intended behaviour: +access is determined by current group membership, and the user remains a +member of the second group. The default safe rule is to rotate the FK +and redistribute to all groups on any removal event. A sending server +MAY instead compare the unique set of users with access before and after +an epoch change, and skip FK rotation if that set is unchanged, for +example because the removed user remains a member of every other group +that has access to the same resource. Whether this optimisation is +worth the added complexity depends on the nature of the resource and the +frequency of membership changes. + +Member addition does not require FK rotation. The new member receives +the current Group Key via their Welcome, and the re-wrap triggered by +the Add Commit ({{fk-rewrap}}) delivers a wrapped FK, encrypted in an +epoch in which the new member is a member, that the new member can +unwrap with that Group Key. + +## Member Removal: Key-reuse Mode (OPTIONAL) + +Where re-encryption is impractical, for example due to frequent changes +of very large files, and where all participating servers belong to a +formal federation with explicit governance and mutual trust, a sending +server MAY instead keep the existing FK. In that case no action beyond +the standard re-wrap on epoch change ({{fk-rewrap}}) is required: the +Remove Commit advances the epoch, and the sending server re-wraps the +existing FK under the new Group Key and distributes it to the remaining +Member Servers of the affected group. + +When a resource is shared with multiple groups, only the epoch of the +group from which the member was removed has advanced, so only that +group's FK wrapping is refreshed. The wrapped FKs for other groups are +unchanged and remain valid for their respective members. + +In this mode, access-follows-membership relies on trust rather than +cryptography: the FK itself is unchanged, so a removed member's server +and, in native client deployments, the removed user's devices, may still +hold the superseded Group Key together with the old wrapped FK, or the +unwrapped FK itself, any of which decrypts the unchanged ciphertext. +Key-reuse mode therefore relies on trusting servers to discard key +material they are no longer entitled to after a Remove Commit. A +removed member who is also a member of another group that has access to +the same resource will still be able to decrypt via that group's wrapped +FK, which is the expected behaviour - they remain a member of that +group. This assumption is appropriate within a formal federation but +SHOULD NOT be made in open or ad-hoc sharing contexts. + +The sending server's choice of mode is its own policy decision and is +not signalled in the protocol. + +## Member Removal: OCM Notifications + +Member removal requires no OCM-level notification by itself. Because +federation shares are addressed to the group ({{share-creation}}), each +Member Server observes the Remove Commit and re-evaluates which of its +local users the share resolves to; a removed user loses access without +any action by the sending server. If the removed member's clients may +have held their server's transport credential, the sending server SHOULD +additionally rotate that credential ({{credential-update}}). + +When the last member homed on a given server is removed from the group, +that server no longer has any user with access. A well-behaved sending +server SHOULD then reconcile the OCM state of the share, revoke that +server's per-server transport credential ({{share-creation}}), and send +a `SHARE_UNSHARED` notification to the `/notifications` endpoint of that +server. + +# Share Creation {#share-creation} + +The sending server sends one OCM Share Creation Notification directly to +each current Member Server, identified through the OCM Addresses in the +ratchet tree's leaf credentials. This is standard OCM server-to-server +communication, with `shareWith` set to the group's OCM Address and +`shareType` set to `"federation"`. The share is addressed to the group +as the Receiving Party; no per-user notifications are sent. + +A federation share is a standard OCM share: every field that is REQUIRED +by [OCM], including the `protocol` object, is REQUIRED here too, and +resource access follows the standard OCM resource access procedure +driven by the `protocol` object. For encrypted resources the protocol +endpoint serves ciphertext; the plaintext is obtained by unwrapping the +FK as described in the Encryption Model. + +Each Member Server SHOULD be given its own `sharedSecret` (or equivalent +protocol credential) in its copy of the notification. The credential is +per server, not per user: all users on a Member Server share it, +mirroring how the server holds MLS state on behalf of its users. +Distinct per-server credentials allow the sending server to revoke a +single server's transport access, for example when the last group member +on that server is removed, without affecting other Member Servers. +Share Creation Notifications sent to servers that join the group later +({{fk-rewrap}}) carry credentials minted at that time, and a server's +credential can be rotated during the share's lifetime +({{credential-update}}). + +Share Permissions apply uniformly to the whole group: every member of +the group receives the same permissions on the resource. A sending +server that needs different permissions for different parties should use +separate groups or individual shares. Receiving Server criteria that +affect the share payload, such as `must-exchange-token`, are evaluated +per Member Server against that server's discovery document, exactly as +in base OCM. + +The receiving server resolves `shareWith` against its local MLS state: +it identifies the group whose `group_ocm_address` ({{admin-set}}) +matches the `shareWith` value and delivers the share to every local user +whose leaf credential appears in that group's ratchet tree. On every +subsequent `MLS_COMMIT` the receiving server MUST re-evaluate this +resolution, so that local users added to the group gain access to +existing federation shares, and removed users lose it, without any +further OCM notifications. + +Addressing the share to the group also allows the receiving server to +distinguish between shares of the same resource arriving via different +groups - a user may be a member of two groups that both have access to +the same resource from the same sending server - and to correctly key +its local wrapped FK store by `(resourceId, groupId)` rather than +`resourceId` alone, where `groupId` is the group OCM Address carried in +`shareWith`, ensuring that FK updates delivered via `MLS_APPLICATION` +are applied to the correct entry. + +Because notifications can be delayed or reordered in transit, a +federation share MAY arrive before the receiving server has processed +the Welcome or Commit that made it a Member Server of the group. A +receiving server that does not recognise the `shareWith` value as a +known group SHOULD queue the share, or reject it in a way that causes +the sender to retry, rather than fail it permanently. Since sending +servers only contact servers present in the ratchet tree, this condition +is transient. + +When an `MLS_COMMIT` adds one or more members to the group, the sending +server MUST send each Member Server that is new to the group a Share +Creation Notification for every federation share it has with that group, +encrypted or not. For encrypted resources this accompanies the +re-wrapped FK ({{fk-rewrap}}). A server that joins the group after a +share was created thereby learns of the shares its users now have access +to without any further action by its users. + +Each notification MAY include the optional `encryption` field: + +~~~ json +{ + "shareWith": "research-group@receiver.example.org", + "shareType": "federation", + "resourceType": "file", + "sender": "alice@cloud.example.org", + "owner": "alice@cloud.example.org", + "providerId": "7c084226-d9a1-11e6-bf26-cec0c932ce01", + "name": "experiment-data.tar", + "protocol": { + "name": "multi", + "webdav": { + "uri": "experiment-data.tar", + "sharedSecret": "", + "permissions": ["read", "write"] + } + }, + "encryption": { + "scheme": "ocm-mls-1", + "cipher": "AES-256-GCM", + "resourceId": "3a02538b-aa54-42f2-8853-a38996e211b1" + } +} +~~~ + +The `encryption` field is OPTIONAL. If absent, the resource is +unencrypted and the share follows the standard OCM flow without +modification. If present, it carries all encryption-related parameters: +`scheme` identifies the encryption scheme, for which this document +defines `"ocm-mls-1"`; `resourceId` is the stable resource identifier +described in {{resource-id}}; and `cipher` (REQUIRED when `encryption` +is present) names the content AEAD that the resource is encrypted with +({{file-key-wrapping}}), one of the AEAD algorithms defined for HPKE +([RFC9180] Section 7.3): `"AES-128-GCM"`, `"AES-256-GCM"`, or +`"CHACHA20-POLY1305"`. The field signals that the FK is distributed via +the `MLS_APPLICATION` mechanism keyed by `(resourceId, groupId)`. No +epoch information is carried in the share notification. Member Servers +always hold the current wrapped FK for each `(resourceId, groupId)` pair +and use their current Group Key to unwrap it at access time. + +The Group Owner Server is not involved in the delivery of OCM share +notifications. All other OCM notifications relating to a share, such as +share updates and share deletions, are likewise sent directly from the +sending server to each Member Server, referencing the share by its +`providerId` as in base OCM. + +# Trust and Authentication {#trust-and-authentication} + +The Authentication Service role ([RFC9420] Section 3) is fulfilled by +each user's home OCM server: the server that publishes a user's +KeyPackages attests the binding between the user's OCM Address and their +signature key. Because the basic credential itself carries no +verifiable binding, the attestation lies in the delivery channel. + +## Validation procedure + +A KeyPackage is considered validated with the AS when all of the +following hold: + +- it was fetched from the `/mls-key-packages` endpoint of the +server named in the credential's OCM Address, over TLS, with the +response signed using HTTP Signatures [RFC9421] verifying against that +server's JWKS [RFC7517]; +- the OCM Address in the credential is identical to the `userId` the +KeyPackage was requested for, which is the OCM Address of the user the +requester intends to add; in particular, its host part names the server +the KeyPackage was fetched from; and +- the KeyPackage signature verifies with the `signature_key` of its +LeafNode, proving possession of the private key ([RFC9420] Section +10.1). + +Requests to the KeyPackage endpoint are signed at the server level +({{security-considerations}}), so in native client deployments the +fetch is performed by the admin's home server on the admin client's +behalf. The home server SHOULD relay the response with its HTTP +Message Signature intact, allowing the native client to verify the +channel binding end-to-end against the target server's published JWKS; +a native client that cannot do so delegates the channel verification to +its home server and verifies the KeyPackage signature itself. + +[RFC9420] Section 5.3.1 requires a credential to be validated whenever +it is introduced into the group. This protocol distributes that duty to +the party that introduces the credential: + +- Add: the admin client committing an Add MUST have validated the +KeyPackage as described above. Other members accept the new leaf on the +strength of the admin-signed Commit; they do not contact the new +member's home server. +- Update proposals, and Commits whose UpdatePath carries a new +credential: the successor credential MUST present the same OCM Address +as the credential it replaces, and members MUST reject the proposal or +Commit otherwise. This is the successor-credential policy anticipated +by [RFC9420] Section 5.3.1. Continuity of the signature key is anchored +in MLS itself: the message introducing the new leaf is signed with the +member's current key, so only the holder of the previous key can rotate +to a new one. +- Joining via Welcome: the joiner MUST verify the GroupInfo signature +and the integrity of the ratchet tree as required by [RFC9420] Section +12.4.3.1, and MUST verify that every leaf credential is a basic +credential carrying a well-formed OCM Address. The joiner accepts the +bindings of those credentials transitively, on the basis that each was +validated by an admin client when it was introduced. It MAY +additionally re-validate any leaf against the `/mls-key-packages` +endpoint of its home server, but such re-validation can fail benignly, +since published KeyPackages rotate independently of leaves already in +groups. + +In this transitive model, each home server is trusted to attest only its +own users, and each admin client is trusted to have performed the +attestation check at introduction time. A malicious home server can +impersonate its own users - it is their Authentication Service - but it +cannot impersonate users of other servers, since it cannot produce an +authenticated KeyPackage delivery for an OCM Address whose host part it +does not serve. + +Users who require protection of their key material from their own server +should choose a native client implementation where cryptographic +operations occur on the user's device. + +# Security Considerations {#security-considerations} + +**Trust model.** In web-client deployments, the OCM Server holds the +Group Key and can decrypt any resource shared with the group on behalf +of its users. This is consistent with the standard OCM Server trust +model, where users trust their server with their data, and with OCM's +existing approach of abstracting security to the server level. Native +client deployments provide stronger isolation, as the server does not +hold key material. Implementations SHOULD move toward native client +deployments over time. + +**FK rotation vs key-reuse.** FK rotation provides cryptographic access +revocation on member removal, independent of trust assumptions, and +SHOULD also be performed periodically or when key compromise is +suspected. In key-reuse mode the FK is unchanged and the ciphertext is +not re-encrypted, so revocation is not cryptographic: it relies on +trusting servers to discard all key material they are no longer entitled +to - superseded Group Keys, old wrapped FKs, and any cached unwrapped +FKs - after a Remove Commit. Key-reuse mode SHOULD only be used within +formal federations with governance agreements that enforce this +behaviour. + +**Two access-control layers.** For an encrypted federation share, access +is controlled at two independent layers: the per-server transport +credential in the `protocol` object gates who can fetch the ciphertext, +and the Group Key gates who can unwrap the FK and decrypt it. +Confidentiality rests on the cryptographic layer alone; the transport +credential provides defence in depth and is shared by all users on a +Member Server. The two layers can diverge: a server whose last group +member was just removed may still hold a valid transport credential +until the sending server revokes it, which is why revocation SHOULD +accompany the `SHARE_UNSHARED` notification. For unencrypted federation +shares the transport credential is the only access control, exactly as +in base OCM, and access-follows-membership then depends on the receiving +server re-evaluating share resolution on every Commit +({{share-creation}}) and on the sending server revoking the credentials +of departed servers promptly. + +**Credential rotation.** Rotated transport credentials are delivered in +group-encrypted `MLS_APPLICATION` messages sent only to the affected +server ({{credential-update}}). A removed member is excluded +cryptographically: it does not hold the new epoch's key material. Other +Member Servers are excluded only by targeted delivery; a credential +message that leaks to another member server is readable by it. Since +every Member Server already holds transport access to the same +ciphertext under its own credential, the impact of such a leak is +limited to transport-layer attribution. + +**Key distribution via Application Messages.** Wrapped FKs are +distributed in MLS `PrivateMessage` objects encrypted in the current +epoch. A removed member cannot decrypt these messages as they do not +hold the new epoch's key material. Because sending servers re-wrap and +redistribute FKs after every epoch transition ({{fk-rewrap}}), and +Member Servers always replace their locally stored wrapped FK with the +latest received, the current Group Key is always sufficient for +unwrapping once the re-wrapped FKs have arrived. + +**Group Key retention window.** Between processing a Commit and +receiving the re-wrapped FKs for the new epoch ({{fk-rewrap}}), a Member +Server may retain the previous epoch's Group Key in order to keep +serving access requests. This retention slightly weakens forward +secrecy for the duration of the window: a server compromised during the +window exposes the previous epoch's Group Key in addition to the current +one. The window is bounded by the arrival of the re-wrapped FKs, and +Member Servers MUST delete the previous Group Key as soon as it is no +longer needed, or after a bounded time, whichever comes first. + +**Commit ordering.** The Group Owner Server is the sole arbiter of +Commits, eliminating conflicting Commits for the same epoch during +normal operation. A compromised or unavailable Group Owner Server can +stall epoch transitions, but it cannot decrypt resource content, and it +cannot cause the group to accept a Commit constructed by a non-admin +client, because every Member Server independently verifies the committer +against the admin set before processing a Commit ({{admins}}). The role +passes automatically to the next admin's server when the first admin +leaves the group ({{admin-set}}), and an unavailable arbiter is +eventually replaced through failover ({{failover}}), during which +conflicting Commits can briefly exist and are resolved +deterministically. + +**Forked-state retention.** During a detected failover window, Member +Servers retain the previous epoch's group state so that they can revert +to the winning Commit ({{failover}}). Retaining forked state weakens +forward secrecy for its duration; [RFC9420] Section 14 requires such +state to be deleted promptly, so the retention is bounded in time and +limited to servers that have observed the failover trigger. + +**Rejoin.** The rejoin procedure ({{rejoin}}) lets a home server replace +its own users' leaves with fresh KeyPackages on the strength of its HTTP +Signature alone, without per-request admin approval. This grants no new +capability: the home server is already the trust anchor for its own +users' KeyPackages and could substitute their keys at any time through +the ordinary KeyPackage endpoint. Because admin clients verify that a +rejoin only replaces leaves whose OCM Addresses name the requesting +server and that are already present in the ratchet tree, a rejoin can +never admit a new party. + +**Admin liveness and removal latency.** A Remove proposal takes +cryptographic effect only when an admin client commits it. Removing +another member additionally requires explicit admin approval, so the +revocation latency for a membership change is bounded by admin +availability. Groups SHOULD appoint multiple admins, on multiple Member +Servers, to keep this window small and to avoid stalling group +operations when a single admin is offline. The same bound applies to +the post-compromise security provided by Update proposals, which only +take effect once committed. + +**Application message ordering.** Per [RFC9420] Section 15.2, sending +servers MUST apply a new epoch secret before encrypting any application +data. `MLS_APPLICATION` messages carrying re-wrapped keys MUST be sent +only after the sending server has processed the corresponding +`MLS_COMMIT`. + +**Ordering and the DS.** All ordering in this protocol derives from +MLS-authenticated metadata: Commits are ordered by the epoch they +advance, and FK updates by the `(epoch, generation)` of the enclosing +`PrivateMessage`. No unauthenticated transport counter is relied upon. +Servers in the DS role can still delay, drop, or selectively withhold +messages, but cannot reorder them undetectably or forge them, consistent +with the MLS threat model ([RFC9420] Section 16.9). + +**Reinitialisation continuity.** A reinitialisation Welcome is accepted +only with a resumption PSK from the old group's final epoch and after +verification of the old group's ReInit Commit and of membership +preservation ({{reinit}}). A party that was not a member of the old +group's final epoch cannot produce that PSK, so the binding between a +group's OCM Address and its MLS group state cannot be hijacked through a +forged reinitialisation. + +**Handshake message confidentiality.** Proposals and Commits are sent as +PublicMessage, so group operations are visible to the servers that +handle them. The MLS architecture [RFC9750] recommends encrypting +handshake messages to hide membership changes and signatures from the +Delivery Service; this protocol deliberately departs from that +recommendation because the servers performing the DS role must know the +group's membership anyway: sending servers derive notification +recipients from the ratchet tree, and receiving servers resolve +federation shares to their local users. No information is exposed to +those servers beyond what their OCM duties already require, and +transport protection (TLS and HTTP Signatures [RFC9421]) prevents +exposure to outside observers. Application Messages, which carry key +material, are always encrypted as PrivateMessage. + +**Group membership privacy.** The ratchet tree contains every member's +OCM Address and is held by every Member Server, so the full membership +of a group is visible to all servers that have a member in it. This is +inherent to the design - servers route shares and notifications using +exactly this information - but it sets the privacy baseline: federated +groups are not anonymous, and membership of a group is as visible to the +participating servers as membership of a shared folder. The tree is not +exposed to servers outside the group, and transport protection prevents +exposure to third parties. + +**Admin set integrity.** The admin set and the group's OCM Address are +carried in the GroupContext ({{admin-set}}), so they are covered by the +MLS confirmation tag and agreed upon by all members of every epoch. A +malicious server cannot unilaterally appoint admins or seize the Group +Owner Server role; changing the admin set requires a Commit constructed +by an existing admin client. + +**Post-compromise security.** Member Servers SHOULD periodically rotate +their users' leaf keys via Update proposals to maintain post-compromise +security ([RFC9420] Section 16.6). Members that do not update SHOULD +eventually be removed from the group. + +**Key material deletion.** Security-sensitive values MUST be deleted as +soon as they are consumed, per [RFC9420] Section 9.2. In particular, +the exporter_secret used to derive the Group Key must not be retained +after the Group Key has been derived. + +**KeyPackage reuse.** KeyPackages MUST be one-time use, except for a +designated last resort KeyPackage used when a user's single-use +KeyPackages are exhausted ([RFC9420] Section 16.8). Servers MUST remove +a KeyPackage that has been consumed, and SHOULD rate-limit KeyPackage +requests to make exhaustion attacks impractical. + +**User enumeration.** A server MUST only reply to HTTPS GET requests +signed using HTTP Message Signatures [RFC9421] and SHOULD implement rate +limiting and other access control methods on the `/mls-key-packages` +endpoint to avoid user enumeration. + +# IANA Considerations + +The MLS Exporter label `"ocm-group-key"` used in the Group Key +Derivation section is to be registered in the "MLS Exporter Labels" +registry defined in [RFC9420] Section 17.8, to avoid collisions with +other applications using the MLS Exporter: + +- Label: "ocm-group-key" +- Recommended: N +- Reference: This document + +The GroupContext extension `ocm_federated_group` defined in +{{admin-set}} is to be registered in the "MLS Extension Types" registry +defined in [RFC9420] Section 17.3: + +- Value: TBD +- Name: ocm_federated_group +- Message(s): GC +- Recommended: N +- Reference: This document + +# Open Issues + +This section collects open design issues and shall be removed before +publication. + +- **Streaming decryption.** A chunked AEAD construction enabling +streaming decryption of large files should be specified for native +client implementations. The specific construction and its interaction +with the FK wrapping model needs to be defined. +- **Application Message batching.** The frequency and batching of +`MLS_APPLICATION` messages carrying wrapped FKs needs to be defined. +Since every epoch transition triggers a re-wrap of every shared +resource's FK ({{fk-rewrap}}), batching is load-bearing when many shares +exist and epoch transitions are frequent. +- **Commit retransmission.** A missed Commit is detected directly from +the MLS epoch: a Commit arriving for a later epoch than the next +expected one indicates a gap. A mechanism for requesting retransmission +of missed Commits, from the Group Owner Server or any Admin Server, +needs to be specified. Retransmission is the first remedy for a gap; +the rejoin procedure ({{rejoin}}) is the fallback when retransmitted +Commits can no longer be applied. The proposed OCM Journaling mechanism +can be useful in this context. + +# References + +## Normative References + +[OCM] Lo Presti, G., de Jong, M.B., Baghbani, M. and Nordin, M. "[Open +Cloud +Mesh](https://datatracker.ietf.org/doc/draft-ietf-ocm-open-cloud-mesh/)", +Work in Progress, Internet-Draft, draft-ietf-ocm-open-cloud-mesh-04, +March 2026. + +[RFC2119] Bradner, S. "[Key words for use in RFCs to Indicate +Requirement Levels](https://datatracker.ietf.org/doc/html/rfc2119)", +March 1997. + +[RFC7517] Jones, M., "[JSON Web Key +(JWK)](https://datatracker.ietf.org/doc/html/rfc7517)", May 2015. + +[RFC8174] Leiba, B. "[Ambiguity of Uppercase vs Lowercase in RFC 2119 +Key Words](https://datatracker.ietf.org/html/rfc8174)", May 2017. + +[RFC9180] Barnes, R., Bhargavan, K., Lipp, B. and Wood, C. A. "[Hybrid +Public Key Encryption](https://datatracker.ietf.org/doc/html/rfc9180)", +February 2022. + +[RFC9420] Barnes, R., Beurdouche, B., Robert, R., Millican, J., Omara, +E. and Cohn-Gordon, K. "[The Messaging Layer Security (MLS) +Protocol](https://datatracker.ietf.org/doc/html/rfc9420)", July 2023. + +[RFC9421] Backman, A., Richer, J. and Sporny, M. "[HTTP Message +Signatures](https://datatracker.ietf.org/doc/html/rfc9421)", February +2024. + +## Informative References + +[RFC4918] Dusseault, L. M. "[HTTP Extensions for Web Distributed +Authoring and +Versioning](https://datatracker.ietf.org/doc/html/rfc4918)", June 2007. + +[RFC9750] Beurdouche, B., Rescorla, E., Omara, E., Inguva, S. and Duric, +A. "[The Messaging Layer Security (MLS) +Architecture](https://datatracker.ietf.org/doc/html/rfc9750)", April +2025. + +# Acknowledgements + +This work builds on the Open Cloud Mesh specification and the +discussions in the OCM community. + +Work on this document has been funded by [Sovereign Tech Agency][sta] +through the [Tech Fund][sta-fund], with a specific [project][sta-ocm]. + +[sta-ocm]: https://www.sovereign.tech/tech/open-cloud-mesh + +[sta-fund]: https://www.sovereign.tech/programs/fund + +--- back diff --git a/IETF-OCM-MLS.xml b/IETF-OCM-MLS.xml new file mode 100644 index 0000000..9a420b6 --- /dev/null +++ b/IETF-OCM-MLS.xml @@ -0,0 +1,2665 @@ + + + + + + + + + + +]> + + + + + Federated Groups in Open Cloud Mesh using Messaging Layer Security + + + SUNET +
+ kano@sunet.se + https://code.smolnet.org/micke +
+
+ + CERN +
+ giuseppe.lopresti@cern.ch + https://cern.ch/lopresti +
+
+ + Ponder Source +
+ mahdi@pondersource.org + https://pondersource.com +
+
+ + + + Applications and Real-Time + + Internet-Draft + + + + + + +This document defines an extension to the Open Cloud Mesh (OCM) protocol +to support federated groups as Receiving Parties of shares. This is +achieved using the Messaging Layer Security (MLS) protocol (RFC 9420) as +a group management layer. MLS is used for establishing and rotating a +shared group key across federated group members, as well as for +maintaining group state. This gives not only a way of federating group +membership, but also a standardized way of distributing encryption keys +in a cryptographically secure way, so that files shared with a group can +optionally be encrypted and decrypted. MLS usage in OCM acts as a +vehicle for group management that gives users optional encryption +capabilities for resources shared with federated groups. + + + + + + + +
+ + + + + + +
Introduction + +Open Cloud Mesh [OCM] currently supports sharing resources with +individual users across federated servers and with groups on a single +server. The specification also defines a shareType of "federation" +but does not further specify its semantics. This document gives +"federation" a concrete definition: a federated group identified by an +OCM Address such as research-group@receiver.example.org whose membership +spans multiple OCM servers, with group state managed through the MLS +[RFC9420] epoch mechanism. + +In many Enterprise File Sync and Share (EFSS) systems, which constitute +the vast majority of all OCM Servers, there is a tight coupling between +a client and a server, because the server offers a built-in web +interface as its primary client. In addition to this, a sync client is +often offered as a way of syncing files between the EFSS system and the +user's devices. + +In MLS, a client is defined as an agent that establishes shared +cryptographic state with other clients, defined by the cryptographic +keys it holds. An EFSS server meets this definition directly. For +deployments where the primary user interface is a web client, the OCM +Server fulfils the MLS client role server-side, holding key material on +behalf of its users, and the word "client" as used in this document +should not necessarily be taken to mean the user's file sync client. +Implementations that do provide a native client application SHOULD +perform cryptographic operations in the native client on the user's +devices, rather than on the server, because this provides stronger +isolation of key material from the server. In either case the same MLS +client model applies. + +Each user who is a member of a federated group has their own MLS leaf +node, enabling individual users to be added and removed independently. +The OCM Server can act as the MLS client on behalf of its users. For +implementations where the primary interface is a web client, the OCM +Server holds and uses key material server-side. Implementations with a +native client application SHOULD perform cryptographic operations in the +native client, with the server acting as a relay for MLS messages. + +Throughout this document, actions described as being performed by an OCM +server are understood to be performed by that server in its capacity as +an MLS client, on behalf of one of its users. The server holds no group +membership or cryptographic state independent of its users. + +The group and its membership exist and evolve independently of any +sharing activity. A user that wants to share a resource with a group +can do so without the need to know the current membership details of +that group. The MLS Delivery Service role is distributed: proposals are +delivered to the home servers of all admins, the Group Owner Server +arbitrates Commits, and File Key (FK) distribution messages are sent +directly from sending servers to member servers, just like OCM share +notifications. Group membership changes are managed entirely through +MLS group lifecycle operations. + +Every group has one or more admins: users who administer the group. The +user who creates a group is its first admin. Adding a member, or +removing a member other than oneself, requires the approval of an admin, +placing a human in the loop for changes that grant or revoke access. +Any member can remove themselves from a group without admin approval, +though the Commit is still performed by an admin client. All Commits +that advance the MLS epoch are constructed by the MLS clients of admins +and arbitrated by the Group Owner Server. + +The group's OCM Address is a stable label. It is minted under the +domain of the server where the group was created, which guarantees its +uniqueness, but it carries no routing semantics: all protocol messages +are routed using the OCM Addresses of individual members and admins, +never the group's. + +Files shared with a group can optionally be encrypted with a per-file +key (FK), wrapped with the current group key. The group key is derived +from the MLS epoch secret and rotates with every epoch transition. On +every epoch transition the sending server re-wraps the FK under the new +group key and redistributes it, so that the current group key is always +sufficient to unwrap the current FK. When a member is added to a group, +their MLS client receives the new group key and the re-wrapped FKs, and +can immediately decrypt all resources shared with the group. + +When a member is removed from the group, sending servers MAY +additionally generate a new FK and re-encrypt affected resources, +depending on their policy and the nature of the shared data. + +
+
Terminology + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and +"OPTIONAL" in this document are to be interpreted as described in BCP 14 +[RFC2119] [RFC8174] when, and only when, they appear in all capitals, as +shown here. + +This document uses terminology from [OCM] and [RFC9420]. Additional +definitions: + + + Group - A Receiving Party identified by an OCM Address whose +identifier resolves to a set of members spanning multiple OCM servers, +with group state managed through MLS. The Group's OCM Address is a +stable label assigned at creation and MUST NOT change for the lifetime +of the Group; it carries no routing semantics. In [RFC9420] a group is +defined as: "a logical collection of clients that share a common secret +value at any given time. Its state is represented as a linear sequence +of epochs in which each epoch depends on its predecessor." + MLS Client - As defined in [RFC9420]: an agent that establishes +shared cryptographic state with other clients, defined by the +cryptographic keys it holds. In this protocol an OCM Server can fulfill +this role. + Member Server - An OCM server with one or more users who are +members of a given Group, acting as MLS client on their behalf. + Group Owner Server - The server currently arbitrating Commits for +the Group: the home server of the first Admin in the admin set. +Initially this is the server at which the Group was created. + Admin - A user who administers the Group membership. The user who +creates a Group is its first Admin. Only the MLS clients of Admins +(admin clients) construct Commits. The admin set is part of the group +state (). + Admin Server - The home server of an Admin. Admin Servers +collectively queue proposals for the Group. + Group Key - A symmetric key derived from the current MLS epoch +secret via the MLS Exporter, with the key length of the AEAD algorithm +of the group's cipher suite. Rotates with every epoch transition. + File Key (FK) - A random symmetric key used to encrypt a single +shared resource. Wrapped with the current Group Key and distributed to +Member Servers via MLS Application Messages. Re-wrapped under the new +Group Key on every epoch transition (). Member Servers +always store the most current wrapped FK for each resource. + Re-encryption mode - On member removal, the sending server +generates a new FK, re-encrypts the resource, and distributes the new +wrapped key. Provides strong cryptographic guarantees independent of +trust assumptions. + Key-reuse mode - On member removal, the existing FK is kept and +only the standard re-wrap on epoch change () is performed, +without re-encrypting the resource. Appropriate only within formally +trusted federations and where re-encryption is impractical. Mode is not +a binary choice; sending servers can choose one mode for one epoch and +another mode for another epoch, depending on policy and other +circumstances. + KeyPackage - As defined in [RFC9420]. A signed object that +enables adding an MLS client to a group asynchronously. KeyPackages +MUST be used only once, except for a designated last resort KeyPackage +([RFC9420] Section 16.8). + + +
+
MLS Roles in OCM + +MLS is designed to operate with two supporting services: an +Authentication Service (AS) and a Delivery Service (DS) ([RFC9420] +Section 3; see also the MLS architecture [RFC9750]). This section +describes how those roles are fulfilled by OCM. + +
Authentication Service + +The AS role is fulfilled by each user's home OCM server. Credentials in +this protocol are MLS basic credentials ([RFC9420] Section 5.3) whose +identity field is the UTF-8 encoded OCM Address of the user. Each user +has their own distinct signing key pair so that individual users can be +identified and addressed independently within the MLS group, for example +to add or remove a specific user. In web-client deployments the key +pair is generated and held by the OCM Server on the user's behalf. In +native client deployments the key pair is held on the user's device and +the server's role is limited to publishing the user's KeyPackages. + +A basic credential carries no verifiable binding of its own; the binding +between a user's OCM Address and their signature key is attested by +authenticated delivery from the user's home server. A KeyPackage +fetched over TLS from the <endPoint>/mls-key-packages endpoint of the +server named in the credential's OCM Address, with the response signed +using HTTP Signatures [RFC9421] verifying against that server's JWKS +endpoint at /.well-known/jwks.json [RFC7517], is considered validated +with the AS. The full validation procedure, including how credentials +introduced later in the life of a group are validated, is specified in +. + +
+
Delivery Service + +The DS role is distributed across the servers of the group rather than +centralised on a single server. MLS places no constraints on how the DS +is arranged, as long as messages are delivered ([RFC9420] Section 3). + + + Proposal delivery: MLS_PROPOSAL notifications are sent to the home +server of every admin (), derived from the admin set and the +OCM Addresses in the ratchet tree's leaf credentials. Admin Servers +queue proposals, deduplicated by ProposalRef ([RFC9420] Section 5.2), +and make them available to their admin clients. + Commit arbitration: the Group Owner Server, the home server of the +first admin in the admin set, accepts exactly one Commit per epoch from +an admin client and broadcasts it to all Member Servers. + FK distribution: MLS_APPLICATION messages carrying wrapped file keys +are sent directly from the sending server to all current Member Servers, +exactly like OCM share notifications; credential updates are sent to a +single Member Server (). + + +All MLS messages are delivered to the <endPoint>/notifications +endpoint of each recipient server, authenticated with HTTP Signatures +[RFC9421]. + +Commits are constructed and signed by admin clients, but only the Commit +accepted by the Group Owner Server takes effect; competing Commits for +the same epoch are discarded by their senders. Designating a single +arbiter of Commits eliminates conflicting Commits for the same epoch +during normal operation, satisfying the sequencing requirement of +[RFC9420] Section 14; conflicting Commits can arise only during failover +and are then resolved deterministically (). Per [RFC9420] +Section 14, generating a Commit does not modify the sender's state, so +an admin client whose Commit is rejected simply discards it and +constructs a new Commit on the new epoch. + +OCM share notifications are sent directly from the sending server to +each Member Server. Since sending servers must be group members, they +hold the current MLS ratchet tree after processing each MLS_COMMIT, +and can derive the current membership - specifically the OCM Address in +each leaf node's credential - to determine which Member Servers to +contact. No proxying through the Group Owner Server is required for +OCM-level communication. + +MLS is designed to protect confidentiality and integrity even against a +misbehaving DS. No single server in this design carries the full DS +role, and no server holds key material by virtue of its DS duties; the +MLS security properties with respect to message confidentiality hold +regardless. + +
+
+
How MLS is implemented over OCM + + + MLS for group key management only. MLS establishes and rotates a +shared group key. The only MLS application messages used in this +protocol carry wrapped file keys () and per-server +transport credential updates (). + At least one MLS leaf per user. Each user who is a member of a +federated group has at least one MLS leaf node, enabling individual +users to be added and removed independently. In web-client deployments +the OCM Server manages a single leaf node per user on their behalf. In +native client deployments each user may have a leaf node per device. + The OCM Server is a MLS client. An OCM Server meets the MLS +definition of a client. For web-client deployments this means key +material is held server-side. For native client deployments +cryptographic operations SHOULD be performed in the native client. + Admins approve membership changes. Every group has one or more +admins (). Commits are constructed by admin clients and +arbitrated by the Group Owner Server. Add proposals and Remove +proposals targeting another user require admin approval; any member may +remove themselves, and Update proposals are committed automatically. + Encryption is optional. MLS group management is useful +independently of whether encryption is used. A federation share MAY be +unencrypted, in which case the encryption field is omitted from the +Share Creation Notification and the MLS layer provides only group +membership management. + FK re-wrap on every epoch change. After processing an MLS_COMMIT +for a group, a sending server MUST re-wrap the current FK of every +resource it shares with that group under the new Group Key and +distribute it via MLS_APPLICATION (). This maintains the +invariant that the current Group Key is always sufficient to unwrap the +current wrapped FK. + FK rotation on member removal. On member removal, a sending server +SHOULD additionally rotate the FK for affected resources: generate a new +FK, re-encrypt the resource, and distribute the new wrapped FK to all +groups that share those resources. FK rotation may also be triggered by +other factors such as periodic key rotation policy or suspected key +compromise. Member addition does not require FK rotation; the standard +re-wrap is sufficient. + Key-reuse mode as an alternative. Where re-encryption on removal +is impractical and where participating servers are mutually trusted +within a formal federation, a sending server MAY instead keep the +existing FK, relying on the standard per-epoch re-wrap alone. + Sending servers must have group members. To share a resource with +a group, the sending server must have at least one user who is a member +of that group, allowing it to work out the members to share with, and to +be able to wrap the FK for encrypted shares. This is by design, to +mitigate spam shares and other abusive behaviour. + OCM messages are still just OCM messages. Proposals flow to the +servers of all admins, Commits are arbitrated by the Group Owner Server, +and FK distribution and OCM share notifications flow directly from the +sending server to each Member Server, derived from the sending server's +local view of group membership from the MLS ratchet tree. No message is +proxied through a single central server. + Sending servers derive membership from the ratchet tree. Since +sending servers must have group members, they process all MLS_COMMIT +messages and hold the current ratchet tree. The OCM Address in each +leaf node's credential identifies the corresponding Member Server. The +sending server uses this to determine which Member Servers to contact +directly for share notifications and FK distribution. + Push-based FK distribution. Wrapped file keys are distributed via +MLS_APPLICATION directly from the sending server to all current Member +Servers, at share creation and after every epoch transition +(). Member Servers always hold the current wrapped FK for +each resource and use their current Group Key to unwrap it at access +time. + Minimal protocol surface. The shareType: "federation" value +already defined in the OCM specification is used without modification, +with shareWith carrying the group's OCM Address. A federation share +is otherwise a standard OCM share, carrying every field REQUIRED by +[OCM] including the protocol object. All new server-to-server +messages use the existing /notifications endpoint with new +notificationType values. A single new field is added to the Share +Creation Notification: encryption (optional, present only for +encrypted resources), carrying all encryption-related parameters, +including the resourceId. + + +
+
Discovery + +A server signals support for federation shares by including +"federation" in the shareTypes array for a given resource type in +its OCM discovery document at /.well-known/ocm: + +
+ +No additional discovery fields are introduced. The notifications +endpoint is derived as <endPoint>/notifications per the base OCM +specification. The KeyPackage endpoint is derived as +<endPoint>/mls-key-packages. + +A server that advertises "federation" MUST be able to receive OCM +Notifications, since all MLS lifecycle messages are delivered as +notifications, and SHOULD include "notifications" in its +capabilities array. + +
+
KeyPackage Distribution + +Each OCM Server acting as an MLS client generates and maintains +KeyPackages for its users and exposes them at: + +
/mls-key-packages?userId={userId} +]]>
+ +Response: + +
" + } + ] +} +]]>
+ +Requests to this endpoint MUST be signed using HTTP Message Signatures +[RFC9421] (). + +In native client deployments, the user's device generates KeyPackages +and publishes them to the home server, which exposes them at the same +endpoint without interpreting them. + +Each KeyPackage contains an MLS Credential identifying the user by their +OCM Address, signed by the user's own signing key pair. Users who +require stronger isolation of key material from their server should use +a native client implementation. + +KeyPackages MUST be one-time use, with the exception of a designated +"last resort" KeyPackage ([RFC9420] Section 16.8). The server MUST +remove a KeyPackage after it has been delivered. Servers SHOULD +pre-generate multiple KeyPackages per user to support concurrent group +additions, MAY designate a last resort KeyPackage per user to be +returned when all single-use KeyPackages are exhausted, and SHOULD +rate-limit KeyPackage requests, so that an attacker cannot block a +user's addition to groups by exhausting their KeyPackages. KeyPackages +carry a leaf node lifetime, and applications MUST define a maximum total +lifetime they accept ([RFC9420] Section 7.2). + +The userId fields defined in this document carry the user's full OCM +Address, not the bare identifier that [OCM] calls userID; the full +address is required because these messages routinely cross server +boundaries. + +
+
Group Lifecycle + +The group lifecycle is entirely independent of other OCM lifecycles +(token-exchange, shares, invitations etc.). Members are added and +removed through MLS group operations conveyed via the /notifications +endpoint. + +
Group Creation + +The creating server creates an MLS group on behalf of one of its users +and initialises leaf nodes for each of its users who are initial +members. The creating user becomes the group's first admin +(), making the creating server the initial Group Owner Server. +No notifications are required for this step. The group becomes +addressable at its OCM Address immediately upon creation. + +The group's OCM Address is minted under the creating server's domain, +which guarantees its uniqueness, and MUST NOT change for the lifetime of +the group. It is a label only: no protocol message is routed based on +it, and it remains valid even after the Group Owner Server role has +moved to another server. The MLS group_id SHOULD be a fresh random +value, as recommended by [RFC9420] Section 11. + +The creator selects the group's MLS cipher suite based on the +capabilities advertised in the prospective members' KeyPackages +([RFC9420] Section 11). Implementations of this document MUST support +the mandatory-to-implement MLS cipher suite +MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519 ([RFC9420] Section 17.1). + +
+
Group Admins + +Every group has a set of admins: users who administer the group +membership. The user who creates the group is its first admin, and an +admin MAY appoint further admins. Admins are ordinary group members and +MAY be homed on any Member Server. An admin's MLS clients are referred +to as admin clients. + +Commits MUST be constructed and signed by admin clients. This is an +application-level policy on top of MLS, as anticipated by [RFC9420] +Section 16.11, and it is enforced at two points. First, the Group Owner +Server MUST reject Commits submitted by any other client. Second, every +Member Server processing an MLS_COMMIT MUST verify that the Commit is +signed by an admin client: a Commit is signed by the leaf indicated in +its sender field ([RFC9420] Section 6.1), and the credential at that +leaf, in the ratchet tree of the epoch in which the Commit was created, +must identify a user listed in admins () as of that same +epoch. A Commit that fails this check MUST be rejected, regardless of +which server broadcast it. Because the admin set is part of the +GroupContext, every member performs this check locally; acceptance of a +Commit does not rely on trusting the Group Owner Server. + +Proposals are handled according to the following policy: + + + An Add proposal, or a Remove proposal targeting a leaf that does not +belong to the proposing user, MUST be explicitly approved by an admin +before an admin client commits it, unless both are part of a rejoin pair +as described below. This places a human in the loop for changes that +grant or revoke another party's access. + A Remove proposal targeting a leaf that belongs to the proposing user +(self-removal) does not require admin approval. Any member MAY leave a +group at any time, and admin clients SHOULD commit self-removal +proposals automatically. + A rejoin pair - a Remove of a leaf together with an Add of a fresh +KeyPackage whose credential carries the same OCM Address as the removed +leaf's credential () - is identity-preserving and grants no +new party access. It does not require explicit admin approval, and +admin clients SHOULD commit rejoin pairs automatically. + Update proposals do not require admin approval, and admin clients +SHOULD commit pending Update proposals automatically whenever they are +online. + + +The group MUST have at least one admin at all times. A proposal that +would remove the last admin, including a self-removal, MUST be rejected +by the Group Owner Server until another admin has been appointed. + +Removing an admin from the group and removing an admin from the admin +set are distinct operations; when an admin's membership ends, a single +Commit combines them (). An admin MAY instead resign from +the admin set while remaining a member: this is a GroupContextExtensions +proposal only, and the resigning admin's own client MAY commit it. +Removing an admin's membership is constrained by MLS: a Commit that +removes its own committer is invalid ([RFC9420] Section 12.2). A Commit +that removes some but not all of an admin's leaves MAY be committed by +one of that admin's remaining clients, but a Commit that removes an +admin's last leaf is necessarily committed by an admin client of a +different admin. + +
Group OCM Address and Admin Set + +The group's OCM Address and the admin set are part of the group state, +carried in a GroupContext extension ocm_federated_group ([RFC9420] +Section 13.4): + +
; +} Admin; + +struct { + opaque group_ocm_address; + Admin admins; +} OCMFederatedGroup; +]]>
+ +All addresses are UTF-8 encoded OCM Addresses. The group_ocm_address +field carries the group's OCM Address and MUST NOT change for the +lifetime of the group. + +The admins list is ordered by appointment: a newly appointed admin is +appended at the end, a departing admin is deleted by the same Commit +that ends their membership or admin role (see below), and the list MUST +NOT otherwise be reordered. The home server of the first admin in the +list is the current Group Owner Server. Succession is therefore +automatic: when the first admin leaves the group or resigns as admin, +the home server of the next admin in the list becomes the Group Owner +Server. For example, if alice on server1 creates the group and appoints +bob on server2 and then charlie on server3, the list is (alice, bob, +charlie) and server1 is the Group Owner Server; after bob leaves it is +(alice, charlie); after alice then leaves it is (charlie,) and server3 +is the Group Owner Server. + +An admin client is any MLS client whose leaf credential identifies a +user listed in admins. Because this extension is part of the +GroupContext, it is agreed upon by all members through the MLS key +schedule, every member can verify which clients are entitled to +construct Commits and which server arbitrates them, and new members +learn the group's OCM Address and admin set from the GroupInfo in their +Welcome. Changes to the admin set are made with a +GroupContextExtensions proposal ([RFC9420] Section 12.1.7); such +proposals MUST be explicitly approved by an admin, MUST be committed by +an admin client, and MUST NOT change group_ocm_address. + +The admin set and the group membership are coupled: an entry in admins +is only meaningful while that admin has at least one leaf in the ratchet +tree. A Commit after whose application an admin would no longer have +any leaf in the ratchet tree MUST therefore also include a +GroupContextExtensions proposal deleting that admin from admins, and +the Group Owner Server and all Member Servers MUST reject a Commit that +would leave an entry in admins with no corresponding leaf in the tree. +(A rejoin pair () that replaces an admin's leaf does not +trigger this rule, since the admin retains a leaf after the Commit.) +Because a GroupContextExtensions proposal replaces the extension list +wholesale ([RFC9420] Section 12.1.7), the proposal carries the complete +new OCMFederatedGroup value, with the departing admin deleted and +group_ocm_address unchanged. A GroupContextExtensions proposal whose +only change to the admin set is deleting admins whose leaves are removed +in the same Commit requires no separate admin approval; it follows the +approval status of the Remove proposals it accompanies, so that the +self-removal of an admin can still be committed automatically. + +Clients implementing this document MUST list the ocm_federated_group +extension type in the capabilities.extensions field of their +KeyPackages, since GroupContext extensions must be supported by every +member of the group ([RFC9420] Section 13.4). + +
+
+
Group Owner Server Failover + +The Group Owner Server can become unavailable, leaving the group without +an arbiter and therefore unable to advance its epoch. Leaf staleness +() anchors the failover trigger: the absence of +committed Updates from a leaf is part of the group state that all +members observe identically. The other trigger condition, the absence +of broadcast Commits, is necessarily observer-dependent - a server that +missed a broadcast cannot distinguish silence from loss - which is why +divergent failover decisions are tolerated and resolved +deterministically in step 3 below. + +In addition to the update deadline, groups MUST define a takeover time +T. T MUST be longer than the update deadline, so that the staleness of +the first admin's leaf is observable before takeover is permitted. +Failover proceeds as follows: + + + Trigger: no MLS_COMMIT has been broadcast for time T, and the +first admin's leaf is stale. + Takeover: the home server of the next admin in the admin set MAY +begin arbitrating Commits. The first Commit it arbitrates SHOULD +cover Remove proposals evicting the stale first admin's leaves, together +with the GroupContextExtensions proposal deleting them from the admin +set required by , constructed by one of its own admin +clients. This makes the takeover permanent through the normal +succession rule. + Conflict resolution: if a Member Server receives two different +Commits for the same epoch from two arbiters, it MUST process the +one arbitrated by the server of the admin listed earlier in the admin +set and discard the other. + Hold-back: a Member Server that has observed the trigger conditions +of step 1 SHOULD retain the previous epoch's group state when +processing a Commit, so that it can revert and reprocess the winning +Commit if conflict resolution later discards the one it processed first. +Retained state MUST be deleted after a bounded time, per [RFC9420] +Section 14; the security trade-off is discussed in Security +Considerations. + Rejoin: a Member Server that processed a discarded Commit and no +longer holds the state needed to reprocess the winning Commit has +drifted from the group. It recovers through the rejoin procedure +(). Wrapped FKs are re-wrapped and redistributed by their +sending servers in the new epoch as usual (). + + +Since an unavailable arbiter only pauses membership changes, while +sharing, resource access, and FK distribution continue to operate, the +takeover time T MAY be generous, for example several hours. Loose time +synchronisation between servers is sufficient and is already assumed by +MLS for leaf node lifetimes ([RFC9420] Section 7.2). + +
+
MLS Notification Types + +All MLS group lifecycle messages are sent as OCM Notifications to +<endPoint>/notifications using HTTP POST with Content-Type: +application/json and HTTP Signatures [RFC9421]. + +Proposals and Commits MUST be encoded as PublicMessage objects +([RFC9420] Section 6.2), and Application Messages as PrivateMessage +objects ([RFC9420] Section 6.3). Handshake messages are sent in the +clear at the MLS layer because the servers that route and arbitrate them +are required to track the public group state - the ratchet tree and +GroupContext - in order to derive membership for share routing, resolve +shares to local users, and verify that Commits are signed by admin +clients; in native client deployments those servers do not hold the +group's secrets. A recipient that holds the group's secrets MUST verify +the membership_tag on a PublicMessage ([RFC9420] Section 6.2); a server +relaying or arbitrating without group secrets verifies what it can, +namely the signature against the sender's leaf in its copy of the +ratchet tree and the policy checks of . The confidentiality +trade-off relative to encrypted handshake messages is discussed in +Security Considerations. + +The notification types defined in this document are group-scoped rather +than share-scoped. [OCM] requires a providerId field in notifications +because the notification types it defines all refer to a Share; the MLS +notification types refer to a group instead, so this document updates +that requirement: providerId is REQUIRED only for notification types +that refer to a Share, and the MLS notification types omit it. All +MLS-specific parameters are carried inside the notification object +that [OCM] provides for type-specific parameters. The mlsGroupId +field carries the base64-encoded MLS group_id as advisory routing +information, used to dispatch the message to the right group state +without parsing the MLS message; the authoritative group_id is the one +inside the MLS message itself, and a mismatch between the two MUST be +treated as an error. At the OCM layer, groups are otherwise identified +by their OCM Address: in particular, the groupId field of the +application data carried inside MLS_APPLICATION messages +(, ) is the group's OCM +Address, never the MLS group_id. + +Since MLS_PROPOSAL is delivered only to Admin Servers and never +broadcast to other Member Servers, Member Servers never observe pending +proposals. Proposals covered by a Commit are instead redistributed +together with that Commit, as described under MLS_COMMIT below. Admin +clients, as the only committers (), MUST satisfy all +considerations of [RFC9420] Section 12.4. + +
MLS_WELCOME + +Sent to a Member Server when one of its users is added to the group. +The Welcome is constructed by the admin client that created the +corresponding Commit ([RFC9420] Section 12.4.3.1) and delivered by that +admin's home server directly to the added user's server, after the Group +Owner Server has accepted the Commit. Delivers the MLS Welcome message +for the added user, enabling the receiving MLS client to initialise its +state and derive the current Group Key. A single MLS_COMMIT covering +multiple Add proposals will result in one MLS_WELCOME notification per +added user. + +
", + "userId": "bob@othercloud.example.org", + "content": "" + } +} +]]>
+ +The Welcome message MUST include the group's ratchet tree in a +ratchet_tree extension ([RFC9420] Section 12.4.3.3). By default a +Welcome carries only a hash of the tree, and this document defines no +other channel through which a newly added Member Server could obtain it. +Member Servers depend on holding the current ratchet tree, both to +derive the group membership and to process subsequent Commits. Carrying +the tree inside the Welcome also gives it the same confidentiality +protection as the rest of the group state, as recommended by [RFC9420] +Section 12.4.3.3. + +A Member Server processing a Welcome learns the group's OCM Address from +the ocm_federated_group extension in the GroupContext (). +It MUST reject a Welcome whose group_ocm_address is already bound to a +different MLS group_id, unless the Welcome reinitialises the group as +described in . This keeps the local wrapped FK store, keyed +by (resourceId, groupId), unambiguous. + +
+
MLS_PROPOSAL + +Sent by a Member Server to the home server of every admin to propose a +group change (for example Add, Remove, Update, GroupContextExtensions, +or ReInit) on behalf of one of its users. This notification is NOT +broadcast to other Member Servers. Each Admin Server queues received +proposals, deduplicated by ProposalRef ([RFC9420] Section 5.2), for +handling by its admin clients according to the policy in . +Sending the proposal to all Admin Servers removes the dependency on any +single server being available and lets whichever admin is online next +act on it. + +
", + "content": "" + } +} +]]>
+ +
+
MLS_COMMIT + +Constructed and signed by an admin client () and submitted to +the Group Owner Server, which accepts at most one Commit per epoch, MUST +reject Commits submitted by non-admin clients, and broadcasts the +accepted Commit to all Member Servers to advance the group epoch. An +admin client whose Commit is rejected discards it and MAY construct a +new Commit on the resulting epoch ([RFC9420] Section 14). A Member +Server receiving a broadcast MLS_COMMIT MUST verify that the Commit is +signed by an admin client before processing it, as specified in +, and MUST reject it otherwise, regardless of which server +broadcast it. Commits are ordered by the MLS epoch itself: each Commit +advances the epoch by exactly one, so Member Servers MUST process +Commits in epoch order, and a Commit arriving for an epoch later than +the next expected one indicates one or more missed Commits. Member +Servers MUST apply the new epoch secret before sending any application +data, per [RFC9420] Section 15.2. + +
", + "proposals": [""], + "content": "" + } +} +]]>
+ +A Commit covers each proposal either by value or by reference ([RFC9420] +Section 12.4). Proposals included by value are carried inside the +Commit itself and are necessarily proposals originated by the committing +admin client, since a by-value proposal carries no sender of its own. +Proposals received from Member Servers via MLS_PROPOSAL - in +particular Update proposals, which can only be applied relative to their +original sender's leaf - are covered by reference, and receiving Member +Servers need the original proposal messages in order to validate and +apply the Commit ([RFC9420] Sections 12.1 and 12.4.2). The proposals +array therefore carries every proposal covered by reference, verbatim as +originally sent by their proposers, in the order in which the +corresponding references appear in the Commit. It MUST be present +whenever the Commit covers at least one proposal by reference and MAY be +omitted otherwise. A Member Server processing an MLS_COMMIT MUST +process the carried proposals before processing the Commit itself. + +The MLS_COMMIT serves as the signal to all sending servers that the +epoch has advanced: each sending server then re-wraps and redistributes +the FKs of the resources it shares with the group (), and +on member removal MAY additionally rotate them according to its policy +(). Any Commit covering a Remove, Update, or +GroupContextExtensions proposal MUST include an UpdatePath ([RFC9420] +Section 12.4). + +
+
MLS_APPLICATION + +Sent by a sending server directly to Member Servers, derived from the +ratchet tree, to deliver updated wrapped file keys and, optionally, +updated per-server transport credentials (). No +central relay is involved. Messages carrying wrapped FKs are sent to +all current Member Servers; messages carrying a transport credential are +sent only to the affected Member Server. The content is a +PrivateMessage carrying application data encrypted in the current +epoch ([RFC9420] Section 15). + +
", + "content": "" + } +} +]]>
+ +Ordering is provided by authenticated MLS metadata rather than a +transport counter: the PrivateMessage carries the epoch in the clear, +and the sender's leaf and generation counter are learned upon decryption +([RFC9420] Section 6.3). Since all FK updates for a given (resourceId, +groupId) originate from the resource's sending server, the (epoch, +generation) pair totally orders them; see . A +Member Server that receives an MLS_APPLICATION encrypted in an epoch +it has not yet entered SHOULD queue it until the corresponding +MLS_COMMIT has been processed. + +Because credential-bearing messages are delivered to a single Member +Server, other Member Servers will observe a gap in the sending leaf's +generation counter on the next message they do receive. Such gaps are +expected and MUST NOT be treated as an error; receivers ratchet forward +past skipped generations as described in [RFC9420] Section 15.3. +Deployments MUST limit the number of generations a receiver will advance +a sender ratchet in response to a single message and reject messages +beyond that limit, bounding the key derivation work a malicious sender +can trigger ([RFC9420] Section 15.3). + +
+
MLS_REJOIN + +Sent by a drifted Member Server to the home server of every admin to +request re-admission of its users after local MLS state loss +(). Unlike the other notification types, the content is not +an MLS message: a drifted server holds no usable MLS state, so the +request is authenticated only at the OCM layer, by the HTTP Signature of +the sending server. Each entry in keyPackages carries a fresh MLS +KeyPackage for one affected user, in the same format as entries served +by the KeyPackage endpoint. + +
", + "keyPackages": [ + { + "userId": "bob@othercloud.example.org", + "mediaType": "message/mls", + "encoding": "base64", + "content": "" + } + ] + } +} +]]>
+ +Admin Servers queue rejoin requests alongside proposals and make them +available to their admin clients, which handle them as described in +. A later rejoin request for the same group and user +supersedes an earlier one; admin clients act on the most recent request. + +
+
+
Leaf Key Updates + +To maintain post-compromise security ([RFC9420] Section 16.6), Member +Servers SHOULD periodically send MLS_PROPOSAL (Update) to the Admin +Servers to rotate their users' leaf keys. Admin clients SHOULD commit +pending Update proposals automatically whenever they are online, without +user interaction; an Update only achieves post-compromise security once +it has been committed ([RFC9420] Section 16.6). + +Groups MUST define an update deadline: the maximum time allowed between +committed Updates of a leaf. A leaf that has not been updated within +the deadline is stale. Members with stale leaves SHOULD be removed from +the group per [RFC9420] Section 3.2, and stale admins in particular +SHOULD be removed promptly: an admin whose clients no longer update +cannot commit, and a stale first admin additionally blocks Commit +arbitration until failover (). + +
+
Rejoin After State Loss + +A Member Server can lose its MLS state for a group: it may have +processed a Commit that was later discarded during failover conflict +resolution () and already deleted the superseded epoch's +secrets per the deletion schedule ([RFC9420] Section 9.2), or its stored +state may be lost or corrupted for any other reason. Such a server has +drifted from the group: it can no longer process Commits or decrypt +Application Messages, and because MLS messages are bound to the current +GroupContext, it cannot sign a valid Proposal with which to recover. A +drifted server detects its condition when an MLS_COMMIT fails to +process against its local state, for example through a confirmation tag +mismatch, or arrives for an epoch it cannot reach after Commit +retransmission has been exhausted. + +Recovery is mediated by an admin client through the normal Commit path: + + + The drifted server discards its MLS state for the group and +generates a fresh KeyPackage for each of its users who are members +of the group. + It sends an MLS_REJOIN notification carrying those KeyPackages to +the home server of every admin. The notification is authenticated +at the OCM layer with HTTP Signatures [RFC9421], the same trust anchor +that authenticates KeyPackage distribution itself, so a rejoin request +is exactly as trustworthy as a freshly fetched KeyPackage. + An admin client verifies that each KeyPackage's credential carries +the OCM Address of a leaf currently in the ratchet tree, and that +the notification was signed by the server named in those OCM Addresses. +A rejoin MUST NOT admit a user without a leaf in the tree; it can only +replace existing members. + The admin client constructs a single Commit containing, by value, a +Remove proposal for each stale leaf and an Add proposal for the +corresponding fresh KeyPackage. This rejoin pair preserves the OCM +Address of every affected leaf and grants no new party access, so admin +clients SHOULD commit it automatically, per the policy in . + The Commit is arbitrated and broadcast as usual, and the drifted +server receives one MLS_WELCOME per re-added user, restoring clean +state from the Welcome's ratchet_tree extension. + + +A single Commit recovers all of the drifted server's users at once. +Until the rejoin completes, the drifted server can continue to serve +resources whose wrapped FKs it received before the fork, using the Group +Key of the last epoch it processed; wrapped FKs distributed after the +fork become accessible when the re-wrap following the rejoin Commit +() arrives. + +
+
Group Reinitialisation + +Reinitialisation ([RFC9420] Section 11.2) replaces a group with a new +MLS group with the same membership and the same OCM Address but +different parameters: a new MLS version, cipher suite, or extension set, +and necessarily a fresh MLS group_id. It is the migration path for +cryptographic agility, for example moving a long-lived group to a +stronger cipher suite. + +A ReInit proposal is a group parameter change and is handled like other +group-changing proposals: it MUST be explicitly approved by an admin and +MUST be committed by an admin client. Per [RFC9420] Section 12.2, a +ReInit proposal is committed alone. The extensions field of the +ReInit proposal MUST include an ocm_federated_group extension with +group_ocm_address unchanged; the admin set is normally carried over +unchanged. + +After the ReInit Commit is processed, the old group MUST NOT be used to +send messages ([RFC9420] Section 12.4.2). In particular, sending +servers MUST NOT send MLS_APPLICATION messages in the old group; the +per-epoch re-wrap obligation () arising from the ReInit +Commit is deferred to the new group. + +The admin client that committed the ReInit SHOULD create the new group: +it fetches fresh KeyPackages, valid for the new version and cipher +suite, for every member of the old group, creates the new group with an +initial Commit re-admitting them, and sends each member a Welcome +carrying a PreSharedKeyID of type resumption with usage reinit, as +specified by [RFC9420] Section 11.2. The Add proposals of this initial +Commit re-admit the old group's members and require no separate admin +approval. If the committing admin client fails to complete this step in +reasonable time, any other admin client MAY do so instead. If a Member +Server receives competing reinitialisation Welcomes for the same +group_ocm_address, it MUST accept the one whose new group was created +by the admin listed earliest in the old group's admin set and reject the +others. + +A Member Server processing a reinitialisation Welcome MUST perform the +verifications of [RFC9420] Section 12.4.3.1 for usage reinit: the last +Commit of the old group contains the ReInit proposal, the new group's +parameters match it, and every member of the old group is a member of +the new group, where members are equivalent if their leaf credentials +carry the same OCM Address. It MUST additionally verify that the +group_ocm_address of the new group equals that of the old group. On +success it rebinds the OCM Address from the old group_id to the new +one; this is the only case in which that binding may change. Because +the local wrapped FK store is keyed by the group's OCM Address, stored +entries carry over unchanged. + +After joining the new group, a sending server MUST re-wrap the FK of +every resource it shares with the group under the new group's Group Key +and redistribute the wrapped FKs to all Member Servers, exactly as for +an epoch change (). The new group's Group Key differs from +any key of the old group both through the fresh epoch secret and through +the new group_id in the Exporter context, so no wrapped FK from the +old group can be unwrapped in the new one. Until the re-wrapped FKs +arrive, Member Servers retain the old group's last Group Key under the +same retention rule as for an epoch change. Members SHOULD retain the +resumption PSK of the old group's final epoch until the reinitialisation +has completed ([RFC9420] Section 8.6). + +
+
+
Encryption Model + +
Group Key Derivation + +After processing any MLS Welcome or Commit, the MLS client MUST apply +the new epoch secret before encrypting any application data, then +derives the current Group Key: + +
+ +AEAD.Nk is the length in bytes of a key for the AEAD algorithm of the +group's negotiated MLS cipher suite ([RFC9420] Section 9.1). Deriving +the Group Key at exactly this length makes it a valid key for the wrap +AEAD (), which is the AEAD algorithm of the group's +cipher suite, for every cipher suite, including those whose AEAD takes a +16-byte key such as AES-128-GCM. + +The MLS Exporter ([RFC9420] Section 8.5) produces application-specific +key material from the epoch secret without exposing the epoch secret +itself. The label "ocm-group-key" scopes the output to this +application. The group_id_bytes context, the raw MLS group_id of +the group, further binds the output to this specific group. The Group +Key therefore changes with every epoch transition and cannot be derived +by any party that did not participate in that epoch. + +Per [RFC9420] Section 8.5, the Group Key SHOULD be refreshed after each +processed Commit. Security-sensitive values derived from the epoch +secret MUST be deleted as soon as they are consumed, per [RFC9420] +Section 9.2. + +All MLS clients in the group independently derive the same Group Key for +a given epoch. + +
+
Resource Id + +The resourceId used in the AEAD associated data MUST be a stable +identifier for the underlying file, consistent across all groups it is +shared with. It identifies the resource, not a particular version of +it. This ensures that the FK unwrapped by members of any group correctly +decrypts the same ciphertext. The providerId values in separate share +notifications, for the same resource, MUST differ, per the providerId +definition in [OCM], but the resourceId in the AEAD associated data +MUST be the same. This means that the providerId MUST NOT be reused +as resourceId. The sending server is responsible for maintaining this +stable resourceId and MUST send it in the encryption object of the +share payload (). + +
+
File Key Wrapping + +Two AEAD algorithms are involved in protecting a resource, and they are +deliberately decoupled. The content AEAD encrypts the resource itself: +it is chosen by the sending server from the AEAD algorithms defined for +HPKE ([RFC9180] Section 7.3), it is fixed for the lifetime of a +ciphertext and identical across all groups the resource is shared with, +and it is identified explicitly by the cipher field of the +encryption object (). The wrap AEAD protects the FK +in transit: it is always the AEAD algorithm of the respective group's +MLS cipher suite, keyed with that group's Group Key, and may therefore +differ between groups that share the same resource. + +When sharing an encrypted resource with a group, the sending MLS client +acts on behalf of a user who is a member of that group: + + + Chooses the content AEAD and generates a random per-file key (FK) +whose length is the key length of that algorithm. + Encrypts the resource with FK using the content AEAD. +Implementations supporting native client decryption of large files +SHOULD use a chunked AEAD construction to enable streaming decryption. + Derives the current Group Key from the user's local MLS state. + Wraps FK using the wrap AEAD: +
+ +where the associated data is the serialisation of the following +structure, in the presentation language of [RFC9420]: +
; + opaque resource_id; +} FKWrapAAD; +]]>
+ +The group_ocm_address field is the UTF-8 encoding of the group's +OCM Address (the same value carried in the shareWith field of the +share notification) and resource_id is the UTF-8 encoding of the +resourceId field of the encryption object. The length-prefixed +encoding makes the pair unambiguous; raw concatenation of the two +strings would allow distinct (address, identifier) pairs to produce +identical associated data. The MLS group_id is NOT used in the +associated data.
+ Sends an MLS_APPLICATION notification directly to all current +Member Servers, carrying the wrapped FK keyed by (resourceId, +groupId). +
+ +
+
FK Re-wrap on Epoch Change + +The Group Key changes with every epoch transition, whatever the reason +for the transition: a Commit covering Add, Remove, Update, or +GroupContextExtensions proposals, or an empty Commit, all advance the +epoch. To maintain the invariant that the current Group Key is always +sufficient to unwrap the current wrapped FK, a sending server MUST, +after processing an MLS_COMMIT for a group, or after joining the +successor group of a reinitialisation via its Welcome (), for +every resource it shares with that group: + + + Re-wrap the resource's current FK under the new Group Key, following +the procedure in . + Distribute the new wrapped FK to all current Member Servers, derived +from the new ratchet tree, via MLS_APPLICATION. + + +Note that the FK itself is unchanged by this procedure; only its +wrapping is refreshed. Whether the FK is also rotated is a separate, +removal-triggered policy decision (). + +If the Commit added one or more members, the set of Member Servers may +have grown. The sending server MUST identify Member Servers that are +new to the group and send them the Share Creation Notifications for its +federation shares with the group, as described in , in +addition to the wrapped FKs. A server that joins the group after a +share was created thereby receives both the share itself and a wrapped +FK it can decrypt, since the MLS_APPLICATION is encrypted in an epoch +in which it is a member. + +Between processing a Commit and receiving the re-wrapped FK for a +resource, a Member Server holds a wrapped FK produced under the previous +epoch's Group Key. To remain able to serve access requests in this +window, a Member Server SHOULD retain the previous epoch's Group Key +until it has received a strictly newer wrapped FK () +for every locally stored (resourceId, groupId) pair of that group, or +until a bounded time has elapsed, whichever comes first, and MUST delete +it at that point. The security trade-off of this retention window is +discussed in Security Considerations. + +The volume of MLS_APPLICATION traffic produced by this rule grows with +the number of shared resources and the frequency of epoch transitions; +see the batching item in Open Issues. + +
+
Key Distribution via MLS Application Messages + +Wrapped file keys are distributed to Member Servers via MLS Application +Messages, PrivateMessage objects carrying application data ([RFC9420] +Section 15). Wrapped FKs are distributed at share creation and +re-distributed after every epoch transition (). A sending +server MUST process the MLS_COMMIT and derive the new Group Key before +sending an MLS_APPLICATION with updated wrapped keys, per [RFC9420] +Section 15.2. + +The PrivateMessage application data is a JSON object carrying the +current wrapped FK for each (resourceId, groupId) pair in a keys +array, and MAY also carry a credentials array (): + +
" + } + ] +} +]]>
+ +The groupId field carries the group's OCM Address, matching the +shareWith of the corresponding share notification, and the +resourceId field matches the resourceId in the encryption object +of that notification. + +The PrivateMessage is encrypted using the current epoch's keys, so +only current group members can decrypt it. A just-removed member cannot +decrypt the Application Message even if they receive the notification, +as they do not hold the new epoch's key material. + +Member Servers store the received wrapped FKs locally, keyed by +(resourceId, groupId), always replacing any previous wrapped FK for +the same pair with the latest one. "Latest" is defined by the +authenticated (epoch, generation) of the enclosing PrivateMessage, +compared lexicographically, not by arrival order: a stored wrapped FK +MUST only be replaced by one with a strictly higher (epoch, +generation). A sending server MUST send all FK updates for a given +group through a single MLS leaf within any given epoch, since generation +counters are maintained per leaf; updates from a later epoch always +supersede updates from an earlier epoch regardless of leaf. MLS +Application Messages may be delayed or reordered in transit ([RFC9420] +Section 15.3); a Member Server that receives an out-of-order +MLS_APPLICATION simply ignores wrapped FKs that are not newer than +those it already holds. At access time, the Member Server uses its +current Group Key, derived from its current MLS state for the identified +group, to unwrap the FK. + +
+
Transport Credential Updates + +The per-server transport credential of a share () may +need to be rotated during the lifetime of the share. In particular, in +native client deployments the user's device interacts directly with the +sending server and therefore holds its server's credential, so when such +a user is removed from the group, the credential of their server can no +longer be considered private to that server's remaining users. On +removal of a member whose clients may have held a server's transport +credential, the sending server SHOULD rotate that server's credential +for every share affected. Rotation MAY also be triggered by policy or +suspected leakage. + +A rotated credential is delivered in an MLS_APPLICATION message sent +only to the affected Member Server, carrying a credentials array in +the application data: + +
" + } + ] +} +]]>
+ +Each entry identifies the share by its providerId, the group by its +OCM Address in groupId, and the intended Member Server by its FQDN in +recipient. A Member Server MUST ignore entries whose recipient does +not name itself. Upon accepting an entry, the Member Server replaces +the stored transport credential for that share; replacement follows the +same (epoch, generation) supersede rule as wrapped FKs +(). The sending server invalidates the old +credential once the rotation has been delivered. + +Encrypting the credential update in the current epoch guarantees that +the removed member cannot read it, independent of transport protection: +they do not hold the new epoch's key material. Confidentiality with +respect to other Member Servers, by contrast, rests on targeted +delivery: the PrivateMessage is decryptable by any group member that +obtains it, so delivering it to the affected server only is a routing +measure, not a cryptographic one (see Security Considerations). + +A keys array and a credentials array MAY appear in the same +application data object when both are destined for the same single +Member Server. + +
+
Resource Access + +To access a resource: + + + The resource is fetched from the sending server using the standard +OCM resource access procedure ([OCM]), with the protocol details and +per-server credential from the protocol object of the share +notification. For an encrypted resource, what is fetched is ciphertext. + The MLS client identifies the relevant group from the shareWith +field of the share notification and looks up the locally stored +wrapped_file_key for the (resourceId, groupId) pair. + The MLS client derives the current Group Key from its local MLS +state for that group and unwraps FK using the wrap AEAD of the +group's cipher suite. + The MLS client decrypts the resource using FK and the content AEAD +named in the cipher field of the encryption object. + + +In web-client deployments, decryption happens server-side and the +plaintext is served to the user through whatever access protocol is in +use (WebDAV [RFC4918], SFTP, webapp, etc.). In native client +deployments, decryption happens on the user's device and the client +interacts directly with the sending server, which serves only +ciphertext. + +
+
Resource Modification by Member Servers + +A common operation is for a user on a Member Server to open a shared +encrypted resource, modify it, and save it back. The cryptographic flow +is as follows: + + + The Member Server fetches the encrypted resource from the sending +server using the standard OCM resource access procedure, with the +credential from the share's protocol object. + The Member Server identifies the relevant group from the shareWith +field of the share notification, looks up the locally stored +wrapped_file_key for the (resourceId, groupId) pair, derives the +current Group Key from its local MLS state for that group, and unwraps +FK. + The Member Server decrypts the resource using FK and presents the +plaintext to the user. + The user modifies the resource. + The Member Server re-encrypts the modified resource using the same +FK and the same content AEAD, but a fresh random nonce. The nonce +MUST NOT be reused with the same key, as required by AEAD security. + The Member Server uploads the re-encrypted resource to the sending +server. This requires the share to grant write permission in its +protocol object. + + +The FK is reused across modifications of the same resource because it is +bound to the group's OCM Address and resourceId in the AEAD associated +data, making it specific to that resource. No new MLS_APPLICATION +message is needed, as the wrapped FK in all Member Servers' local stores +remains valid for the updated ciphertext. + +FK rotation for a resource is only necessary on member removal in +re-encryption mode (). + +
+
Sharing a Resource with Multiple Groups + +A sending server MAY share the same encrypted resource with more than +one group. The file is encrypted once, with a single FK and a single +content AEAD; the cipher field in every group's share notification +names that same algorithm. Each group receives its own wrapped FK, +produced with that group's wrap AEAD, Group Key, and OCM Address: + +
+ +A separate Share Creation Notification is sent to each Member Server of +each group. A separate MLS_APPLICATION carrying the respective +wrapped FK is broadcast to each group's Member Servers. Members of each +group can only unwrap the FK using their own group's Group Key and +cannot access the other group's wrapped FK or Group Key. + +The sending server MUST maintain a mapping from each resource to all +groups it has been shared with. This mapping is required to correctly +handle member removal in re-encryption mode, as described in the +following section. + +
+
FK Rotation (RECOMMENDED) + +FK rotation is distinct from the re-wrap performed on every epoch change +(): rotation generates a new FK and re-encrypts the +resource, whereas a re-wrap only refreshes the wrapping of the existing +FK. A sending server SHOULD rotate the FK for a resource when a member +is removed from any group that has access to it. FK rotation may also +be triggered by other factors, such as periodic key rotation policy, +regulatory requirements, or a suspected compromise of key material. +Applications SHOULD define a policy for the frequency of FK rotation +independent of membership changes. + +When rotating the FK for a resource, the sending server: + + + Generates a new FK for the resource. + Re-encrypts the resource with the new FK. + For every group that has access to the resource, wraps the new FK +using that group's current Group Key: +
+
+ Broadcasts an MLS_APPLICATION notification carrying the respective +new wrapped FK directly to each group's Member Servers. +
+ +Distributing the new wrapped FK to all groups that share the resource is +necessary because all groups share the same ciphertext. If only one +group received the new wrapped FK, members of other groups would hold a +wrapped FK that no longer decrypts the current ciphertext. + +A member removed from one group but still a member of another group that +shares the same resource retains the ability to decrypt that resource +through the second group. This is correct and intended behaviour: +access is determined by current group membership, and the user remains a +member of the second group. The default safe rule is to rotate the FK +and redistribute to all groups on any removal event. A sending server +MAY instead compare the unique set of users with access before and after +an epoch change, and skip FK rotation if that set is unchanged, for +example because the removed user remains a member of every other group +that has access to the same resource. Whether this optimisation is +worth the added complexity depends on the nature of the resource and the +frequency of membership changes. + +Member addition does not require FK rotation. The new member receives +the current Group Key via their Welcome, and the re-wrap triggered by +the Add Commit () delivers a wrapped FK, encrypted in an +epoch in which the new member is a member, that the new member can +unwrap with that Group Key. + +
+
Member Removal: Key-reuse Mode (OPTIONAL) + +Where re-encryption is impractical, for example due to frequent changes +of very large files, and where all participating servers belong to a +formal federation with explicit governance and mutual trust, a sending +server MAY instead keep the existing FK. In that case no action beyond +the standard re-wrap on epoch change () is required: the +Remove Commit advances the epoch, and the sending server re-wraps the +existing FK under the new Group Key and distributes it to the remaining +Member Servers of the affected group. + +When a resource is shared with multiple groups, only the epoch of the +group from which the member was removed has advanced, so only that +group's FK wrapping is refreshed. The wrapped FKs for other groups are +unchanged and remain valid for their respective members. + +In this mode, access-follows-membership relies on trust rather than +cryptography: the FK itself is unchanged, so a removed member's server +and, in native client deployments, the removed user's devices, may still +hold the superseded Group Key together with the old wrapped FK, or the +unwrapped FK itself, any of which decrypts the unchanged ciphertext. +Key-reuse mode therefore relies on trusting servers to discard key +material they are no longer entitled to after a Remove Commit. A +removed member who is also a member of another group that has access to +the same resource will still be able to decrypt via that group's wrapped +FK, which is the expected behaviour - they remain a member of that +group. This assumption is appropriate within a formal federation but +SHOULD NOT be made in open or ad-hoc sharing contexts. + +The sending server's choice of mode is its own policy decision and is +not signalled in the protocol. + +
+
Member Removal: OCM Notifications + +Member removal requires no OCM-level notification by itself. Because +federation shares are addressed to the group (), each +Member Server observes the Remove Commit and re-evaluates which of its +local users the share resolves to; a removed user loses access without +any action by the sending server. If the removed member's clients may +have held their server's transport credential, the sending server SHOULD +additionally rotate that credential (). + +When the last member homed on a given server is removed from the group, +that server no longer has any user with access. A well-behaved sending +server SHOULD then reconcile the OCM state of the share, revoke that +server's per-server transport credential (), and send +a SHARE_UNSHARED notification to the /notifications endpoint of that +server. + +
+
+
Share Creation + +The sending server sends one OCM Share Creation Notification directly to +each current Member Server, identified through the OCM Addresses in the +ratchet tree's leaf credentials. This is standard OCM server-to-server +communication, with shareWith set to the group's OCM Address and +shareType set to "federation". The share is addressed to the group +as the Receiving Party; no per-user notifications are sent. + +A federation share is a standard OCM share: every field that is REQUIRED +by [OCM], including the protocol object, is REQUIRED here too, and +resource access follows the standard OCM resource access procedure +driven by the protocol object. For encrypted resources the protocol +endpoint serves ciphertext; the plaintext is obtained by unwrapping the +FK as described in the Encryption Model. + +Each Member Server SHOULD be given its own sharedSecret (or equivalent +protocol credential) in its copy of the notification. The credential is +per server, not per user: all users on a Member Server share it, +mirroring how the server holds MLS state on behalf of its users. +Distinct per-server credentials allow the sending server to revoke a +single server's transport access, for example when the last group member +on that server is removed, without affecting other Member Servers. +Share Creation Notifications sent to servers that join the group later +() carry credentials minted at that time, and a server's +credential can be rotated during the share's lifetime +(). + +Share Permissions apply uniformly to the whole group: every member of +the group receives the same permissions on the resource. A sending +server that needs different permissions for different parties should use +separate groups or individual shares. Receiving Server criteria that +affect the share payload, such as must-exchange-token, are evaluated +per Member Server against that server's discovery document, exactly as +in base OCM. + +The receiving server resolves shareWith against its local MLS state: +it identifies the group whose group_ocm_address () +matches the shareWith value and delivers the share to every local user +whose leaf credential appears in that group's ratchet tree. On every +subsequent MLS_COMMIT the receiving server MUST re-evaluate this +resolution, so that local users added to the group gain access to +existing federation shares, and removed users lose it, without any +further OCM notifications. + +Addressing the share to the group also allows the receiving server to +distinguish between shares of the same resource arriving via different +groups - a user may be a member of two groups that both have access to +the same resource from the same sending server - and to correctly key +its local wrapped FK store by (resourceId, groupId) rather than +resourceId alone, where groupId is the group OCM Address carried in +shareWith, ensuring that FK updates delivered via MLS_APPLICATION +are applied to the correct entry. + +Because notifications can be delayed or reordered in transit, a +federation share MAY arrive before the receiving server has processed +the Welcome or Commit that made it a Member Server of the group. A +receiving server that does not recognise the shareWith value as a +known group SHOULD queue the share, or reject it in a way that causes +the sender to retry, rather than fail it permanently. Since sending +servers only contact servers present in the ratchet tree, this condition +is transient. + +When an MLS_COMMIT adds one or more members to the group, the sending +server MUST send each Member Server that is new to the group a Share +Creation Notification for every federation share it has with that group, +encrypted or not. For encrypted resources this accompanies the +re-wrapped FK (). A server that joins the group after a +share was created thereby learns of the shares its users now have access +to without any further action by its users. + +Each notification MAY include the optional encryption field: + +
", + "permissions": ["read", "write"] + } + }, + "encryption": { + "scheme": "ocm-mls-1", + "cipher": "AES-256-GCM", + "resourceId": "3a02538b-aa54-42f2-8853-a38996e211b1" + } +} +]]>
+ +The encryption field is OPTIONAL. If absent, the resource is +unencrypted and the share follows the standard OCM flow without +modification. If present, it carries all encryption-related parameters: +scheme identifies the encryption scheme, for which this document +defines "ocm-mls-1"; resourceId is the stable resource identifier +described in ; and cipher (REQUIRED when encryption +is present) names the content AEAD that the resource is encrypted with +(), one of the AEAD algorithms defined for HPKE +([RFC9180] Section 7.3): "AES-128-GCM", "AES-256-GCM", or +"CHACHA20-POLY1305". The field signals that the FK is distributed via +the MLS_APPLICATION mechanism keyed by (resourceId, groupId). No +epoch information is carried in the share notification. Member Servers +always hold the current wrapped FK for each (resourceId, groupId) pair +and use their current Group Key to unwrap it at access time. + +The Group Owner Server is not involved in the delivery of OCM share +notifications. All other OCM notifications relating to a share, such as +share updates and share deletions, are likewise sent directly from the +sending server to each Member Server, referencing the share by its +providerId as in base OCM. + +
+
Trust and Authentication + +The Authentication Service role ([RFC9420] Section 3) is fulfilled by +each user's home OCM server: the server that publishes a user's +KeyPackages attests the binding between the user's OCM Address and their +signature key. Because the basic credential itself carries no +verifiable binding, the attestation lies in the delivery channel. + +
Validation procedure + +A KeyPackage is considered validated with the AS when all of the +following hold: + + + it was fetched from the <endPoint>/mls-key-packages endpoint of the +server named in the credential's OCM Address, over TLS, with the +response signed using HTTP Signatures [RFC9421] verifying against that +server's JWKS [RFC7517]; + the OCM Address in the credential is identical to the userId the +KeyPackage was requested for, which is the OCM Address of the user the +requester intends to add; in particular, its host part names the server +the KeyPackage was fetched from; and + the KeyPackage signature verifies with the signature_key of its +LeafNode, proving possession of the private key ([RFC9420] Section +10.1). + + +Requests to the KeyPackage endpoint are signed at the server level +(), so in native client deployments the +fetch is performed by the admin's home server on the admin client's +behalf. The home server SHOULD relay the response with its HTTP +Message Signature intact, allowing the native client to verify the +channel binding end-to-end against the target server's published JWKS; +a native client that cannot do so delegates the channel verification to +its home server and verifies the KeyPackage signature itself. + +[RFC9420] Section 5.3.1 requires a credential to be validated whenever +it is introduced into the group. This protocol distributes that duty to +the party that introduces the credential: + + + Add: the admin client committing an Add MUST have validated the +KeyPackage as described above. Other members accept the new leaf on the +strength of the admin-signed Commit; they do not contact the new +member's home server. + Update proposals, and Commits whose UpdatePath carries a new +credential: the successor credential MUST present the same OCM Address +as the credential it replaces, and members MUST reject the proposal or +Commit otherwise. This is the successor-credential policy anticipated +by [RFC9420] Section 5.3.1. Continuity of the signature key is anchored +in MLS itself: the message introducing the new leaf is signed with the +member's current key, so only the holder of the previous key can rotate +to a new one. + Joining via Welcome: the joiner MUST verify the GroupInfo signature +and the integrity of the ratchet tree as required by [RFC9420] Section +12.4.3.1, and MUST verify that every leaf credential is a basic +credential carrying a well-formed OCM Address. The joiner accepts the +bindings of those credentials transitively, on the basis that each was +validated by an admin client when it was introduced. It MAY +additionally re-validate any leaf against the /mls-key-packages +endpoint of its home server, but such re-validation can fail benignly, +since published KeyPackages rotate independently of leaves already in +groups. + + +In this transitive model, each home server is trusted to attest only its +own users, and each admin client is trusted to have performed the +attestation check at introduction time. A malicious home server can +impersonate its own users - it is their Authentication Service - but it +cannot impersonate users of other servers, since it cannot produce an +authenticated KeyPackage delivery for an OCM Address whose host part it +does not serve. + +Users who require protection of their key material from their own server +should choose a native client implementation where cryptographic +operations occur on the user's device. + +
+
+
Security Considerations + +Trust model. In web-client deployments, the OCM Server holds the +Group Key and can decrypt any resource shared with the group on behalf +of its users. This is consistent with the standard OCM Server trust +model, where users trust their server with their data, and with OCM's +existing approach of abstracting security to the server level. Native +client deployments provide stronger isolation, as the server does not +hold key material. Implementations SHOULD move toward native client +deployments over time. + +FK rotation vs key-reuse. FK rotation provides cryptographic access +revocation on member removal, independent of trust assumptions, and +SHOULD also be performed periodically or when key compromise is +suspected. In key-reuse mode the FK is unchanged and the ciphertext is +not re-encrypted, so revocation is not cryptographic: it relies on +trusting servers to discard all key material they are no longer entitled +to - superseded Group Keys, old wrapped FKs, and any cached unwrapped +FKs - after a Remove Commit. Key-reuse mode SHOULD only be used within +formal federations with governance agreements that enforce this +behaviour. + +Two access-control layers. For an encrypted federation share, access +is controlled at two independent layers: the per-server transport +credential in the protocol object gates who can fetch the ciphertext, +and the Group Key gates who can unwrap the FK and decrypt it. +Confidentiality rests on the cryptographic layer alone; the transport +credential provides defence in depth and is shared by all users on a +Member Server. The two layers can diverge: a server whose last group +member was just removed may still hold a valid transport credential +until the sending server revokes it, which is why revocation SHOULD +accompany the SHARE_UNSHARED notification. For unencrypted federation +shares the transport credential is the only access control, exactly as +in base OCM, and access-follows-membership then depends on the receiving +server re-evaluating share resolution on every Commit +() and on the sending server revoking the credentials +of departed servers promptly. + +Credential rotation. Rotated transport credentials are delivered in +group-encrypted MLS_APPLICATION messages sent only to the affected +server (). A removed member is excluded +cryptographically: it does not hold the new epoch's key material. Other +Member Servers are excluded only by targeted delivery; a credential +message that leaks to another member server is readable by it. Since +every Member Server already holds transport access to the same +ciphertext under its own credential, the impact of such a leak is +limited to transport-layer attribution. + +Key distribution via Application Messages. Wrapped FKs are +distributed in MLS PrivateMessage objects encrypted in the current +epoch. A removed member cannot decrypt these messages as they do not +hold the new epoch's key material. Because sending servers re-wrap and +redistribute FKs after every epoch transition (), and +Member Servers always replace their locally stored wrapped FK with the +latest received, the current Group Key is always sufficient for +unwrapping once the re-wrapped FKs have arrived. + +Group Key retention window. Between processing a Commit and +receiving the re-wrapped FKs for the new epoch (), a Member +Server may retain the previous epoch's Group Key in order to keep +serving access requests. This retention slightly weakens forward +secrecy for the duration of the window: a server compromised during the +window exposes the previous epoch's Group Key in addition to the current +one. The window is bounded by the arrival of the re-wrapped FKs, and +Member Servers MUST delete the previous Group Key as soon as it is no +longer needed, or after a bounded time, whichever comes first. + +Commit ordering. The Group Owner Server is the sole arbiter of +Commits, eliminating conflicting Commits for the same epoch during +normal operation. A compromised or unavailable Group Owner Server can +stall epoch transitions, but it cannot decrypt resource content, and it +cannot cause the group to accept a Commit constructed by a non-admin +client, because every Member Server independently verifies the committer +against the admin set before processing a Commit (). The role +passes automatically to the next admin's server when the first admin +leaves the group (), and an unavailable arbiter is +eventually replaced through failover (), during which +conflicting Commits can briefly exist and are resolved +deterministically. + +Forked-state retention. During a detected failover window, Member +Servers retain the previous epoch's group state so that they can revert +to the winning Commit (). Retaining forked state weakens +forward secrecy for its duration; [RFC9420] Section 14 requires such +state to be deleted promptly, so the retention is bounded in time and +limited to servers that have observed the failover trigger. + +Rejoin. The rejoin procedure () lets a home server replace +its own users' leaves with fresh KeyPackages on the strength of its HTTP +Signature alone, without per-request admin approval. This grants no new +capability: the home server is already the trust anchor for its own +users' KeyPackages and could substitute their keys at any time through +the ordinary KeyPackage endpoint. Because admin clients verify that a +rejoin only replaces leaves whose OCM Addresses name the requesting +server and that are already present in the ratchet tree, a rejoin can +never admit a new party. + +Admin liveness and removal latency. A Remove proposal takes +cryptographic effect only when an admin client commits it. Removing +another member additionally requires explicit admin approval, so the +revocation latency for a membership change is bounded by admin +availability. Groups SHOULD appoint multiple admins, on multiple Member +Servers, to keep this window small and to avoid stalling group +operations when a single admin is offline. The same bound applies to +the post-compromise security provided by Update proposals, which only +take effect once committed. + +Application message ordering. Per [RFC9420] Section 15.2, sending +servers MUST apply a new epoch secret before encrypting any application +data. MLS_APPLICATION messages carrying re-wrapped keys MUST be sent +only after the sending server has processed the corresponding +MLS_COMMIT. + +Ordering and the DS. All ordering in this protocol derives from +MLS-authenticated metadata: Commits are ordered by the epoch they +advance, and FK updates by the (epoch, generation) of the enclosing +PrivateMessage. No unauthenticated transport counter is relied upon. +Servers in the DS role can still delay, drop, or selectively withhold +messages, but cannot reorder them undetectably or forge them, consistent +with the MLS threat model ([RFC9420] Section 16.9). + +Reinitialisation continuity. A reinitialisation Welcome is accepted +only with a resumption PSK from the old group's final epoch and after +verification of the old group's ReInit Commit and of membership +preservation (). A party that was not a member of the old +group's final epoch cannot produce that PSK, so the binding between a +group's OCM Address and its MLS group state cannot be hijacked through a +forged reinitialisation. + +Handshake message confidentiality. Proposals and Commits are sent as +PublicMessage, so group operations are visible to the servers that +handle them. The MLS architecture [RFC9750] recommends encrypting +handshake messages to hide membership changes and signatures from the +Delivery Service; this protocol deliberately departs from that +recommendation because the servers performing the DS role must know the +group's membership anyway: sending servers derive notification +recipients from the ratchet tree, and receiving servers resolve +federation shares to their local users. No information is exposed to +those servers beyond what their OCM duties already require, and +transport protection (TLS and HTTP Signatures [RFC9421]) prevents +exposure to outside observers. Application Messages, which carry key +material, are always encrypted as PrivateMessage. + +Group membership privacy. The ratchet tree contains every member's +OCM Address and is held by every Member Server, so the full membership +of a group is visible to all servers that have a member in it. This is +inherent to the design - servers route shares and notifications using +exactly this information - but it sets the privacy baseline: federated +groups are not anonymous, and membership of a group is as visible to the +participating servers as membership of a shared folder. The tree is not +exposed to servers outside the group, and transport protection prevents +exposure to third parties. + +Admin set integrity. The admin set and the group's OCM Address are +carried in the GroupContext (), so they are covered by the +MLS confirmation tag and agreed upon by all members of every epoch. A +malicious server cannot unilaterally appoint admins or seize the Group +Owner Server role; changing the admin set requires a Commit constructed +by an existing admin client. + +Post-compromise security. Member Servers SHOULD periodically rotate +their users' leaf keys via Update proposals to maintain post-compromise +security ([RFC9420] Section 16.6). Members that do not update SHOULD +eventually be removed from the group. + +Key material deletion. Security-sensitive values MUST be deleted as +soon as they are consumed, per [RFC9420] Section 9.2. In particular, +the exporter_secret used to derive the Group Key must not be retained +after the Group Key has been derived. + +KeyPackage reuse. KeyPackages MUST be one-time use, except for a +designated last resort KeyPackage used when a user's single-use +KeyPackages are exhausted ([RFC9420] Section 16.8). Servers MUST remove +a KeyPackage that has been consumed, and SHOULD rate-limit KeyPackage +requests to make exhaustion attacks impractical. + +User enumeration. A server MUST only reply to HTTPS GET requests +signed using HTTP Message Signatures [RFC9421] and SHOULD implement rate +limiting and other access control methods on the /mls-key-packages +endpoint to avoid user enumeration. + +
+
IANA Considerations + +The MLS Exporter label "ocm-group-key" used in the Group Key +Derivation section is to be registered in the "MLS Exporter Labels" +registry defined in [RFC9420] Section 17.8, to avoid collisions with +other applications using the MLS Exporter: + + + Label: "ocm-group-key" + Recommended: N + Reference: This document + + +The GroupContext extension ocm_federated_group defined in + is to be registered in the "MLS Extension Types" registry +defined in [RFC9420] Section 17.3: + + + Value: TBD + Name: ocm_federated_group + Message(s): GC + Recommended: N + Reference: This document + + +
+
Open Issues + +This section collects open design issues and shall be removed before +publication. + + + Streaming decryption. A chunked AEAD construction enabling +streaming decryption of large files should be specified for native +client implementations. The specific construction and its interaction +with the FK wrapping model needs to be defined. + Application Message batching. The frequency and batching of +MLS_APPLICATION messages carrying wrapped FKs needs to be defined. +Since every epoch transition triggers a re-wrap of every shared +resource's FK (), batching is load-bearing when many shares +exist and epoch transitions are frequent. + Commit retransmission. A missed Commit is detected directly from +the MLS epoch: a Commit arriving for a later epoch than the next +expected one indicates a gap. A mechanism for requesting retransmission +of missed Commits, from the Group Owner Server or any Admin Server, +needs to be specified. Retransmission is the first remedy for a gap; +the rejoin procedure () is the fallback when retransmitted +Commits can no longer be applied. The proposed OCM Journaling mechanism +can be useful in this context. + + +
+
References + +
Normative References + +[OCM] Lo Presti, G., de Jong, M.B., Baghbani, M. and Nordin, M. "Open +Cloud +Mesh", +Work in Progress, Internet-Draft, draft-ietf-ocm-open-cloud-mesh-04, +March 2026. + +[RFC2119] Bradner, S. "Key words for use in RFCs to Indicate +Requirement Levels", +March 1997. + +[RFC7517] Jones, M., "JSON Web Key +(JWK)", May 2015. + +[RFC8174] Leiba, B. "Ambiguity of Uppercase vs Lowercase in RFC 2119 +Key Words", May 2017. + +[RFC9180] Barnes, R., Bhargavan, K., Lipp, B. and Wood, C. A. "Hybrid +Public Key Encryption", +February 2022. + +[RFC9420] Barnes, R., Beurdouche, B., Robert, R., Millican, J., Omara, +E. and Cohn-Gordon, K. "The Messaging Layer Security (MLS) +Protocol", July 2023. + +[RFC9421] Backman, A., Richer, J. and Sporny, M. "HTTP Message +Signatures", February +2024. + +
+
Informative References + +[RFC4918] Dusseault, L. M. "HTTP Extensions for Web Distributed +Authoring and +Versioning", June 2007. + +[RFC9750] Beurdouche, B., Rescorla, E., Omara, E., Inguva, S. and Duric, +A. "The Messaging Layer Security (MLS) +Architecture", April +2025. + +
+
+
Acknowledgements + +This work builds on the Open Cloud Mesh specification and the +discussions in the OCM community. + +Work on this document has been funded by [Sovereign Tech Agency][sta] +through the Tech Fund, with a specific project. + +
+ + +
+ + + + + + + + + + + + +
+ diff --git a/work/mls-over-ocm/cm-mls-federated-groups.md b/work/mls-over-ocm/cm-mls-federated-groups.md deleted file mode 100644 index 35bd927..0000000 --- a/work/mls-over-ocm/cm-mls-federated-groups.md +++ /dev/null @@ -1,883 +0,0 @@ -# Federated Groups in OCM using MLS - ---- - -## Abstract - -This document proposes an extension to the Open Cloud Mesh (OCM) -protocol to support federated groups as receiving parties of shares. -This is achieved using the Messaging Layer Security (MLS) protocol -[RFC9420] as a group management layer. MLS is used for establishing and -rotating a shared group key across federated group members, as well as -for maintaining group state. This gives us not only a way of federating -group membership, but also a standardized way of distributing encryption -keys in a cryptographically secure way, so that we can optionally -encrypt and decrypt files shared across a group. MLS usage in OCM is not -used to carry application messages (i.e. for "chatting"), but rather as -a vehicle for group management that gives users optional encryption -capabilities for resources shared with federated groups. - -In many EFSS systems, there is a tight coupling between a client and a -server, because the server offers a built in web interface as it's -primary client. In addition to this a `sync client` is often offered as -a way of syncing files between the EFSS system and the users devices. - -In MLS, a client is defined as an agent that establishes shared -cryptographic state with other clients, defined by the cryptographic -keys it holds. - -An EFSS server meets this definition directly. For deployments where the -primary user interface is a web client, the EFSS fulfils the MLS client -role server-side, holding key material on behalf of its users and the -word `client` as used in this text should not neccessarily be taken to -mean the users file sync client. Implementations that do provide a -native client application SHOULD perform cryptographic operations in the -native client on the users devices, rather than on the server, because -this provides stronger isolation of key material from the server. In -either case the same MLS client model applies. - -Files shared with a group can optionally be encrypted with a per-file -key (FK), wrapped with the current group key. The group key is derived -from the MLS epoch secret and rotates with every epoch transition. When -a member is added to a group, their MLS client receives the new group -key and can immediately decrypt all resources shared with the group. -When a member is removed, the group key rotates. - -On member removal, a sending server SHOULD rotate the FK for affected -resources, re-encrypting with a new FK and distributing the new wrapped -FK to all groups that share those resources. This provides strong -cryptographic guarantees regardless of trust assumptions. Where -re-encryption is impractical, for example due to frequent changes in -groups with very large files, and where participating servers belong to -a formal federation with explicit governance and mutual trust, a sending -server acting as an MLS client MAY instead re-wrap the existing FK under -the new group key without re-encrypting the file data. In this case, -access-follows-membership relies on trusting member servers not to -retain superseded group keys. - ---- - -## 1. Introduction - -OCM currently supports sharing resources with individual users across -federated servers and with groups on a single server. The specification -also defines a `shareType` of `"federation"` but does not further -specify its semantics. This proposal gives `"federation"` a concrete -definition: a federated group identified by an OCM Address such as -`research-group@cloud.example.org` whose membership spans multiple OCM -servers, with group state managed through the MLS epoch mechanism. - -Each user who is a member of a federated group has their own MLS leaf -node, enabling individual users to be added and removed independently. -The EFSS can act as the MLS client on behalf of its users. For -implementations where the primary interface is a web client, the EFSS -holds and uses key material server-side. Implementations with a native -client application SHOULD perform cryptographic operations in the native -client, with the server acting as a relay for MLS messages. - -Throughout this document, actions described as being performed by an OCM -server are understood to be performed by that server in its capacity as -an MLS client, on behalf of one of its users. The server holds no -independent group membership or cryptographic state independent of it's -users. - -The group and its membership exist and evolve independently of any -sharing activity. A user that wants to share a resource with a group can -do so without the need to know the current membership details of that -group. The Group Owner Server acts as the MLS Delivery Service, the -single distribution point for all MLS group lifecycle messages and FK -distribution. OCM share notifications are sent directly between sending -servers and member servers. Group membership changes are managed -entirely through MLS group lifecycle operations. - -When a member is removed from the group, sending servers are notified -via the MLS commit mechanism and MAY choose to re-encrypt affected -resources or re-wrap existing per-file keys, depending on their policy -and the nature of the shared data. - ---- - -## 2. MLS Roles in OCM - -MLS is designed to operate with two supporting services: an -Authentication Service (AS) and a Delivery Service (DS). This section -describes how those roles are fulfilled by OCM. - -### 2.1. Authentication Service - -The AS role is fulfilled by each user's home OCM server. MLS Credentials -in KeyPackages identify users by their OCM Address and are signed by the -user's own signing key pair. Each user has their own distinct signing -key pair so that individual users can be identified and addressed -independently within the MLS group, for example to add or remove a -specific user. In web-client deployments the key pair is generated and -held by the EFSS on the user's behalf. In native client deployments the -key pair is held on the user's device and the server's role is limited -to publishing the public key. - -A group member authenticates another member's credential by fetching -their KeyPackage from the canonical `/mls-key-packages` -endpoint of the server named in the OCM Address and verifying the -signature against the published public key. The server-to-server channel -over which KeyPackages are fetched is authenticated using HTTP -Signatures [RFC9421], with the server's public key discoverable via its -JWKS endpoint at `/.well-known/jwks.json` [RFC7517]. - -### 2.2. Delivery Service - -The Group Owner Server fulfils the DS role for MLS group lifecycle -messages. It serialises incoming `MLS_PROPOSAL` notifications into -Commits, broadcasts `MLS_COMMIT` notifications to all member servers -with monotonically increasing sequence numbers, and broadcasts -`MLS_APPLICATION` messages carrying wrapped file keys to all current -member servers. All MLS messages are delivered to the -`/notifications` endpoint of each recipient server, -authenticated with HTTP Signatures [RFC9421]. - -By designating the Group Owner Server as the sole committer, this design -eliminates the possibility of conflicting Commits for the same epoch, -satisfying the sequencing requirement of [RFC9420] Section 14 without -requiring a conflict resolution protocol. - -OCM share notifications are sent directly from the sending server to -each member server. Since sending servers must be group members, they -hold the current MLS ratchet tree after processing each `MLS_COMMIT`, -and can derive the current membership — specifically the OCM Address in -each leaf node's credential — to determine which member servers to -contact. No proxying through the Group Owner Server is required for -OCM-level communication. - -MLS is designed to protect confidentiality and integrity even against a -misbehaving DS. The Group Owner Server carries more responsibility than -a typical MLS DS since it also relays key distribution messages, but the -MLS security properties with respect to message confidentiality still -hold. - ---- - -## 3. Design Principles - -- **MLS for group key management only.** MLS establishes and rotates a - shared group key. The only MLS application messages used in this - protocol carry wrapped file keys as described in Section 8.3. - -- **At least one MLS leaf per user.** Each user who is a member of a - federated group has at least one MLS leaf node, enabling individual - users to be added and removed independently. In web-client deployments - the EFSS manages a single leaf node per user on their behalf. In - native client deployments each user may have a leaf node per device. - -- **The EFSS is the MLS client.** An EFSS meets the MLS definition of a - client. For web-client deployments this means key material is held - server-side. For native client deployments cryptographic operations - SHOULD be performed in the native client. - -- **Encryption is optional.** MLS group management is useful - independently of whether encryption is used. A federation share MAY be - unencrypted, in which case the `encryption` field is omitted from the - Share Creation Notification and the MLS layer provides only group - membership management. - -- **FK rotation on member removal.** On member removal, a sending server - SHOULD rotate the FK for affected resources and distribute the new - wrapped FK to all groups that share those resources. FK rotation may - also be triggered by other factors such as periodic key rotation - policy or suspected key compromise. Member addition does not require - FK rotation. - -- **Key-reuse mode as an alternative.** Where re-encryption on removal - is impractical and where participating servers are mutually trusted - within a formal federation, a sending server MAY instead re-wrap the - existing FK under the new group key. - -- **Sending servers must have group members.** To share a resource with - a group, the sending server must have at least one user who is a - member of that group, allowing it to work out the members to share - with, and to be able to wrap the FK for encrypted shares. This is by - design, as to mitigate spam shares and other abusive behaviour. - -- **OCM messages are still just OCM messages.** MLS group lifecycle - messages and FK distribution flow through the Group Owner Server - acting as DS. OCM share notifications flow directly from the sending - server to each member server, derived from the sending server's local - view of group membership from the MLS ratchet tree. No proxying of OCM - messages through the Group Owner Server is required. - -- **Sending servers derive membership from the ratchet tree.** Since - sending servers must have group members, they process all `MLS_COMMIT` - messages and hold the current ratchet tree. The OCM Address in each - leaf node's credential identifies the corresponding member server. The - sending server uses this to determine which member servers to contact - directly for share notifications and FK distribution. - -- **Push-based FK distribution via the Group Owner Server.** Wrapped - file keys are distributed via `MLS_APPLICATION` through the Group - Owner Server, which broadcasts them to all current member servers. - Member servers always hold the current wrapped FK for each resource - and use their current Group Key to unwrap it at access time. - -- **Minimal protocol surface.** The `shareType: "federation"` value - already defined in the OCM spec is used without modification. All new - server-to-server messages use the existing `/notifications` endpoint - with new `notificationType` values. Two new fields are added to the - Share Creation Notification: `groupId` (required for all federation - shares) and `encryption` (optional, present only for encrypted - resources). - ---- - -## 4. Terminology - -This document uses terminology from draft-ietf-ocm-open-cloud-mesh-04 -and [RFC9420]. Additional definitions: - -- **Group** — A Receiving Party identified by an OCM Address whose - identifier resolves to a set of members spanning multiple OCM servers, - with group state managed through MLS. In [RFC9420] a group is defined - as: "a logical collection of clients that share a common secret value - at any given time. Its state is represented as a linear sequence of - epochs in which each epoch depends on its predecessor." - -- **MLS Client** — As defined in [RFC9420]: an agent that establishes - shared cryptographic state with other clients, defined by the - cryptographic keys it holds. In this protocol the EFSS fulfils this - role. - -- **Member Server** — An OCM server with one or more users who are - members of a given group, acting as MLS client on their behalf. - -- **Group Owner Server** — The OCM server at which the Group is - registered. Fulfils the MLS Delivery Service role, is the sole - committer for the group, and relays FK distribution messages to member - servers via `MLS_APPLICATION`. - -- **Group Key** — A 32-byte symmetric key derived from the current MLS - epoch secret via the MLS Exporter. Rotates with every epoch - transition. - -- **File Key (FK)** — A random symmetric key used to encrypt a single - shared resource. Wrapped with the current Group Key and distributed to - member servers via MLS Application Messages. Member servers always - store the most current wrapped FK for each resource. - -- **Re-encryption mode** — On member removal, the sending server - generates a new FK, re-encrypts the resource, and distributes the new - wrapped key. Provides strong cryptographic guarantees independent of - trust assumptions. - -- **Key-reuse mode** — On member removal, the existing FK is re-wrapped - under the new Group Key without re-encrypting the resource. - Appropriate only within formally trusted federations and where - re-encryption is impractical. Mode is not a binary choice, instead - sending servers can choose one mode for one epoch, and another mode - for another epoch, depending on policy and other circumstances. - -- **KeyPackage** — As defined in [RFC9420]. A signed object that enables - adding an MLS client to a group asynchronously. KeyPackages MUST be - used only once ([RFC9420] §16.8). - ---- - -## 5. Discovery - -A server signals support for federation shares by including -`"federation"` in the `shareTypes` array for a given resource type in -its OCM discovery document at `/.well-known/ocm`: - -```json -{ - "enabled": true, - "apiVersion": "1.1.0", - "endPoint": "https://cloud.example.org/ocm", - "provider": "Example Cloud", - "resourceTypes": [ - { - "name": "file", - "shareTypes": ["user", "group", "federation"], - "protocols": { "webdav": "/webdav/" } - } - ] -} -``` - -No additional discovery fields are introduced. The notifications -endpoint is derived as `/notifications` per the base OCM -specification. The KeyPackage endpoint is derived as -`/mls-key-packages`. - ---- - -## 6. KeyPackage Distribution - -Each EFSS acting as an MLS client generates and maintains KeyPackages -for its users and exposes them at: - -``` -GET /mls-key-packages?userId={userId} -``` - -Response: - -```json -{ - "userId": "alice@cloud.example.org", - "keyPackages": [ - { - "mediaType": "message/mls", - "encoding": "base64", - "content": "" - } - ] -} -``` - -In native client deployments, the user's device generates KeyPackages -and publishes them to the home server, which exposes them at the same -endpoint without interpreting them. - -Each KeyPackage contains an MLS Credential identifying the user by their -OCM Address, signed by the user's own signing key pair. Users who -require stronger isolation of key material from their server should use -a native client implementation. - -KeyPackages MUST be one-time use ([RFC9420] §16.8). The server MUST -remove a KeyPackage after it has been delivered. Servers SHOULD -pre-generate multiple KeyPackages per user to support concurrent group -additions. - ---- - -## 7. Group Lifecycle - -The group lifecycle is entirely independent of the share lifecycle. -Members are added and removed through MLS group operations conveyed via -the `/notifications` endpoint. None of these operations are triggered by -or coupled to share creation. - -### 7.1. Group Creation - -The Group Owner Server creates an MLS group and initialises leaf nodes -for each of its users who are initial members. No notifications are -required for this step. The group becomes addressable at its OCM Address -immediately upon creation. - -### 7.2. MLS Notification Types - -All MLS group lifecycle messages are sent as OCM Notifications to -`/notifications` using HTTP POST with -`Content-Type: application/json` and HTTP Signatures [RFC9421]. - -Since `MLS_PROPOSAL` is delivered only to the Group Owner Server and -never broadcast to other member servers, those member servers never -observe pending proposals. The Group Owner Server, as sole committer, -satisfies [RFC9420] §12.4 by processing the Commit before sending any -application data. - -#### 7.2.1. `MLS_WELCOME` - -Sent by the Group Owner Server to a member server when one of its users -is added to the group. Delivers the MLS Welcome message for the added -user, enabling the receiving MLS client to initialise its state and -derive the current Group Key. A single `MLS_COMMIT` covering multiple -Add proposals will result in one `MLS_WELCOME` notification per added -user. - -```json -{ - "notificationType": "MLS_WELCOME", - "groupId": "", - "userId": "bob@othercloud.example.org", - "content": "" -} -``` - -#### 7.2.2. `MLS_PROPOSAL` - -Sent by a member server to the Group Owner Server to propose a -membership change (Add or Remove) on behalf of one of its users. This -notification is NOT broadcast to other member servers; it is delivered -only to the Group Owner Server, which acts as sole committer. - -```json -{ - "notificationType": "MLS_PROPOSAL", - "groupId": "", - "content": "" -} -``` - -#### 7.2.3. `MLS_COMMIT` - -Sent by the Group Owner Server to all member servers to advance the -group epoch. The `sequenceNumber` is assigned by the Group Owner Server -and MUST be monotonically increasing. Member servers MUST process -commits in sequence-number order and MUST apply the new epoch secret -before sending any application data, per [RFC9420] §15.2. - -```json -{ - "notificationType": "MLS_COMMIT", - "groupId": "", - "sequenceNumber": 42, - "content": "" -} -``` - -The `MLS_COMMIT` serves as the signal to all sending servers that group -composition has changed, enabling them to trigger re-encryption or -re-wrapping according to their policy. Any Commit covering a Remove -proposal MUST include an UpdatePath ([RFC9420] §12.4). - -#### 7.2.4. `MLS_APPLICATION` - -Used in two directions. Sending servers send this to the Group Owner -Server to deliver updated wrapped file keys after processing an epoch -transition. The Group Owner Server then broadcasts it to all current -member servers. The `content` is a `PrivateMessage` carrying application -data encrypted in the current epoch ([RFC9420] §15). - -```json -{ - "notificationType": "MLS_APPLICATION", - "groupId": "", - "content": "" -} -``` - -### 7.3. Leaf Key Updates - -To maintain post-compromise security ([RFC9420] §16.6), member servers -SHOULD periodically send `MLS_PROPOSAL` (Update) to the Group Owner -Server to rotate their users' leaf keys. The Group Owner Server MUST -commit received Update proposals promptly. Members that do not update -SHOULD eventually be removed from the group per [RFC9420] §3.2. - ---- - -## 8. Encryption Model - -### 8.1. Group Key Derivation - -After processing any MLS Welcome or Commit, the MLS client MUST apply -the new epoch secret before encrypting any application data, then -derives the current 32-byte Group Key: - -``` -group_key = MLS-Exporter("ocm-group-key", group_id_bytes, 32) -``` - -The MLS Exporter ([RFC9420] §8.5) produces application-specific key -material from the epoch secret without exposing the epoch secret itself. -The label `"ocm-group-key"` scopes the output to this application. The -`group_id_bytes` context further binds the output to this specific -group. The Group Key therefore changes with every epoch transition and -cannot be derived by any party that did not participate in that epoch. - -Per [RFC9420] §8.5, the Group Key SHOULD be refreshed after each -processed Commit. Security-sensitive values derived from the epoch -secret MUST be deleted as soon as they are consumed, per [RFC9420] §9.2. - -All MLS clients in the group independently derive the same Group Key for -a given epoch. - -### 8.2. File Key Wrapping - -When sharing an encrypted resource with a group, the sending MLS client -acts on behalf of a user who is a member of that group: - -1. Generates a random per-file key (FK) of appropriate length for the - chosen AEAD algorithm. -2. Encrypts the resource using an AEAD algorithm from the set supported - by the MLS cipher suite negotiated for the group, as defined in - [RFC9180]. Implementations supporting native client decryption of - large files SHOULD use a chunked AEAD construction to enable - streaming decryption. -3. Derives the current Group Key from the user's local MLS state. -4. Wraps FK using the same AEAD algorithm: - ``` - wrapped_file_key = AEAD-Encrypt( - key = group_key, - nonce = random_nonce, - plaintext = FK, - aad = group_id || resource_id_utf8 - ) - ``` -5. Sends an `MLS_APPLICATION` notification to the Group Owner Server - carrying the wrapped FK keyed by `(providerId, groupId)`, for - broadcast to all current member servers. - -### 8.3. Key Distribution via MLS Application Messages - -Wrapped file keys are distributed to member servers via MLS Application -Messages, `PrivateMessage` objects carrying application data ([RFC9420] -§15). A sending server MUST process the `MLS_COMMIT` and derive the new -Group Key before sending an `MLS_APPLICATION` with updated wrapped keys, -per [RFC9420] §15.2. - -The `PrivateMessage` application data is a JSON object carrying the -current wrapped FK for each `(providerId, groupId)` pair: - -```json -{ - "keys": [ - { - "providerId": "7c084226-d9a1-11e6-bf26-cec0c932ce01", - "groupId": "research-group@cloud.example.org", - "wrappedKey": "" - } - ] -} -``` - -The `PrivateMessage` is encrypted using the current epoch's keys, so -only current group members can decrypt it. A just-removed member cannot -decrypt the Application Message even if they receive the notification, -as they do not hold the new epoch's key material. - -Member servers store the received wrapped FKs locally, always replacing -any previous wrapped FK for the same `(providerId, groupId)` pair with -the latest received. At access time, the member server uses its current -Group Key, derived from its current MLS state for the identified group, -to unwrap the FK. - -### 8.4. Resource Access - -To access a resource: - -1. The MLS client identifies the relevant group from the `groupId` in - the share notification and looks up the locally stored - `wrapped_file_key` for the `(providerId, groupId)` pair. -2. The MLS client derives the current Group Key from its local MLS state - for that group and unwraps FK. -3. The MLS client decrypts the resource using FK. - -In web-client deployments, decryption happens server-side and the -plaintext is served to the user through whatever access protocol is in -use (WebDAV, SFTP, webapp, etc.). In native client deployments, -decryption happens on the user's device and the client interacts -directly with the sending server, which serves only ciphertext. - -### 8.5. Resource Modification by Member Servers - -A common operation is for a user on a member server to open a shared -encrypted resource, modify it, and save it back. The cryptographic flow -is as follows: - -1. The member server fetches the encrypted resource from the sending - server via whatever access protocol is in use. -2. The member server identifies the relevant group from the `groupId` in - the share notification, looks up the locally stored - `wrapped_file_key` for the `(providerId, groupId)` pair, derives the - current Group Key from its local MLS state for that group, and - unwraps FK. -3. The member server decrypts the resource using FK and presents the - plaintext to the user. -4. The user modifies the resource. -5. The member server re-encrypts the modified resource using the same FK - but a fresh random nonce. The nonce MUST NOT be reused with the same - key, as required by AEAD security. -6. The member server uploads the re-encrypted resource to the sending - server. - -The FK is reused across modifications of the same resource because it is -bound to the `group_id` and `resource_id` in the AEAD associated data, -making it specific to that resource. No new `MLS_APPLICATION` message is -needed, as the wrapped FK in all member servers' local stores remains -valid for the updated ciphertext. - -The `resource_id` used in the AEAD associated data MUST be stable across -edits of the same resource. It identifies the resource, not a particular -version of it. In OCM terms this corresponds to the `providerId` of the -share. The `groupId` in the AEAD associated data further scopes the -wrapped FK to a specific group, so the same resource shared with two -different groups produces two distinct wrapped FKs that cannot be -confused. - -FK rotation for a resource is only necessary on member removal in -re-encryption mode (Section 8.6). - -### 8.6. Sharing a Resource with Multiple Groups - -A sending server MAY share the same encrypted resource with more than -one group. The file is encrypted once with a single FK. Each group -receives its own wrapped FK, produced using that group's Group Key and -`group_id`: - -``` -wrapped_file_key_group1 = AEAD-Encrypt(group_key_1, nonce_1, FK, - group_id_1 || resource_id) -wrapped_file_key_group2 = AEAD-Encrypt(group_key_2, nonce_2, FK, - group_id_2 || resource_id) -``` - -A separate Share Creation Notification is sent to each member of the -group. A separate `MLS_APPLICATION` is sent to each Group Owner Server -carrying the respective wrapped FK. Members of each group can only -unwrap the FK using their own group's Group Key and cannot access the -other group's wrapped FK or Group Key. - -The `resource_id` used in the AEAD associated data MUST be a stable -identifier for the underlying file, consistent across all groups it is -shared with. This ensures that the FK unwrapped by members of any group -correctly decrypts the same ciphertext. The `providerId` values in the -separate share notifications MAY differ, but the `resource_id` in the -AEAD associated data MUST be the same. The sending server is responsible -for maintaining this stable `resource_id`. - -The sending server MUST maintain a mapping from each resource to all -groups it has been shared with. This mapping is required to correctly -handle member removal in re-encryption mode, as described in the -following section. - -### 8.7. FK Rotation (RECOMMENDED) - -A sending server SHOULD rotate the FK for a resource when a member is -removed from any group that has access to it. FK rotation may also be -triggered by other factors, such as periodic key rotation policy, -regulatory requirements, or a suspected compromise of key material. -Applications SHOULD define a policy for the frequency of FK rotation -independent of membership changes. - -When rotating the FK for a resource, the sending server: - -1. Generates a new FK for the resource. -2. Re-encrypts the resource with the new FK. -3. For every group that has access to the resource, wraps the new FK - using that group's current Group Key: - ``` - new_wrapped_file_key_groupN = AEAD-Encrypt(group_key_N, nonce_N, new_FK, - group_id_N || resource_id) - ``` -4. Sends an `MLS_APPLICATION` notification to every group's Group Owner - Server carrying the respective new wrapped FK for broadcast to that - group's member servers. - -Distributing the new wrapped FK to all groups that share the resource is -necessary because all groups share the same ciphertext. If only one -group received the new wrapped FK, members of other groups would hold a -wrapped FK that no longer decrypts the current ciphertext. - -A member removed from one group but still a member of another group that -shares the same resource retains the ability to decrypt that resource -through the second group. This is correct and intended behaviour: access -is determined by current group membership, and the user remains a member -of the second group. The default safe rule is to rotate the FK and -redistribute to all groups on any removal event. A sending server MAY -instead compare the unique set of users with access before and after an -epoch change, and skip FK rotation if that set is unchanged, for example -because the removed user remains a member of every other group that has -access to the same resource. Whether this optimisation is worth the -added complexity depends on the nature of the resource and the frequency -of membership changes. - -Member addition does not require FK rotation. The new member receives -the current Group Key via their Welcome and can unwrap the existing FK -directly. - -### 8.8. Member Removal: Key-reuse Mode (OPTIONAL) - -Where re-encryption is impractical, for example due to frequent changes -of very large files, and where all participating servers belong to a -formal federation with explicit governance and mutual trust, a sending -server MAY instead: - -1. Process the Commit and derive the new Group Key for the affected - group. -2. Re-wrap the existing FK under the new Group Key for the affected - group. -3. Send an `MLS_APPLICATION` notification to that group's Group Owner - Server carrying the re-wrapped FK for broadcast to all remaining - member servers. - -In key-reuse mode, when a resource is shared with multiple groups, it is -sufficient to re-wrap the FK only for the group from which the member -was removed. The wrapped FKs for other groups are unchanged and remain -valid for their respective members. - -In this mode, access-follows-membership relies on trusting member -servers to discard superseded group keys after processing a Remove -Commit. A removed member who is also a member of another group that has -access to the same resource will still be able to decrypt via that -group's wrapped FK, which is the expected behaviour — they remain a -member of that group. This assumption is appropriate within a formal -federation but SHOULD NOT be made in open or ad-hoc sharing contexts. - -The sending server's choice of mode is its own policy decision and is -not signalled in the protocol. - -### 8.9. Member Removal: OCM Notifications - -When a member has been removed from a group, a well-behaved sending -server SHOULD reconcile the OCM state of the share, and send a -SHARE_UNSHARED notification to the /notification endpoint of the -receiving server. - ---- - -## 9. Share Creation - -### 9.1. Share Creation Notification - -The sending server sends individual OCM Share Creation Notifications -directly to each current member server, using the OCM Address from each -leaf node's credential in the ratchet tree to identify the recipients. -This is standard OCM server-to-server communication, with `shareWith` -set to the receiving user's OCM Address and `shareType` set to -`"federation"` to indicate the share originates from a federated group -context. - -A `groupId` field carrying the OCM Address of the group MUST be included -in all federation share notifications. This allows the receiving server -to distinguish between shares of the same resource arriving via -different groups — a user may be a member of two groups that both have -access to the same resource from the same sending server. It also allows -the receiving server to correctly key its local wrapped FK store by -`(providerId, groupId)` rather than `providerId` alone, ensuring that FK -updates delivered via `MLS_APPLICATION` are applied to the correct -entry. - -Each notification MAY include the optional `encryption` field: - -```json -{ - "shareWith": "bob@othercloud.example.org", - "shareType": "federation", - "groupId": "research-group@cloud.example.org", - "resourceType": "file", - "sender": "alice@cloud.example.org", - "owner": "alice@cloud.example.org", - "providerId": "7c084226-d9a1-11e6-bf26-cec0c932ce01", - "name": "experiment-data.tar", - "encryption": { - "scheme": "ocm-mls-1" - } -} -``` - -The `encryption` field is OPTIONAL. If absent, the resource is -unencrypted and the share follows the standard OCM flow without -modification. If present, `scheme` identifies the encryption scheme. -This proposal defines `"ocm-mls-1"`. The field signals that the FK is -distributed via the `MLS_APPLICATION` mechanism keyed by -`(providerId, groupId)`. No epoch information is carried in the share -notification. Member servers always hold the current wrapped FK for each -`(providerId, groupId)` pair and use their current Group Key to unwrap -it at access time. - -The Group Owner Server is not involved in the delivery of OCM share -notifications. All other OCM notifications relating to a share, such as -share updates and share deletions, are likewise sent directly from the -sending server to each member server and MUST include the `groupId` -field. - ---- - -## 10. Trust and Authentication - -The Authentication Service role ([RFC9420] §3) is fulfilled by each -user's home OCM server. A KeyPackage is considered authenticated if it -is retrievable from the canonical `/mls-key-packages` endpoint -of the server named in the user's OCM Address, and the credential -signature verifies against the user's published public key. - -Users who require protection of their key material from their own server -should choose a native client implementation where cryptographic -operations occur on the user's device. - ---- - -## 11. Security Considerations - -**Trust model.** In web-client deployments, the EFSS holds the Group Key -and can decrypt any resource shared with the group on behalf of its -users. This is consistent with the standard EFSS trust model, where -users trust their server with their data, and with OCM's existing -approach of abstracting security to the server level. Native client -deployments provide stronger isolation, as the server does not hold key -material. Implementations SHOULD move toward native client deployments -over time. - -**FK rotation vs key-reuse.** FK rotation provides cryptographic access -revocation on member removal, independent of trust assumptions, and -SHOULD also be performed periodically or when key compromise is -suspected. Key-reuse mode relies on trusting member servers to discard -superseded group keys after processing a Remove Commit. Key-reuse mode -SHOULD only be used within formal federations with governance agreements -that enforce this behaviour. - -**Key distribution via Application Messages.** Wrapped FKs are -distributed in MLS `PrivateMessage` objects encrypted in the current -epoch. A removed member cannot decrypt these messages as they do not -hold the new epoch's key material. Member servers always replace their -locally stored wrapped FK with the latest received, so the current Group -Key is always sufficient for unwrapping. - -**Commit ordering.** The Group Owner Server is the sole committer, -eliminating the possibility of conflicting Commits for the same epoch. A -compromised or unavailable Group Owner Server can stall epoch -transitions but cannot decrypt resource content from the key store -alone. - -**Application message ordering.** Per [RFC9420] §15.2, sending servers -MUST apply a new epoch secret before encrypting any application data. -`MLS_APPLICATION` messages carrying re-wrapped keys MUST be sent only -after the sending server has processed the corresponding `MLS_COMMIT`. - -**Post-compromise security.** Member servers SHOULD periodically rotate -their users' leaf keys via Update proposals to maintain post-compromise -security ([RFC9420] §16.6). Members that do not update SHOULD eventually -be removed from the group. - -**Key material deletion.** Security-sensitive values MUST be deleted as -soon as they are consumed, per [RFC9420] §9.2. In particular, the -exporter_secret used to derive the Group Key must not be retained after -the Group Key has been derived. - -**KeyPackage reuse.** As per [RFC9420] §16.8, KeyPackages MUST be -one-time use. Servers MUST remove a KeyPackage that has been consumed. - -**User enumeration.** A server MUST only reply to HTTPS GET requests -signed using http-sig [RFC9421] and SHOULD implement rate limiting and -other access control methods on the /mls-key-packages endpoint to avoid -user enumeration. - ---- - -## 12. IANA Considerations - -The MLS Exporter label `"ocm-group-key"` used in Section 8.1 SHOULD be -registered in the MLS Exporter Labels registry defined in [RFC9420] -§17.8 to avoid collisions with other applications using the MLS -Exporter. - ---- - -## 13. Open Issues - -- **Streaming decryption.** A chunked AEAD construction enabling - streaming decryption of large files should be specified for native - client implementations. The specific construction and its interaction - with the FK wrapping model needs to be defined. - -- **Application Message batching.** The frequency and batching of - `MLS_APPLICATION` messages carrying wrapped FKs needs to be defined, - particularly when many shares exist and epoch transitions are - frequent. - -- **Group Owner Server failover.** A mechanism for designating a - successor Group Owner Server, and for publishing a current GroupInfo - object to enable External Joins ([RFC9420] §3.3) for member servers - that have lost state, needs to be specified. - ---- - -## 14. References - -- draft-ietf-ocm-open-cloud-mesh-04, Lo Presti et al., March 2026 -- [RFC9420] Barnes et al., "The Messaging Layer Security (MLS) - Protocol", July 2023 -- [RFC9421] Backman et al., "HTTP Message Signatures" -- [RFC9180] Bhargavan et al., "Hybrid Public Key Encryption" -- [RFC7517] Jones, "JSON Web Key (JWK)" -- [RFC4918] Dusseault, "HTTP Extensions for Web Distributed Authoring - and Versioning (WebDAV)" From 8c5d19d3da74e24174271a5975e619ad4c0208aa Mon Sep 17 00:00:00 2001 From: Micke Nordin Date: Sat, 13 Jun 2026 12:54:30 +0200 Subject: [PATCH 2/4] Update IETF-OCM-MLS.md Co-authored-by: Giuseppe Lo Presti --- IETF-OCM-MLS.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/IETF-OCM-MLS.md b/IETF-OCM-MLS.md index 1d12777..4fb02b4 100644 --- a/IETF-OCM-MLS.md +++ b/IETF-OCM-MLS.md @@ -1863,8 +1863,7 @@ can be useful in this context. [OCM] Lo Presti, G., de Jong, M.B., Baghbani, M. and Nordin, M. "[Open Cloud Mesh](https://datatracker.ietf.org/doc/draft-ietf-ocm-open-cloud-mesh/)", -Work in Progress, Internet-Draft, draft-ietf-ocm-open-cloud-mesh-04, -March 2026. +Work in Progress, Internet-Draft. [RFC2119] Bradner, S. "[Key words for use in RFCs to Indicate Requirement Levels](https://datatracker.ietf.org/doc/html/rfc2119)", From 6c814d108960044ed343b113088e4a4f3c2796e3 Mon Sep 17 00:00:00 2001 From: Micke Nordin Date: Sat, 13 Jun 2026 13:02:32 +0200 Subject: [PATCH 3/4] Fix line length --- IETF-OCM-MLS.md | 6 +- IETF-OCM-MLS.xml | 1261 +++++++++++++++++++++++----------------------- 2 files changed, 633 insertions(+), 634 deletions(-) diff --git a/IETF-OCM-MLS.md b/IETF-OCM-MLS.md index 4fb02b4..ff6b4aa 100644 --- a/IETF-OCM-MLS.md +++ b/IETF-OCM-MLS.md @@ -54,9 +54,9 @@ individual users across federated servers and with groups on a single server. The specification also defines a `shareType` of `"federation"` but does not further specify its semantics. This document gives `"federation"` a concrete definition: a federated group identified by an -OCM Address such as `research-group@receiver.example.org` whose membership -spans multiple OCM servers, with group state managed through the MLS -[RFC9420] epoch mechanism. +OCM Address such as `research-group@receiver.example.org` whose +membership spans multiple OCM servers, with group state managed through +the MLS [RFC9420] epoch mechanism. In many Enterprise File Sync and Share (EFSS) systems, which constitute the vast majority of all OCM Servers, there is a tight coupling between diff --git a/IETF-OCM-MLS.xml b/IETF-OCM-MLS.xml index 9a420b6..9e6e9e7 100644 --- a/IETF-OCM-MLS.xml +++ b/IETF-OCM-MLS.xml @@ -38,7 +38,7 @@ - + Applications and Real-Time @@ -81,9 +81,9 @@ individual users across federated servers and with groups on a single server. The specification also defines a shareType of "federation" but does not further specify its semantics. This document gives "federation" a concrete definition: a federated group identified by an -OCM Address such as research-group@receiver.example.org whose membership -spans multiple OCM servers, with group state managed through the MLS -[RFC9420] epoch mechanism. +OCM Address such as research-group@receiver.example.org whose +membership spans multiple OCM servers, with group state managed through +the MLS [RFC9420] epoch mechanism. In many Enterprise File Sync and Share (EFSS) systems, which constitute the vast majority of all OCM Servers, there is a tight coupling between @@ -1944,8 +1944,7 @@ can be useful in this context. [OCM] Lo Presti, G., de Jong, M.B., Baghbani, M. and Nordin, M. "Open Cloud Mesh", -Work in Progress, Internet-Draft, draft-ietf-ocm-open-cloud-mesh-04, -March 2026. +Work in Progress, Internet-Draft. [RFC2119] Bradner, S. "Key words for use in RFCs to Indicate Requirement Levels", @@ -2030,634 +2029,634 @@ gqDn4x6K46GcgU29Wq1JaXzEGm/brnZLPDQM5fwfNOxfClqgLQ2MF0ukXN7B i5zeyq+jNV6RoK92NFYZ+khm6K/X+KDREeoxaXl3WPBpWPIdCEpVdFfVsj5X xS2bH09qcYa5vr29qs54/88OTHra5uAssLSsWpWy892WjtRWn3db1DwLUihN Xy/jMYzKAMsf8uex+LS0A1VfyRBq0VPl6EjUK3oGDZr+sCDRbgLv/slqRatF -L90tL1kKzuhfVbldXspN9tcttATNu/qt3FytodPOipvLtquKdAZCd1XS/bXZ -rfuavgS50jWduQWVs6ZStSKRoj9eXIpSeXEa/kEKg/XFL0V11dJwNtXykjRv -tyH5eN7wz26Lp3wXXm1rev0zOg/F6W2zxLad8poX954+OyUd1N12fbXhd5NE -X/ICke7vd30V+F3XZdfT0/7ZQmvRDtGpwZBPbci8JxXrpLLo64vLnp6wo3ua -RGtR9TdV1ZA6W65r3hN+d6mTJVVQLUuSMUxJ/kbPP4dokZqo1/2cTt1NtSCZ -pHmcl8uKF513nea0Kbe3+ljaeppxuVphN0Xh16zNaGo0YX036ef2nC4FeQcf -9i6pLP4ij1jUho4bA+M10iXC8OlvgQ/GxyRq1XVN50YWnPaE3xhfpiIur6HR -XUS9EDV2POgh02m68ZCEFgIvD6UZ2TNJJHls2c/YBOLVKS7b9YqPw0mjg5el -3VQVrVx/aUOTxVrVJLSkF+j7z0jjr6qrdXvL54fUAfaV32PLzfMu0mZgy2l/ -dHwzuWcf/xhENOi8rmk9OxNZW5ttu7b9nnd0zmYYMa8+X1Ebmvu2Ju1DymxR -XZbrc94f3nSoo5ltQsHmXnEgzzzgVcaVWDc6RVUDdAe2u/UK+qOh40m38bYW -td+X7ypIy6YqZa91X1kIvOgchud8mvlxantiH1ctX9+kK0ksySDq6eRHOU+G -anH6/aufXjwJV7Ro7XaT7xndC6qbOhl5NXhQ6wcWVOBmBf2G5YKG0dhXxoeq -7mx8JGd0RTQX1TbUXbuWcdGqZut9vm037klyqKpaBLC0Y0p2H9SPjm9Dpuxa -pouD8JRMIBET0noiIKL4oDlGWvayhHTU9PENjlCxrsrz0LQsFVXDx4TEYnQl -0Z7R/tGB1yt7W23aa2w+yW/VrHDTHYa3Io6qqfji5/u7KEcSSasxIWp6JOrB -3o+PxYefCBxNDJne0OXr704Er/3wrTBhwvvErPhAMcsfpNeO08O0TjAheT7b -imxPGCi8ZBsYtNjst3Iltbs+P3Mz/JxfRqK3JGtOtOCi4kfqAO1exerYS2ld -d7D3+7Zd6S5n38e502/TRHir2Ipa8tXEZnPjdnWWbyv5f8PdfZvmKxvTtCOD -lRyaYko7O1HLHxsgdiLevNH8iXtc9RsZuPigum7X11UuszglzW0w24zX8Zom -x9pcjhVW4KZk/cwuC+7xMtpwmaUbWOBJSZG5xX+WbSIFU1VY23dNeyO3iNiG -fpSrisz+NTs5QUxZfp6uGK/wk2rNds4tjhapJNHpLAJmvlfkipP2uWo7svd4 -Z0l54Tfycn7vZbupojGphkW52pC/KecG0YTi1U0Dt4m/Fsrtou5ZgXTF43az -qXu9D2Dd/ECn6d6zH+47H4IkwOQV0tXxjWBXnmg8+hPuHhsI7gNorGiT/XNH -W7au36mpxmtOKqqPJi3L0nfekeIlZGvMXms2HJuUdJpuzZgLvJYiKuv6vFre +L90tL1kKzuhfVbldXspN9tcttATNu/qt3FytodPOipvLlm6BdAZo/CXdX5vd +uq/pS5ArXdOZW1A5aypVKxIp+uPFZYBSIbH8BykM1he/FNVVS8PZVMtL0rzd +huTjecM/uy2e8l14ta27qnhG56E4vW2W2LZTXvPi3tNnp6SDutuurzb8bpLo +S14g0v39rq/wruuy6+lp/2yhtWiH6NRgyKc2ZN6TinVSWfT1xWVPT9jRPU2i +taj6m6pqSJ0t1zXvCb+71MmSKqiWJckY9KT8jZ5/DtEiNVGv+zmduptqQTJJ +8zgvlxUvOu86zWlTbm/1sbT1NONytcJuisKvWZvR1GjC+m7Sz+05XQryDj7s +XVJZ/EUesagNHTcGxmukS4Th098CH4yPSdSq65rOjSw47Qm/Mb5MRVxeQ6O7 +iHohaux40EOm03TjIQktBF4eSjOyZ5JI8tiyn7EJxKtTXLbrFR+Hk0YHL0u7 +qSpauf7ShiaLtapJaEkv0PefkcZfVVfr9pbPD6kD7Cu/x5ab512kzcCW0/7o ++GZyzz7+MYho0Hld03p2hYmsrs22Xdt+zzs6ZzOMmFefr6gNzX1bk/YhZbao +Lsv1Oe8PbzrU0cw2oWBzrziQZx7wKuNKrBudoqoBugPb3XoF/dHQ8aTbeFuL +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 -HZk1MRJxN13CkBdhOC2+tMGUQB75BP9B4fkPPqQAVjhVEjmHsDOUWlfL/uYx -AyeGDAk4kMKPILGflr20mVLMcHAd1zcwswrrODcekAlsCVCwdNMEPQRtTFl2 -LtgFAT3DSH+tSTel7G5JVzGzC0ptmRTRAsW65c3a8PGFHTBxJx4dunPB0a+K -C/Zy+YOR7Erg4pwlxeSJE6NDEQMttHRIi7hY5ceZnp+6qY/uT5AuIarulS82 -V69T7OKGoyk0i1sOdkSDYzR+RrP8evTg61+ffP/D0x//3wdffHH0za8nT0/p -T989/vHX0+9PHnzx5a9PV/hg0pL46vDovtcxmjn//SM9m2OqmFgj/mE8MS5Z -OigbjRorfneCNEZvyEYy8jAn6LqEHWq0jTIOQ/vK8QelbhnH7Ug9guSSYfoK -0rq5HQVkTxQf97GvAjbFcl5tmVuPZbsbgn0jGNPswA8EZLqcB881GQSKzLLc -HBshV7z4QgvI39bc1uBcBGcrHh3F84wLkVTHUkrsuawJi4mEIq/6iCLJKMY0 -6YxqL5tkt1toch08A7dZLTisS5o+mWWSkc4htvuz3/IqqUJISeMITgxuCXMY -43HCQbK+z5wGXG2MABJQrcaiBBqpAb6J40Frdz8xA7rwfqklb/zY2RQe3YD+ -Ep2OWAU3E0+BE5DBMI9Iy1VItXcy1uJMZPxsWNjMEmApOnHSgLrk+KW+RUhr -S6FL5CKMy4psW5NOw3lyqtIQbXyRyGD1/o34cBIgevS3jl1zXzG2lNc+Zl/7 -t17335LwCuDJxoNE1Pr2kdq0IDwC2GsIa4Ulx6dgm2zvaSaj1xmwhe7M1RoV -GUuohgvzgM9bS2nKEQO9xkmTwXKYpor2RHA58a8eliPipeyNMtRA126b3iO/ -MuNoFneA3G16bQ2OAEErZZJNTzkHJ9cAsLvUE8hX9a7Bti3aXsDWtg+cE/4n -HW54xiEjPeGx3ZjO0aKSD6HNCiPaLL3d+Z237CspjZbQknzIeskyddPrFO4x -+9dcU/z3x2iDHPsEzR0FjRU9vYcdYiUkUjYO53llqC01Q2RtC/9mB8YaAKNQ -CJ+WuZgnQcEWyETbC8E7Cf2TSJcQV7K14wIIisSeKHyzOExewmZl3jC3oI3y -NCTpCxkdK4s57lctppwjFbG9Nnpv7CwvbuCUB/bTdhPG5GjpTXKH5GcCfrtj -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 -p/xVstfnc3QID/8fQsCKqPZxAQA= +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 +5LrfjMdxAQA= --> From 5aecbc8bbf7b14bc6c3413887ddfbe31c2bc87c5 Mon Sep 17 00:00:00 2001 From: Giuseppe Lo Presti Date: Sat, 13 Jun 2026 13:17:12 +0200 Subject: [PATCH 4/4] Delete IETF-OCM-MLS.xml, will be autogenerated --- IETF-OCM-MLS.xml | 2664 ---------------------------------------------- 1 file changed, 2664 deletions(-) delete mode 100644 IETF-OCM-MLS.xml diff --git a/IETF-OCM-MLS.xml b/IETF-OCM-MLS.xml deleted file mode 100644 index 9e6e9e7..0000000 --- a/IETF-OCM-MLS.xml +++ /dev/null @@ -1,2664 +0,0 @@ - - - - - - - - - - -]> - - - - - Federated Groups in Open Cloud Mesh using Messaging Layer Security - - - SUNET -
- kano@sunet.se - https://code.smolnet.org/micke -
-
- - CERN -
- giuseppe.lopresti@cern.ch - https://cern.ch/lopresti -
-
- - Ponder Source -
- mahdi@pondersource.org - https://pondersource.com -
-
- - - - Applications and Real-Time - - Internet-Draft - - - - - - -This document defines an extension to the Open Cloud Mesh (OCM) protocol -to support federated groups as Receiving Parties of shares. This is -achieved using the Messaging Layer Security (MLS) protocol (RFC 9420) as -a group management layer. MLS is used for establishing and rotating a -shared group key across federated group members, as well as for -maintaining group state. This gives not only a way of federating group -membership, but also a standardized way of distributing encryption keys -in a cryptographically secure way, so that files shared with a group can -optionally be encrypted and decrypted. MLS usage in OCM acts as a -vehicle for group management that gives users optional encryption -capabilities for resources shared with federated groups. - - - - - - - -
- - - - - - -
Introduction - -Open Cloud Mesh [OCM] currently supports sharing resources with -individual users across federated servers and with groups on a single -server. The specification also defines a shareType of "federation" -but does not further specify its semantics. This document gives -"federation" a concrete definition: a federated group identified by an -OCM Address such as research-group@receiver.example.org whose -membership spans multiple OCM servers, with group state managed through -the MLS [RFC9420] epoch mechanism. - -In many Enterprise File Sync and Share (EFSS) systems, which constitute -the vast majority of all OCM Servers, there is a tight coupling between -a client and a server, because the server offers a built-in web -interface as its primary client. In addition to this, a sync client is -often offered as a way of syncing files between the EFSS system and the -user's devices. - -In MLS, a client is defined as an agent that establishes shared -cryptographic state with other clients, defined by the cryptographic -keys it holds. An EFSS server meets this definition directly. For -deployments where the primary user interface is a web client, the OCM -Server fulfils the MLS client role server-side, holding key material on -behalf of its users, and the word "client" as used in this document -should not necessarily be taken to mean the user's file sync client. -Implementations that do provide a native client application SHOULD -perform cryptographic operations in the native client on the user's -devices, rather than on the server, because this provides stronger -isolation of key material from the server. In either case the same MLS -client model applies. - -Each user who is a member of a federated group has their own MLS leaf -node, enabling individual users to be added and removed independently. -The OCM Server can act as the MLS client on behalf of its users. For -implementations where the primary interface is a web client, the OCM -Server holds and uses key material server-side. Implementations with a -native client application SHOULD perform cryptographic operations in the -native client, with the server acting as a relay for MLS messages. - -Throughout this document, actions described as being performed by an OCM -server are understood to be performed by that server in its capacity as -an MLS client, on behalf of one of its users. The server holds no group -membership or cryptographic state independent of its users. - -The group and its membership exist and evolve independently of any -sharing activity. A user that wants to share a resource with a group -can do so without the need to know the current membership details of -that group. The MLS Delivery Service role is distributed: proposals are -delivered to the home servers of all admins, the Group Owner Server -arbitrates Commits, and File Key (FK) distribution messages are sent -directly from sending servers to member servers, just like OCM share -notifications. Group membership changes are managed entirely through -MLS group lifecycle operations. - -Every group has one or more admins: users who administer the group. The -user who creates a group is its first admin. Adding a member, or -removing a member other than oneself, requires the approval of an admin, -placing a human in the loop for changes that grant or revoke access. -Any member can remove themselves from a group without admin approval, -though the Commit is still performed by an admin client. All Commits -that advance the MLS epoch are constructed by the MLS clients of admins -and arbitrated by the Group Owner Server. - -The group's OCM Address is a stable label. It is minted under the -domain of the server where the group was created, which guarantees its -uniqueness, but it carries no routing semantics: all protocol messages -are routed using the OCM Addresses of individual members and admins, -never the group's. - -Files shared with a group can optionally be encrypted with a per-file -key (FK), wrapped with the current group key. The group key is derived -from the MLS epoch secret and rotates with every epoch transition. On -every epoch transition the sending server re-wraps the FK under the new -group key and redistributes it, so that the current group key is always -sufficient to unwrap the current FK. When a member is added to a group, -their MLS client receives the new group key and the re-wrapped FKs, and -can immediately decrypt all resources shared with the group. - -When a member is removed from the group, sending servers MAY -additionally generate a new FK and re-encrypt affected resources, -depending on their policy and the nature of the shared data. - -
-
Terminology - -The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", -"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and -"OPTIONAL" in this document are to be interpreted as described in BCP 14 -[RFC2119] [RFC8174] when, and only when, they appear in all capitals, as -shown here. - -This document uses terminology from [OCM] and [RFC9420]. Additional -definitions: - - - Group - A Receiving Party identified by an OCM Address whose -identifier resolves to a set of members spanning multiple OCM servers, -with group state managed through MLS. The Group's OCM Address is a -stable label assigned at creation and MUST NOT change for the lifetime -of the Group; it carries no routing semantics. In [RFC9420] a group is -defined as: "a logical collection of clients that share a common secret -value at any given time. Its state is represented as a linear sequence -of epochs in which each epoch depends on its predecessor." - MLS Client - As defined in [RFC9420]: an agent that establishes -shared cryptographic state with other clients, defined by the -cryptographic keys it holds. In this protocol an OCM Server can fulfill -this role. - Member Server - An OCM server with one or more users who are -members of a given Group, acting as MLS client on their behalf. - Group Owner Server - The server currently arbitrating Commits for -the Group: the home server of the first Admin in the admin set. -Initially this is the server at which the Group was created. - Admin - A user who administers the Group membership. The user who -creates a Group is its first Admin. Only the MLS clients of Admins -(admin clients) construct Commits. The admin set is part of the group -state (). - Admin Server - The home server of an Admin. Admin Servers -collectively queue proposals for the Group. - Group Key - A symmetric key derived from the current MLS epoch -secret via the MLS Exporter, with the key length of the AEAD algorithm -of the group's cipher suite. Rotates with every epoch transition. - File Key (FK) - A random symmetric key used to encrypt a single -shared resource. Wrapped with the current Group Key and distributed to -Member Servers via MLS Application Messages. Re-wrapped under the new -Group Key on every epoch transition (). Member Servers -always store the most current wrapped FK for each resource. - Re-encryption mode - On member removal, the sending server -generates a new FK, re-encrypts the resource, and distributes the new -wrapped key. Provides strong cryptographic guarantees independent of -trust assumptions. - Key-reuse mode - On member removal, the existing FK is kept and -only the standard re-wrap on epoch change () is performed, -without re-encrypting the resource. Appropriate only within formally -trusted federations and where re-encryption is impractical. Mode is not -a binary choice; sending servers can choose one mode for one epoch and -another mode for another epoch, depending on policy and other -circumstances. - KeyPackage - As defined in [RFC9420]. A signed object that -enables adding an MLS client to a group asynchronously. KeyPackages -MUST be used only once, except for a designated last resort KeyPackage -([RFC9420] Section 16.8). - - -
-
MLS Roles in OCM - -MLS is designed to operate with two supporting services: an -Authentication Service (AS) and a Delivery Service (DS) ([RFC9420] -Section 3; see also the MLS architecture [RFC9750]). This section -describes how those roles are fulfilled by OCM. - -
Authentication Service - -The AS role is fulfilled by each user's home OCM server. Credentials in -this protocol are MLS basic credentials ([RFC9420] Section 5.3) whose -identity field is the UTF-8 encoded OCM Address of the user. Each user -has their own distinct signing key pair so that individual users can be -identified and addressed independently within the MLS group, for example -to add or remove a specific user. In web-client deployments the key -pair is generated and held by the OCM Server on the user's behalf. In -native client deployments the key pair is held on the user's device and -the server's role is limited to publishing the user's KeyPackages. - -A basic credential carries no verifiable binding of its own; the binding -between a user's OCM Address and their signature key is attested by -authenticated delivery from the user's home server. A KeyPackage -fetched over TLS from the <endPoint>/mls-key-packages endpoint of the -server named in the credential's OCM Address, with the response signed -using HTTP Signatures [RFC9421] verifying against that server's JWKS -endpoint at /.well-known/jwks.json [RFC7517], is considered validated -with the AS. The full validation procedure, including how credentials -introduced later in the life of a group are validated, is specified in -. - -
-
Delivery Service - -The DS role is distributed across the servers of the group rather than -centralised on a single server. MLS places no constraints on how the DS -is arranged, as long as messages are delivered ([RFC9420] Section 3). - - - Proposal delivery: MLS_PROPOSAL notifications are sent to the home -server of every admin (), derived from the admin set and the -OCM Addresses in the ratchet tree's leaf credentials. Admin Servers -queue proposals, deduplicated by ProposalRef ([RFC9420] Section 5.2), -and make them available to their admin clients. - Commit arbitration: the Group Owner Server, the home server of the -first admin in the admin set, accepts exactly one Commit per epoch from -an admin client and broadcasts it to all Member Servers. - FK distribution: MLS_APPLICATION messages carrying wrapped file keys -are sent directly from the sending server to all current Member Servers, -exactly like OCM share notifications; credential updates are sent to a -single Member Server (). - - -All MLS messages are delivered to the <endPoint>/notifications -endpoint of each recipient server, authenticated with HTTP Signatures -[RFC9421]. - -Commits are constructed and signed by admin clients, but only the Commit -accepted by the Group Owner Server takes effect; competing Commits for -the same epoch are discarded by their senders. Designating a single -arbiter of Commits eliminates conflicting Commits for the same epoch -during normal operation, satisfying the sequencing requirement of -[RFC9420] Section 14; conflicting Commits can arise only during failover -and are then resolved deterministically (). Per [RFC9420] -Section 14, generating a Commit does not modify the sender's state, so -an admin client whose Commit is rejected simply discards it and -constructs a new Commit on the new epoch. - -OCM share notifications are sent directly from the sending server to -each Member Server. Since sending servers must be group members, they -hold the current MLS ratchet tree after processing each MLS_COMMIT, -and can derive the current membership - specifically the OCM Address in -each leaf node's credential - to determine which Member Servers to -contact. No proxying through the Group Owner Server is required for -OCM-level communication. - -MLS is designed to protect confidentiality and integrity even against a -misbehaving DS. No single server in this design carries the full DS -role, and no server holds key material by virtue of its DS duties; the -MLS security properties with respect to message confidentiality hold -regardless. - -
-
-
How MLS is implemented over OCM - - - MLS for group key management only. MLS establishes and rotates a -shared group key. The only MLS application messages used in this -protocol carry wrapped file keys () and per-server -transport credential updates (). - At least one MLS leaf per user. Each user who is a member of a -federated group has at least one MLS leaf node, enabling individual -users to be added and removed independently. In web-client deployments -the OCM Server manages a single leaf node per user on their behalf. In -native client deployments each user may have a leaf node per device. - The OCM Server is a MLS client. An OCM Server meets the MLS -definition of a client. For web-client deployments this means key -material is held server-side. For native client deployments -cryptographic operations SHOULD be performed in the native client. - Admins approve membership changes. Every group has one or more -admins (). Commits are constructed by admin clients and -arbitrated by the Group Owner Server. Add proposals and Remove -proposals targeting another user require admin approval; any member may -remove themselves, and Update proposals are committed automatically. - Encryption is optional. MLS group management is useful -independently of whether encryption is used. A federation share MAY be -unencrypted, in which case the encryption field is omitted from the -Share Creation Notification and the MLS layer provides only group -membership management. - FK re-wrap on every epoch change. After processing an MLS_COMMIT -for a group, a sending server MUST re-wrap the current FK of every -resource it shares with that group under the new Group Key and -distribute it via MLS_APPLICATION (). This maintains the -invariant that the current Group Key is always sufficient to unwrap the -current wrapped FK. - FK rotation on member removal. On member removal, a sending server -SHOULD additionally rotate the FK for affected resources: generate a new -FK, re-encrypt the resource, and distribute the new wrapped FK to all -groups that share those resources. FK rotation may also be triggered by -other factors such as periodic key rotation policy or suspected key -compromise. Member addition does not require FK rotation; the standard -re-wrap is sufficient. - Key-reuse mode as an alternative. Where re-encryption on removal -is impractical and where participating servers are mutually trusted -within a formal federation, a sending server MAY instead keep the -existing FK, relying on the standard per-epoch re-wrap alone. - Sending servers must have group members. To share a resource with -a group, the sending server must have at least one user who is a member -of that group, allowing it to work out the members to share with, and to -be able to wrap the FK for encrypted shares. This is by design, to -mitigate spam shares and other abusive behaviour. - OCM messages are still just OCM messages. Proposals flow to the -servers of all admins, Commits are arbitrated by the Group Owner Server, -and FK distribution and OCM share notifications flow directly from the -sending server to each Member Server, derived from the sending server's -local view of group membership from the MLS ratchet tree. No message is -proxied through a single central server. - Sending servers derive membership from the ratchet tree. Since -sending servers must have group members, they process all MLS_COMMIT -messages and hold the current ratchet tree. The OCM Address in each -leaf node's credential identifies the corresponding Member Server. The -sending server uses this to determine which Member Servers to contact -directly for share notifications and FK distribution. - Push-based FK distribution. Wrapped file keys are distributed via -MLS_APPLICATION directly from the sending server to all current Member -Servers, at share creation and after every epoch transition -(). Member Servers always hold the current wrapped FK for -each resource and use their current Group Key to unwrap it at access -time. - Minimal protocol surface. The shareType: "federation" value -already defined in the OCM specification is used without modification, -with shareWith carrying the group's OCM Address. A federation share -is otherwise a standard OCM share, carrying every field REQUIRED by -[OCM] including the protocol object. All new server-to-server -messages use the existing /notifications endpoint with new -notificationType values. A single new field is added to the Share -Creation Notification: encryption (optional, present only for -encrypted resources), carrying all encryption-related parameters, -including the resourceId. - - -
-
Discovery - -A server signals support for federation shares by including -"federation" in the shareTypes array for a given resource type in -its OCM discovery document at /.well-known/ocm: - -
- -No additional discovery fields are introduced. The notifications -endpoint is derived as <endPoint>/notifications per the base OCM -specification. The KeyPackage endpoint is derived as -<endPoint>/mls-key-packages. - -A server that advertises "federation" MUST be able to receive OCM -Notifications, since all MLS lifecycle messages are delivered as -notifications, and SHOULD include "notifications" in its -capabilities array. - -
-
KeyPackage Distribution - -Each OCM Server acting as an MLS client generates and maintains -KeyPackages for its users and exposes them at: - -
/mls-key-packages?userId={userId} -]]>
- -Response: - -
" - } - ] -} -]]>
- -Requests to this endpoint MUST be signed using HTTP Message Signatures -[RFC9421] (). - -In native client deployments, the user's device generates KeyPackages -and publishes them to the home server, which exposes them at the same -endpoint without interpreting them. - -Each KeyPackage contains an MLS Credential identifying the user by their -OCM Address, signed by the user's own signing key pair. Users who -require stronger isolation of key material from their server should use -a native client implementation. - -KeyPackages MUST be one-time use, with the exception of a designated -"last resort" KeyPackage ([RFC9420] Section 16.8). The server MUST -remove a KeyPackage after it has been delivered. Servers SHOULD -pre-generate multiple KeyPackages per user to support concurrent group -additions, MAY designate a last resort KeyPackage per user to be -returned when all single-use KeyPackages are exhausted, and SHOULD -rate-limit KeyPackage requests, so that an attacker cannot block a -user's addition to groups by exhausting their KeyPackages. KeyPackages -carry a leaf node lifetime, and applications MUST define a maximum total -lifetime they accept ([RFC9420] Section 7.2). - -The userId fields defined in this document carry the user's full OCM -Address, not the bare identifier that [OCM] calls userID; the full -address is required because these messages routinely cross server -boundaries. - -
-
Group Lifecycle - -The group lifecycle is entirely independent of other OCM lifecycles -(token-exchange, shares, invitations etc.). Members are added and -removed through MLS group operations conveyed via the /notifications -endpoint. - -
Group Creation - -The creating server creates an MLS group on behalf of one of its users -and initialises leaf nodes for each of its users who are initial -members. The creating user becomes the group's first admin -(), making the creating server the initial Group Owner Server. -No notifications are required for this step. The group becomes -addressable at its OCM Address immediately upon creation. - -The group's OCM Address is minted under the creating server's domain, -which guarantees its uniqueness, and MUST NOT change for the lifetime of -the group. It is a label only: no protocol message is routed based on -it, and it remains valid even after the Group Owner Server role has -moved to another server. The MLS group_id SHOULD be a fresh random -value, as recommended by [RFC9420] Section 11. - -The creator selects the group's MLS cipher suite based on the -capabilities advertised in the prospective members' KeyPackages -([RFC9420] Section 11). Implementations of this document MUST support -the mandatory-to-implement MLS cipher suite -MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519 ([RFC9420] Section 17.1). - -
-
Group Admins - -Every group has a set of admins: users who administer the group -membership. The user who creates the group is its first admin, and an -admin MAY appoint further admins. Admins are ordinary group members and -MAY be homed on any Member Server. An admin's MLS clients are referred -to as admin clients. - -Commits MUST be constructed and signed by admin clients. This is an -application-level policy on top of MLS, as anticipated by [RFC9420] -Section 16.11, and it is enforced at two points. First, the Group Owner -Server MUST reject Commits submitted by any other client. Second, every -Member Server processing an MLS_COMMIT MUST verify that the Commit is -signed by an admin client: a Commit is signed by the leaf indicated in -its sender field ([RFC9420] Section 6.1), and the credential at that -leaf, in the ratchet tree of the epoch in which the Commit was created, -must identify a user listed in admins () as of that same -epoch. A Commit that fails this check MUST be rejected, regardless of -which server broadcast it. Because the admin set is part of the -GroupContext, every member performs this check locally; acceptance of a -Commit does not rely on trusting the Group Owner Server. - -Proposals are handled according to the following policy: - - - An Add proposal, or a Remove proposal targeting a leaf that does not -belong to the proposing user, MUST be explicitly approved by an admin -before an admin client commits it, unless both are part of a rejoin pair -as described below. This places a human in the loop for changes that -grant or revoke another party's access. - A Remove proposal targeting a leaf that belongs to the proposing user -(self-removal) does not require admin approval. Any member MAY leave a -group at any time, and admin clients SHOULD commit self-removal -proposals automatically. - A rejoin pair - a Remove of a leaf together with an Add of a fresh -KeyPackage whose credential carries the same OCM Address as the removed -leaf's credential () - is identity-preserving and grants no -new party access. It does not require explicit admin approval, and -admin clients SHOULD commit rejoin pairs automatically. - Update proposals do not require admin approval, and admin clients -SHOULD commit pending Update proposals automatically whenever they are -online. - - -The group MUST have at least one admin at all times. A proposal that -would remove the last admin, including a self-removal, MUST be rejected -by the Group Owner Server until another admin has been appointed. - -Removing an admin from the group and removing an admin from the admin -set are distinct operations; when an admin's membership ends, a single -Commit combines them (). An admin MAY instead resign from -the admin set while remaining a member: this is a GroupContextExtensions -proposal only, and the resigning admin's own client MAY commit it. -Removing an admin's membership is constrained by MLS: a Commit that -removes its own committer is invalid ([RFC9420] Section 12.2). A Commit -that removes some but not all of an admin's leaves MAY be committed by -one of that admin's remaining clients, but a Commit that removes an -admin's last leaf is necessarily committed by an admin client of a -different admin. - -
Group OCM Address and Admin Set - -The group's OCM Address and the admin set are part of the group state, -carried in a GroupContext extension ocm_federated_group ([RFC9420] -Section 13.4): - -
; -} Admin; - -struct { - opaque group_ocm_address; - Admin admins; -} OCMFederatedGroup; -]]>
- -All addresses are UTF-8 encoded OCM Addresses. The group_ocm_address -field carries the group's OCM Address and MUST NOT change for the -lifetime of the group. - -The admins list is ordered by appointment: a newly appointed admin is -appended at the end, a departing admin is deleted by the same Commit -that ends their membership or admin role (see below), and the list MUST -NOT otherwise be reordered. The home server of the first admin in the -list is the current Group Owner Server. Succession is therefore -automatic: when the first admin leaves the group or resigns as admin, -the home server of the next admin in the list becomes the Group Owner -Server. For example, if alice on server1 creates the group and appoints -bob on server2 and then charlie on server3, the list is (alice, bob, -charlie) and server1 is the Group Owner Server; after bob leaves it is -(alice, charlie); after alice then leaves it is (charlie,) and server3 -is the Group Owner Server. - -An admin client is any MLS client whose leaf credential identifies a -user listed in admins. Because this extension is part of the -GroupContext, it is agreed upon by all members through the MLS key -schedule, every member can verify which clients are entitled to -construct Commits and which server arbitrates them, and new members -learn the group's OCM Address and admin set from the GroupInfo in their -Welcome. Changes to the admin set are made with a -GroupContextExtensions proposal ([RFC9420] Section 12.1.7); such -proposals MUST be explicitly approved by an admin, MUST be committed by -an admin client, and MUST NOT change group_ocm_address. - -The admin set and the group membership are coupled: an entry in admins -is only meaningful while that admin has at least one leaf in the ratchet -tree. A Commit after whose application an admin would no longer have -any leaf in the ratchet tree MUST therefore also include a -GroupContextExtensions proposal deleting that admin from admins, and -the Group Owner Server and all Member Servers MUST reject a Commit that -would leave an entry in admins with no corresponding leaf in the tree. -(A rejoin pair () that replaces an admin's leaf does not -trigger this rule, since the admin retains a leaf after the Commit.) -Because a GroupContextExtensions proposal replaces the extension list -wholesale ([RFC9420] Section 12.1.7), the proposal carries the complete -new OCMFederatedGroup value, with the departing admin deleted and -group_ocm_address unchanged. A GroupContextExtensions proposal whose -only change to the admin set is deleting admins whose leaves are removed -in the same Commit requires no separate admin approval; it follows the -approval status of the Remove proposals it accompanies, so that the -self-removal of an admin can still be committed automatically. - -Clients implementing this document MUST list the ocm_federated_group -extension type in the capabilities.extensions field of their -KeyPackages, since GroupContext extensions must be supported by every -member of the group ([RFC9420] Section 13.4). - -
-
-
Group Owner Server Failover - -The Group Owner Server can become unavailable, leaving the group without -an arbiter and therefore unable to advance its epoch. Leaf staleness -() anchors the failover trigger: the absence of -committed Updates from a leaf is part of the group state that all -members observe identically. The other trigger condition, the absence -of broadcast Commits, is necessarily observer-dependent - a server that -missed a broadcast cannot distinguish silence from loss - which is why -divergent failover decisions are tolerated and resolved -deterministically in step 3 below. - -In addition to the update deadline, groups MUST define a takeover time -T. T MUST be longer than the update deadline, so that the staleness of -the first admin's leaf is observable before takeover is permitted. -Failover proceeds as follows: - - - Trigger: no MLS_COMMIT has been broadcast for time T, and the -first admin's leaf is stale. - Takeover: the home server of the next admin in the admin set MAY -begin arbitrating Commits. The first Commit it arbitrates SHOULD -cover Remove proposals evicting the stale first admin's leaves, together -with the GroupContextExtensions proposal deleting them from the admin -set required by , constructed by one of its own admin -clients. This makes the takeover permanent through the normal -succession rule. - Conflict resolution: if a Member Server receives two different -Commits for the same epoch from two arbiters, it MUST process the -one arbitrated by the server of the admin listed earlier in the admin -set and discard the other. - Hold-back: a Member Server that has observed the trigger conditions -of step 1 SHOULD retain the previous epoch's group state when -processing a Commit, so that it can revert and reprocess the winning -Commit if conflict resolution later discards the one it processed first. -Retained state MUST be deleted after a bounded time, per [RFC9420] -Section 14; the security trade-off is discussed in Security -Considerations. - Rejoin: a Member Server that processed a discarded Commit and no -longer holds the state needed to reprocess the winning Commit has -drifted from the group. It recovers through the rejoin procedure -(). Wrapped FKs are re-wrapped and redistributed by their -sending servers in the new epoch as usual (). - - -Since an unavailable arbiter only pauses membership changes, while -sharing, resource access, and FK distribution continue to operate, the -takeover time T MAY be generous, for example several hours. Loose time -synchronisation between servers is sufficient and is already assumed by -MLS for leaf node lifetimes ([RFC9420] Section 7.2). - -
-
MLS Notification Types - -All MLS group lifecycle messages are sent as OCM Notifications to -<endPoint>/notifications using HTTP POST with Content-Type: -application/json and HTTP Signatures [RFC9421]. - -Proposals and Commits MUST be encoded as PublicMessage objects -([RFC9420] Section 6.2), and Application Messages as PrivateMessage -objects ([RFC9420] Section 6.3). Handshake messages are sent in the -clear at the MLS layer because the servers that route and arbitrate them -are required to track the public group state - the ratchet tree and -GroupContext - in order to derive membership for share routing, resolve -shares to local users, and verify that Commits are signed by admin -clients; in native client deployments those servers do not hold the -group's secrets. A recipient that holds the group's secrets MUST verify -the membership_tag on a PublicMessage ([RFC9420] Section 6.2); a server -relaying or arbitrating without group secrets verifies what it can, -namely the signature against the sender's leaf in its copy of the -ratchet tree and the policy checks of . The confidentiality -trade-off relative to encrypted handshake messages is discussed in -Security Considerations. - -The notification types defined in this document are group-scoped rather -than share-scoped. [OCM] requires a providerId field in notifications -because the notification types it defines all refer to a Share; the MLS -notification types refer to a group instead, so this document updates -that requirement: providerId is REQUIRED only for notification types -that refer to a Share, and the MLS notification types omit it. All -MLS-specific parameters are carried inside the notification object -that [OCM] provides for type-specific parameters. The mlsGroupId -field carries the base64-encoded MLS group_id as advisory routing -information, used to dispatch the message to the right group state -without parsing the MLS message; the authoritative group_id is the one -inside the MLS message itself, and a mismatch between the two MUST be -treated as an error. At the OCM layer, groups are otherwise identified -by their OCM Address: in particular, the groupId field of the -application data carried inside MLS_APPLICATION messages -(, ) is the group's OCM -Address, never the MLS group_id. - -Since MLS_PROPOSAL is delivered only to Admin Servers and never -broadcast to other Member Servers, Member Servers never observe pending -proposals. Proposals covered by a Commit are instead redistributed -together with that Commit, as described under MLS_COMMIT below. Admin -clients, as the only committers (), MUST satisfy all -considerations of [RFC9420] Section 12.4. - -
MLS_WELCOME - -Sent to a Member Server when one of its users is added to the group. -The Welcome is constructed by the admin client that created the -corresponding Commit ([RFC9420] Section 12.4.3.1) and delivered by that -admin's home server directly to the added user's server, after the Group -Owner Server has accepted the Commit. Delivers the MLS Welcome message -for the added user, enabling the receiving MLS client to initialise its -state and derive the current Group Key. A single MLS_COMMIT covering -multiple Add proposals will result in one MLS_WELCOME notification per -added user. - -
", - "userId": "bob@othercloud.example.org", - "content": "" - } -} -]]>
- -The Welcome message MUST include the group's ratchet tree in a -ratchet_tree extension ([RFC9420] Section 12.4.3.3). By default a -Welcome carries only a hash of the tree, and this document defines no -other channel through which a newly added Member Server could obtain it. -Member Servers depend on holding the current ratchet tree, both to -derive the group membership and to process subsequent Commits. Carrying -the tree inside the Welcome also gives it the same confidentiality -protection as the rest of the group state, as recommended by [RFC9420] -Section 12.4.3.3. - -A Member Server processing a Welcome learns the group's OCM Address from -the ocm_federated_group extension in the GroupContext (). -It MUST reject a Welcome whose group_ocm_address is already bound to a -different MLS group_id, unless the Welcome reinitialises the group as -described in . This keeps the local wrapped FK store, keyed -by (resourceId, groupId), unambiguous. - -
-
MLS_PROPOSAL - -Sent by a Member Server to the home server of every admin to propose a -group change (for example Add, Remove, Update, GroupContextExtensions, -or ReInit) on behalf of one of its users. This notification is NOT -broadcast to other Member Servers. Each Admin Server queues received -proposals, deduplicated by ProposalRef ([RFC9420] Section 5.2), for -handling by its admin clients according to the policy in . -Sending the proposal to all Admin Servers removes the dependency on any -single server being available and lets whichever admin is online next -act on it. - -
", - "content": "" - } -} -]]>
- -
-
MLS_COMMIT - -Constructed and signed by an admin client () and submitted to -the Group Owner Server, which accepts at most one Commit per epoch, MUST -reject Commits submitted by non-admin clients, and broadcasts the -accepted Commit to all Member Servers to advance the group epoch. An -admin client whose Commit is rejected discards it and MAY construct a -new Commit on the resulting epoch ([RFC9420] Section 14). A Member -Server receiving a broadcast MLS_COMMIT MUST verify that the Commit is -signed by an admin client before processing it, as specified in -, and MUST reject it otherwise, regardless of which server -broadcast it. Commits are ordered by the MLS epoch itself: each Commit -advances the epoch by exactly one, so Member Servers MUST process -Commits in epoch order, and a Commit arriving for an epoch later than -the next expected one indicates one or more missed Commits. Member -Servers MUST apply the new epoch secret before sending any application -data, per [RFC9420] Section 15.2. - -
", - "proposals": [""], - "content": "" - } -} -]]>
- -A Commit covers each proposal either by value or by reference ([RFC9420] -Section 12.4). Proposals included by value are carried inside the -Commit itself and are necessarily proposals originated by the committing -admin client, since a by-value proposal carries no sender of its own. -Proposals received from Member Servers via MLS_PROPOSAL - in -particular Update proposals, which can only be applied relative to their -original sender's leaf - are covered by reference, and receiving Member -Servers need the original proposal messages in order to validate and -apply the Commit ([RFC9420] Sections 12.1 and 12.4.2). The proposals -array therefore carries every proposal covered by reference, verbatim as -originally sent by their proposers, in the order in which the -corresponding references appear in the Commit. It MUST be present -whenever the Commit covers at least one proposal by reference and MAY be -omitted otherwise. A Member Server processing an MLS_COMMIT MUST -process the carried proposals before processing the Commit itself. - -The MLS_COMMIT serves as the signal to all sending servers that the -epoch has advanced: each sending server then re-wraps and redistributes -the FKs of the resources it shares with the group (), and -on member removal MAY additionally rotate them according to its policy -(). Any Commit covering a Remove, Update, or -GroupContextExtensions proposal MUST include an UpdatePath ([RFC9420] -Section 12.4). - -
-
MLS_APPLICATION - -Sent by a sending server directly to Member Servers, derived from the -ratchet tree, to deliver updated wrapped file keys and, optionally, -updated per-server transport credentials (). No -central relay is involved. Messages carrying wrapped FKs are sent to -all current Member Servers; messages carrying a transport credential are -sent only to the affected Member Server. The content is a -PrivateMessage carrying application data encrypted in the current -epoch ([RFC9420] Section 15). - -
", - "content": "" - } -} -]]>
- -Ordering is provided by authenticated MLS metadata rather than a -transport counter: the PrivateMessage carries the epoch in the clear, -and the sender's leaf and generation counter are learned upon decryption -([RFC9420] Section 6.3). Since all FK updates for a given (resourceId, -groupId) originate from the resource's sending server, the (epoch, -generation) pair totally orders them; see . A -Member Server that receives an MLS_APPLICATION encrypted in an epoch -it has not yet entered SHOULD queue it until the corresponding -MLS_COMMIT has been processed. - -Because credential-bearing messages are delivered to a single Member -Server, other Member Servers will observe a gap in the sending leaf's -generation counter on the next message they do receive. Such gaps are -expected and MUST NOT be treated as an error; receivers ratchet forward -past skipped generations as described in [RFC9420] Section 15.3. -Deployments MUST limit the number of generations a receiver will advance -a sender ratchet in response to a single message and reject messages -beyond that limit, bounding the key derivation work a malicious sender -can trigger ([RFC9420] Section 15.3). - -
-
MLS_REJOIN - -Sent by a drifted Member Server to the home server of every admin to -request re-admission of its users after local MLS state loss -(). Unlike the other notification types, the content is not -an MLS message: a drifted server holds no usable MLS state, so the -request is authenticated only at the OCM layer, by the HTTP Signature of -the sending server. Each entry in keyPackages carries a fresh MLS -KeyPackage for one affected user, in the same format as entries served -by the KeyPackage endpoint. - -
", - "keyPackages": [ - { - "userId": "bob@othercloud.example.org", - "mediaType": "message/mls", - "encoding": "base64", - "content": "" - } - ] - } -} -]]>
- -Admin Servers queue rejoin requests alongside proposals and make them -available to their admin clients, which handle them as described in -. A later rejoin request for the same group and user -supersedes an earlier one; admin clients act on the most recent request. - -
-
-
Leaf Key Updates - -To maintain post-compromise security ([RFC9420] Section 16.6), Member -Servers SHOULD periodically send MLS_PROPOSAL (Update) to the Admin -Servers to rotate their users' leaf keys. Admin clients SHOULD commit -pending Update proposals automatically whenever they are online, without -user interaction; an Update only achieves post-compromise security once -it has been committed ([RFC9420] Section 16.6). - -Groups MUST define an update deadline: the maximum time allowed between -committed Updates of a leaf. A leaf that has not been updated within -the deadline is stale. Members with stale leaves SHOULD be removed from -the group per [RFC9420] Section 3.2, and stale admins in particular -SHOULD be removed promptly: an admin whose clients no longer update -cannot commit, and a stale first admin additionally blocks Commit -arbitration until failover (). - -
-
Rejoin After State Loss - -A Member Server can lose its MLS state for a group: it may have -processed a Commit that was later discarded during failover conflict -resolution () and already deleted the superseded epoch's -secrets per the deletion schedule ([RFC9420] Section 9.2), or its stored -state may be lost or corrupted for any other reason. Such a server has -drifted from the group: it can no longer process Commits or decrypt -Application Messages, and because MLS messages are bound to the current -GroupContext, it cannot sign a valid Proposal with which to recover. A -drifted server detects its condition when an MLS_COMMIT fails to -process against its local state, for example through a confirmation tag -mismatch, or arrives for an epoch it cannot reach after Commit -retransmission has been exhausted. - -Recovery is mediated by an admin client through the normal Commit path: - - - The drifted server discards its MLS state for the group and -generates a fresh KeyPackage for each of its users who are members -of the group. - It sends an MLS_REJOIN notification carrying those KeyPackages to -the home server of every admin. The notification is authenticated -at the OCM layer with HTTP Signatures [RFC9421], the same trust anchor -that authenticates KeyPackage distribution itself, so a rejoin request -is exactly as trustworthy as a freshly fetched KeyPackage. - An admin client verifies that each KeyPackage's credential carries -the OCM Address of a leaf currently in the ratchet tree, and that -the notification was signed by the server named in those OCM Addresses. -A rejoin MUST NOT admit a user without a leaf in the tree; it can only -replace existing members. - The admin client constructs a single Commit containing, by value, a -Remove proposal for each stale leaf and an Add proposal for the -corresponding fresh KeyPackage. This rejoin pair preserves the OCM -Address of every affected leaf and grants no new party access, so admin -clients SHOULD commit it automatically, per the policy in . - The Commit is arbitrated and broadcast as usual, and the drifted -server receives one MLS_WELCOME per re-added user, restoring clean -state from the Welcome's ratchet_tree extension. - - -A single Commit recovers all of the drifted server's users at once. -Until the rejoin completes, the drifted server can continue to serve -resources whose wrapped FKs it received before the fork, using the Group -Key of the last epoch it processed; wrapped FKs distributed after the -fork become accessible when the re-wrap following the rejoin Commit -() arrives. - -
-
Group Reinitialisation - -Reinitialisation ([RFC9420] Section 11.2) replaces a group with a new -MLS group with the same membership and the same OCM Address but -different parameters: a new MLS version, cipher suite, or extension set, -and necessarily a fresh MLS group_id. It is the migration path for -cryptographic agility, for example moving a long-lived group to a -stronger cipher suite. - -A ReInit proposal is a group parameter change and is handled like other -group-changing proposals: it MUST be explicitly approved by an admin and -MUST be committed by an admin client. Per [RFC9420] Section 12.2, a -ReInit proposal is committed alone. The extensions field of the -ReInit proposal MUST include an ocm_federated_group extension with -group_ocm_address unchanged; the admin set is normally carried over -unchanged. - -After the ReInit Commit is processed, the old group MUST NOT be used to -send messages ([RFC9420] Section 12.4.2). In particular, sending -servers MUST NOT send MLS_APPLICATION messages in the old group; the -per-epoch re-wrap obligation () arising from the ReInit -Commit is deferred to the new group. - -The admin client that committed the ReInit SHOULD create the new group: -it fetches fresh KeyPackages, valid for the new version and cipher -suite, for every member of the old group, creates the new group with an -initial Commit re-admitting them, and sends each member a Welcome -carrying a PreSharedKeyID of type resumption with usage reinit, as -specified by [RFC9420] Section 11.2. The Add proposals of this initial -Commit re-admit the old group's members and require no separate admin -approval. If the committing admin client fails to complete this step in -reasonable time, any other admin client MAY do so instead. If a Member -Server receives competing reinitialisation Welcomes for the same -group_ocm_address, it MUST accept the one whose new group was created -by the admin listed earliest in the old group's admin set and reject the -others. - -A Member Server processing a reinitialisation Welcome MUST perform the -verifications of [RFC9420] Section 12.4.3.1 for usage reinit: the last -Commit of the old group contains the ReInit proposal, the new group's -parameters match it, and every member of the old group is a member of -the new group, where members are equivalent if their leaf credentials -carry the same OCM Address. It MUST additionally verify that the -group_ocm_address of the new group equals that of the old group. On -success it rebinds the OCM Address from the old group_id to the new -one; this is the only case in which that binding may change. Because -the local wrapped FK store is keyed by the group's OCM Address, stored -entries carry over unchanged. - -After joining the new group, a sending server MUST re-wrap the FK of -every resource it shares with the group under the new group's Group Key -and redistribute the wrapped FKs to all Member Servers, exactly as for -an epoch change (). The new group's Group Key differs from -any key of the old group both through the fresh epoch secret and through -the new group_id in the Exporter context, so no wrapped FK from the -old group can be unwrapped in the new one. Until the re-wrapped FKs -arrive, Member Servers retain the old group's last Group Key under the -same retention rule as for an epoch change. Members SHOULD retain the -resumption PSK of the old group's final epoch until the reinitialisation -has completed ([RFC9420] Section 8.6). - -
-
-
Encryption Model - -
Group Key Derivation - -After processing any MLS Welcome or Commit, the MLS client MUST apply -the new epoch secret before encrypting any application data, then -derives the current Group Key: - -
- -AEAD.Nk is the length in bytes of a key for the AEAD algorithm of the -group's negotiated MLS cipher suite ([RFC9420] Section 9.1). Deriving -the Group Key at exactly this length makes it a valid key for the wrap -AEAD (), which is the AEAD algorithm of the group's -cipher suite, for every cipher suite, including those whose AEAD takes a -16-byte key such as AES-128-GCM. - -The MLS Exporter ([RFC9420] Section 8.5) produces application-specific -key material from the epoch secret without exposing the epoch secret -itself. The label "ocm-group-key" scopes the output to this -application. The group_id_bytes context, the raw MLS group_id of -the group, further binds the output to this specific group. The Group -Key therefore changes with every epoch transition and cannot be derived -by any party that did not participate in that epoch. - -Per [RFC9420] Section 8.5, the Group Key SHOULD be refreshed after each -processed Commit. Security-sensitive values derived from the epoch -secret MUST be deleted as soon as they are consumed, per [RFC9420] -Section 9.2. - -All MLS clients in the group independently derive the same Group Key for -a given epoch. - -
-
Resource Id - -The resourceId used in the AEAD associated data MUST be a stable -identifier for the underlying file, consistent across all groups it is -shared with. It identifies the resource, not a particular version of -it. This ensures that the FK unwrapped by members of any group correctly -decrypts the same ciphertext. The providerId values in separate share -notifications, for the same resource, MUST differ, per the providerId -definition in [OCM], but the resourceId in the AEAD associated data -MUST be the same. This means that the providerId MUST NOT be reused -as resourceId. The sending server is responsible for maintaining this -stable resourceId and MUST send it in the encryption object of the -share payload (). - -
-
File Key Wrapping - -Two AEAD algorithms are involved in protecting a resource, and they are -deliberately decoupled. The content AEAD encrypts the resource itself: -it is chosen by the sending server from the AEAD algorithms defined for -HPKE ([RFC9180] Section 7.3), it is fixed for the lifetime of a -ciphertext and identical across all groups the resource is shared with, -and it is identified explicitly by the cipher field of the -encryption object (). The wrap AEAD protects the FK -in transit: it is always the AEAD algorithm of the respective group's -MLS cipher suite, keyed with that group's Group Key, and may therefore -differ between groups that share the same resource. - -When sharing an encrypted resource with a group, the sending MLS client -acts on behalf of a user who is a member of that group: - - - Chooses the content AEAD and generates a random per-file key (FK) -whose length is the key length of that algorithm. - Encrypts the resource with FK using the content AEAD. -Implementations supporting native client decryption of large files -SHOULD use a chunked AEAD construction to enable streaming decryption. - Derives the current Group Key from the user's local MLS state. - Wraps FK using the wrap AEAD: -
- -where the associated data is the serialisation of the following -structure, in the presentation language of [RFC9420]: -
; - opaque resource_id; -} FKWrapAAD; -]]>
- -The group_ocm_address field is the UTF-8 encoding of the group's -OCM Address (the same value carried in the shareWith field of the -share notification) and resource_id is the UTF-8 encoding of the -resourceId field of the encryption object. The length-prefixed -encoding makes the pair unambiguous; raw concatenation of the two -strings would allow distinct (address, identifier) pairs to produce -identical associated data. The MLS group_id is NOT used in the -associated data.
- Sends an MLS_APPLICATION notification directly to all current -Member Servers, carrying the wrapped FK keyed by (resourceId, -groupId). -
- -
-
FK Re-wrap on Epoch Change - -The Group Key changes with every epoch transition, whatever the reason -for the transition: a Commit covering Add, Remove, Update, or -GroupContextExtensions proposals, or an empty Commit, all advance the -epoch. To maintain the invariant that the current Group Key is always -sufficient to unwrap the current wrapped FK, a sending server MUST, -after processing an MLS_COMMIT for a group, or after joining the -successor group of a reinitialisation via its Welcome (), for -every resource it shares with that group: - - - Re-wrap the resource's current FK under the new Group Key, following -the procedure in . - Distribute the new wrapped FK to all current Member Servers, derived -from the new ratchet tree, via MLS_APPLICATION. - - -Note that the FK itself is unchanged by this procedure; only its -wrapping is refreshed. Whether the FK is also rotated is a separate, -removal-triggered policy decision (). - -If the Commit added one or more members, the set of Member Servers may -have grown. The sending server MUST identify Member Servers that are -new to the group and send them the Share Creation Notifications for its -federation shares with the group, as described in , in -addition to the wrapped FKs. A server that joins the group after a -share was created thereby receives both the share itself and a wrapped -FK it can decrypt, since the MLS_APPLICATION is encrypted in an epoch -in which it is a member. - -Between processing a Commit and receiving the re-wrapped FK for a -resource, a Member Server holds a wrapped FK produced under the previous -epoch's Group Key. To remain able to serve access requests in this -window, a Member Server SHOULD retain the previous epoch's Group Key -until it has received a strictly newer wrapped FK () -for every locally stored (resourceId, groupId) pair of that group, or -until a bounded time has elapsed, whichever comes first, and MUST delete -it at that point. The security trade-off of this retention window is -discussed in Security Considerations. - -The volume of MLS_APPLICATION traffic produced by this rule grows with -the number of shared resources and the frequency of epoch transitions; -see the batching item in Open Issues. - -
-
Key Distribution via MLS Application Messages - -Wrapped file keys are distributed to Member Servers via MLS Application -Messages, PrivateMessage objects carrying application data ([RFC9420] -Section 15). Wrapped FKs are distributed at share creation and -re-distributed after every epoch transition (). A sending -server MUST process the MLS_COMMIT and derive the new Group Key before -sending an MLS_APPLICATION with updated wrapped keys, per [RFC9420] -Section 15.2. - -The PrivateMessage application data is a JSON object carrying the -current wrapped FK for each (resourceId, groupId) pair in a keys -array, and MAY also carry a credentials array (): - -
" - } - ] -} -]]>
- -The groupId field carries the group's OCM Address, matching the -shareWith of the corresponding share notification, and the -resourceId field matches the resourceId in the encryption object -of that notification. - -The PrivateMessage is encrypted using the current epoch's keys, so -only current group members can decrypt it. A just-removed member cannot -decrypt the Application Message even if they receive the notification, -as they do not hold the new epoch's key material. - -Member Servers store the received wrapped FKs locally, keyed by -(resourceId, groupId), always replacing any previous wrapped FK for -the same pair with the latest one. "Latest" is defined by the -authenticated (epoch, generation) of the enclosing PrivateMessage, -compared lexicographically, not by arrival order: a stored wrapped FK -MUST only be replaced by one with a strictly higher (epoch, -generation). A sending server MUST send all FK updates for a given -group through a single MLS leaf within any given epoch, since generation -counters are maintained per leaf; updates from a later epoch always -supersede updates from an earlier epoch regardless of leaf. MLS -Application Messages may be delayed or reordered in transit ([RFC9420] -Section 15.3); a Member Server that receives an out-of-order -MLS_APPLICATION simply ignores wrapped FKs that are not newer than -those it already holds. At access time, the Member Server uses its -current Group Key, derived from its current MLS state for the identified -group, to unwrap the FK. - -
-
Transport Credential Updates - -The per-server transport credential of a share () may -need to be rotated during the lifetime of the share. In particular, in -native client deployments the user's device interacts directly with the -sending server and therefore holds its server's credential, so when such -a user is removed from the group, the credential of their server can no -longer be considered private to that server's remaining users. On -removal of a member whose clients may have held a server's transport -credential, the sending server SHOULD rotate that server's credential -for every share affected. Rotation MAY also be triggered by policy or -suspected leakage. - -A rotated credential is delivered in an MLS_APPLICATION message sent -only to the affected Member Server, carrying a credentials array in -the application data: - -
" - } - ] -} -]]>
- -Each entry identifies the share by its providerId, the group by its -OCM Address in groupId, and the intended Member Server by its FQDN in -recipient. A Member Server MUST ignore entries whose recipient does -not name itself. Upon accepting an entry, the Member Server replaces -the stored transport credential for that share; replacement follows the -same (epoch, generation) supersede rule as wrapped FKs -(). The sending server invalidates the old -credential once the rotation has been delivered. - -Encrypting the credential update in the current epoch guarantees that -the removed member cannot read it, independent of transport protection: -they do not hold the new epoch's key material. Confidentiality with -respect to other Member Servers, by contrast, rests on targeted -delivery: the PrivateMessage is decryptable by any group member that -obtains it, so delivering it to the affected server only is a routing -measure, not a cryptographic one (see Security Considerations). - -A keys array and a credentials array MAY appear in the same -application data object when both are destined for the same single -Member Server. - -
-
Resource Access - -To access a resource: - - - The resource is fetched from the sending server using the standard -OCM resource access procedure ([OCM]), with the protocol details and -per-server credential from the protocol object of the share -notification. For an encrypted resource, what is fetched is ciphertext. - The MLS client identifies the relevant group from the shareWith -field of the share notification and looks up the locally stored -wrapped_file_key for the (resourceId, groupId) pair. - The MLS client derives the current Group Key from its local MLS -state for that group and unwraps FK using the wrap AEAD of the -group's cipher suite. - The MLS client decrypts the resource using FK and the content AEAD -named in the cipher field of the encryption object. - - -In web-client deployments, decryption happens server-side and the -plaintext is served to the user through whatever access protocol is in -use (WebDAV [RFC4918], SFTP, webapp, etc.). In native client -deployments, decryption happens on the user's device and the client -interacts directly with the sending server, which serves only -ciphertext. - -
-
Resource Modification by Member Servers - -A common operation is for a user on a Member Server to open a shared -encrypted resource, modify it, and save it back. The cryptographic flow -is as follows: - - - The Member Server fetches the encrypted resource from the sending -server using the standard OCM resource access procedure, with the -credential from the share's protocol object. - The Member Server identifies the relevant group from the shareWith -field of the share notification, looks up the locally stored -wrapped_file_key for the (resourceId, groupId) pair, derives the -current Group Key from its local MLS state for that group, and unwraps -FK. - The Member Server decrypts the resource using FK and presents the -plaintext to the user. - The user modifies the resource. - The Member Server re-encrypts the modified resource using the same -FK and the same content AEAD, but a fresh random nonce. The nonce -MUST NOT be reused with the same key, as required by AEAD security. - The Member Server uploads the re-encrypted resource to the sending -server. This requires the share to grant write permission in its -protocol object. - - -The FK is reused across modifications of the same resource because it is -bound to the group's OCM Address and resourceId in the AEAD associated -data, making it specific to that resource. No new MLS_APPLICATION -message is needed, as the wrapped FK in all Member Servers' local stores -remains valid for the updated ciphertext. - -FK rotation for a resource is only necessary on member removal in -re-encryption mode (). - -
-
Sharing a Resource with Multiple Groups - -A sending server MAY share the same encrypted resource with more than -one group. The file is encrypted once, with a single FK and a single -content AEAD; the cipher field in every group's share notification -names that same algorithm. Each group receives its own wrapped FK, -produced with that group's wrap AEAD, Group Key, and OCM Address: - -
- -A separate Share Creation Notification is sent to each Member Server of -each group. A separate MLS_APPLICATION carrying the respective -wrapped FK is broadcast to each group's Member Servers. Members of each -group can only unwrap the FK using their own group's Group Key and -cannot access the other group's wrapped FK or Group Key. - -The sending server MUST maintain a mapping from each resource to all -groups it has been shared with. This mapping is required to correctly -handle member removal in re-encryption mode, as described in the -following section. - -
-
FK Rotation (RECOMMENDED) - -FK rotation is distinct from the re-wrap performed on every epoch change -(): rotation generates a new FK and re-encrypts the -resource, whereas a re-wrap only refreshes the wrapping of the existing -FK. A sending server SHOULD rotate the FK for a resource when a member -is removed from any group that has access to it. FK rotation may also -be triggered by other factors, such as periodic key rotation policy, -regulatory requirements, or a suspected compromise of key material. -Applications SHOULD define a policy for the frequency of FK rotation -independent of membership changes. - -When rotating the FK for a resource, the sending server: - - - Generates a new FK for the resource. - Re-encrypts the resource with the new FK. - For every group that has access to the resource, wraps the new FK -using that group's current Group Key: -
-
- Broadcasts an MLS_APPLICATION notification carrying the respective -new wrapped FK directly to each group's Member Servers. -
- -Distributing the new wrapped FK to all groups that share the resource is -necessary because all groups share the same ciphertext. If only one -group received the new wrapped FK, members of other groups would hold a -wrapped FK that no longer decrypts the current ciphertext. - -A member removed from one group but still a member of another group that -shares the same resource retains the ability to decrypt that resource -through the second group. This is correct and intended behaviour: -access is determined by current group membership, and the user remains a -member of the second group. The default safe rule is to rotate the FK -and redistribute to all groups on any removal event. A sending server -MAY instead compare the unique set of users with access before and after -an epoch change, and skip FK rotation if that set is unchanged, for -example because the removed user remains a member of every other group -that has access to the same resource. Whether this optimisation is -worth the added complexity depends on the nature of the resource and the -frequency of membership changes. - -Member addition does not require FK rotation. The new member receives -the current Group Key via their Welcome, and the re-wrap triggered by -the Add Commit () delivers a wrapped FK, encrypted in an -epoch in which the new member is a member, that the new member can -unwrap with that Group Key. - -
-
Member Removal: Key-reuse Mode (OPTIONAL) - -Where re-encryption is impractical, for example due to frequent changes -of very large files, and where all participating servers belong to a -formal federation with explicit governance and mutual trust, a sending -server MAY instead keep the existing FK. In that case no action beyond -the standard re-wrap on epoch change () is required: the -Remove Commit advances the epoch, and the sending server re-wraps the -existing FK under the new Group Key and distributes it to the remaining -Member Servers of the affected group. - -When a resource is shared with multiple groups, only the epoch of the -group from which the member was removed has advanced, so only that -group's FK wrapping is refreshed. The wrapped FKs for other groups are -unchanged and remain valid for their respective members. - -In this mode, access-follows-membership relies on trust rather than -cryptography: the FK itself is unchanged, so a removed member's server -and, in native client deployments, the removed user's devices, may still -hold the superseded Group Key together with the old wrapped FK, or the -unwrapped FK itself, any of which decrypts the unchanged ciphertext. -Key-reuse mode therefore relies on trusting servers to discard key -material they are no longer entitled to after a Remove Commit. A -removed member who is also a member of another group that has access to -the same resource will still be able to decrypt via that group's wrapped -FK, which is the expected behaviour - they remain a member of that -group. This assumption is appropriate within a formal federation but -SHOULD NOT be made in open or ad-hoc sharing contexts. - -The sending server's choice of mode is its own policy decision and is -not signalled in the protocol. - -
-
Member Removal: OCM Notifications - -Member removal requires no OCM-level notification by itself. Because -federation shares are addressed to the group (), each -Member Server observes the Remove Commit and re-evaluates which of its -local users the share resolves to; a removed user loses access without -any action by the sending server. If the removed member's clients may -have held their server's transport credential, the sending server SHOULD -additionally rotate that credential (). - -When the last member homed on a given server is removed from the group, -that server no longer has any user with access. A well-behaved sending -server SHOULD then reconcile the OCM state of the share, revoke that -server's per-server transport credential (), and send -a SHARE_UNSHARED notification to the /notifications endpoint of that -server. - -
-
-
Share Creation - -The sending server sends one OCM Share Creation Notification directly to -each current Member Server, identified through the OCM Addresses in the -ratchet tree's leaf credentials. This is standard OCM server-to-server -communication, with shareWith set to the group's OCM Address and -shareType set to "federation". The share is addressed to the group -as the Receiving Party; no per-user notifications are sent. - -A federation share is a standard OCM share: every field that is REQUIRED -by [OCM], including the protocol object, is REQUIRED here too, and -resource access follows the standard OCM resource access procedure -driven by the protocol object. For encrypted resources the protocol -endpoint serves ciphertext; the plaintext is obtained by unwrapping the -FK as described in the Encryption Model. - -Each Member Server SHOULD be given its own sharedSecret (or equivalent -protocol credential) in its copy of the notification. The credential is -per server, not per user: all users on a Member Server share it, -mirroring how the server holds MLS state on behalf of its users. -Distinct per-server credentials allow the sending server to revoke a -single server's transport access, for example when the last group member -on that server is removed, without affecting other Member Servers. -Share Creation Notifications sent to servers that join the group later -() carry credentials minted at that time, and a server's -credential can be rotated during the share's lifetime -(). - -Share Permissions apply uniformly to the whole group: every member of -the group receives the same permissions on the resource. A sending -server that needs different permissions for different parties should use -separate groups or individual shares. Receiving Server criteria that -affect the share payload, such as must-exchange-token, are evaluated -per Member Server against that server's discovery document, exactly as -in base OCM. - -The receiving server resolves shareWith against its local MLS state: -it identifies the group whose group_ocm_address () -matches the shareWith value and delivers the share to every local user -whose leaf credential appears in that group's ratchet tree. On every -subsequent MLS_COMMIT the receiving server MUST re-evaluate this -resolution, so that local users added to the group gain access to -existing federation shares, and removed users lose it, without any -further OCM notifications. - -Addressing the share to the group also allows the receiving server to -distinguish between shares of the same resource arriving via different -groups - a user may be a member of two groups that both have access to -the same resource from the same sending server - and to correctly key -its local wrapped FK store by (resourceId, groupId) rather than -resourceId alone, where groupId is the group OCM Address carried in -shareWith, ensuring that FK updates delivered via MLS_APPLICATION -are applied to the correct entry. - -Because notifications can be delayed or reordered in transit, a -federation share MAY arrive before the receiving server has processed -the Welcome or Commit that made it a Member Server of the group. A -receiving server that does not recognise the shareWith value as a -known group SHOULD queue the share, or reject it in a way that causes -the sender to retry, rather than fail it permanently. Since sending -servers only contact servers present in the ratchet tree, this condition -is transient. - -When an MLS_COMMIT adds one or more members to the group, the sending -server MUST send each Member Server that is new to the group a Share -Creation Notification for every federation share it has with that group, -encrypted or not. For encrypted resources this accompanies the -re-wrapped FK (). A server that joins the group after a -share was created thereby learns of the shares its users now have access -to without any further action by its users. - -Each notification MAY include the optional encryption field: - -
", - "permissions": ["read", "write"] - } - }, - "encryption": { - "scheme": "ocm-mls-1", - "cipher": "AES-256-GCM", - "resourceId": "3a02538b-aa54-42f2-8853-a38996e211b1" - } -} -]]>
- -The encryption field is OPTIONAL. If absent, the resource is -unencrypted and the share follows the standard OCM flow without -modification. If present, it carries all encryption-related parameters: -scheme identifies the encryption scheme, for which this document -defines "ocm-mls-1"; resourceId is the stable resource identifier -described in ; and cipher (REQUIRED when encryption -is present) names the content AEAD that the resource is encrypted with -(), one of the AEAD algorithms defined for HPKE -([RFC9180] Section 7.3): "AES-128-GCM", "AES-256-GCM", or -"CHACHA20-POLY1305". The field signals that the FK is distributed via -the MLS_APPLICATION mechanism keyed by (resourceId, groupId). No -epoch information is carried in the share notification. Member Servers -always hold the current wrapped FK for each (resourceId, groupId) pair -and use their current Group Key to unwrap it at access time. - -The Group Owner Server is not involved in the delivery of OCM share -notifications. All other OCM notifications relating to a share, such as -share updates and share deletions, are likewise sent directly from the -sending server to each Member Server, referencing the share by its -providerId as in base OCM. - -
-
Trust and Authentication - -The Authentication Service role ([RFC9420] Section 3) is fulfilled by -each user's home OCM server: the server that publishes a user's -KeyPackages attests the binding between the user's OCM Address and their -signature key. Because the basic credential itself carries no -verifiable binding, the attestation lies in the delivery channel. - -
Validation procedure - -A KeyPackage is considered validated with the AS when all of the -following hold: - - - it was fetched from the <endPoint>/mls-key-packages endpoint of the -server named in the credential's OCM Address, over TLS, with the -response signed using HTTP Signatures [RFC9421] verifying against that -server's JWKS [RFC7517]; - the OCM Address in the credential is identical to the userId the -KeyPackage was requested for, which is the OCM Address of the user the -requester intends to add; in particular, its host part names the server -the KeyPackage was fetched from; and - the KeyPackage signature verifies with the signature_key of its -LeafNode, proving possession of the private key ([RFC9420] Section -10.1). - - -Requests to the KeyPackage endpoint are signed at the server level -(), so in native client deployments the -fetch is performed by the admin's home server on the admin client's -behalf. The home server SHOULD relay the response with its HTTP -Message Signature intact, allowing the native client to verify the -channel binding end-to-end against the target server's published JWKS; -a native client that cannot do so delegates the channel verification to -its home server and verifies the KeyPackage signature itself. - -[RFC9420] Section 5.3.1 requires a credential to be validated whenever -it is introduced into the group. This protocol distributes that duty to -the party that introduces the credential: - - - Add: the admin client committing an Add MUST have validated the -KeyPackage as described above. Other members accept the new leaf on the -strength of the admin-signed Commit; they do not contact the new -member's home server. - Update proposals, and Commits whose UpdatePath carries a new -credential: the successor credential MUST present the same OCM Address -as the credential it replaces, and members MUST reject the proposal or -Commit otherwise. This is the successor-credential policy anticipated -by [RFC9420] Section 5.3.1. Continuity of the signature key is anchored -in MLS itself: the message introducing the new leaf is signed with the -member's current key, so only the holder of the previous key can rotate -to a new one. - Joining via Welcome: the joiner MUST verify the GroupInfo signature -and the integrity of the ratchet tree as required by [RFC9420] Section -12.4.3.1, and MUST verify that every leaf credential is a basic -credential carrying a well-formed OCM Address. The joiner accepts the -bindings of those credentials transitively, on the basis that each was -validated by an admin client when it was introduced. It MAY -additionally re-validate any leaf against the /mls-key-packages -endpoint of its home server, but such re-validation can fail benignly, -since published KeyPackages rotate independently of leaves already in -groups. - - -In this transitive model, each home server is trusted to attest only its -own users, and each admin client is trusted to have performed the -attestation check at introduction time. A malicious home server can -impersonate its own users - it is their Authentication Service - but it -cannot impersonate users of other servers, since it cannot produce an -authenticated KeyPackage delivery for an OCM Address whose host part it -does not serve. - -Users who require protection of their key material from their own server -should choose a native client implementation where cryptographic -operations occur on the user's device. - -
-
-
Security Considerations - -Trust model. In web-client deployments, the OCM Server holds the -Group Key and can decrypt any resource shared with the group on behalf -of its users. This is consistent with the standard OCM Server trust -model, where users trust their server with their data, and with OCM's -existing approach of abstracting security to the server level. Native -client deployments provide stronger isolation, as the server does not -hold key material. Implementations SHOULD move toward native client -deployments over time. - -FK rotation vs key-reuse. FK rotation provides cryptographic access -revocation on member removal, independent of trust assumptions, and -SHOULD also be performed periodically or when key compromise is -suspected. In key-reuse mode the FK is unchanged and the ciphertext is -not re-encrypted, so revocation is not cryptographic: it relies on -trusting servers to discard all key material they are no longer entitled -to - superseded Group Keys, old wrapped FKs, and any cached unwrapped -FKs - after a Remove Commit. Key-reuse mode SHOULD only be used within -formal federations with governance agreements that enforce this -behaviour. - -Two access-control layers. For an encrypted federation share, access -is controlled at two independent layers: the per-server transport -credential in the protocol object gates who can fetch the ciphertext, -and the Group Key gates who can unwrap the FK and decrypt it. -Confidentiality rests on the cryptographic layer alone; the transport -credential provides defence in depth and is shared by all users on a -Member Server. The two layers can diverge: a server whose last group -member was just removed may still hold a valid transport credential -until the sending server revokes it, which is why revocation SHOULD -accompany the SHARE_UNSHARED notification. For unencrypted federation -shares the transport credential is the only access control, exactly as -in base OCM, and access-follows-membership then depends on the receiving -server re-evaluating share resolution on every Commit -() and on the sending server revoking the credentials -of departed servers promptly. - -Credential rotation. Rotated transport credentials are delivered in -group-encrypted MLS_APPLICATION messages sent only to the affected -server (). A removed member is excluded -cryptographically: it does not hold the new epoch's key material. Other -Member Servers are excluded only by targeted delivery; a credential -message that leaks to another member server is readable by it. Since -every Member Server already holds transport access to the same -ciphertext under its own credential, the impact of such a leak is -limited to transport-layer attribution. - -Key distribution via Application Messages. Wrapped FKs are -distributed in MLS PrivateMessage objects encrypted in the current -epoch. A removed member cannot decrypt these messages as they do not -hold the new epoch's key material. Because sending servers re-wrap and -redistribute FKs after every epoch transition (), and -Member Servers always replace their locally stored wrapped FK with the -latest received, the current Group Key is always sufficient for -unwrapping once the re-wrapped FKs have arrived. - -Group Key retention window. Between processing a Commit and -receiving the re-wrapped FKs for the new epoch (), a Member -Server may retain the previous epoch's Group Key in order to keep -serving access requests. This retention slightly weakens forward -secrecy for the duration of the window: a server compromised during the -window exposes the previous epoch's Group Key in addition to the current -one. The window is bounded by the arrival of the re-wrapped FKs, and -Member Servers MUST delete the previous Group Key as soon as it is no -longer needed, or after a bounded time, whichever comes first. - -Commit ordering. The Group Owner Server is the sole arbiter of -Commits, eliminating conflicting Commits for the same epoch during -normal operation. A compromised or unavailable Group Owner Server can -stall epoch transitions, but it cannot decrypt resource content, and it -cannot cause the group to accept a Commit constructed by a non-admin -client, because every Member Server independently verifies the committer -against the admin set before processing a Commit (). The role -passes automatically to the next admin's server when the first admin -leaves the group (), and an unavailable arbiter is -eventually replaced through failover (), during which -conflicting Commits can briefly exist and are resolved -deterministically. - -Forked-state retention. During a detected failover window, Member -Servers retain the previous epoch's group state so that they can revert -to the winning Commit (). Retaining forked state weakens -forward secrecy for its duration; [RFC9420] Section 14 requires such -state to be deleted promptly, so the retention is bounded in time and -limited to servers that have observed the failover trigger. - -Rejoin. The rejoin procedure () lets a home server replace -its own users' leaves with fresh KeyPackages on the strength of its HTTP -Signature alone, without per-request admin approval. This grants no new -capability: the home server is already the trust anchor for its own -users' KeyPackages and could substitute their keys at any time through -the ordinary KeyPackage endpoint. Because admin clients verify that a -rejoin only replaces leaves whose OCM Addresses name the requesting -server and that are already present in the ratchet tree, a rejoin can -never admit a new party. - -Admin liveness and removal latency. A Remove proposal takes -cryptographic effect only when an admin client commits it. Removing -another member additionally requires explicit admin approval, so the -revocation latency for a membership change is bounded by admin -availability. Groups SHOULD appoint multiple admins, on multiple Member -Servers, to keep this window small and to avoid stalling group -operations when a single admin is offline. The same bound applies to -the post-compromise security provided by Update proposals, which only -take effect once committed. - -Application message ordering. Per [RFC9420] Section 15.2, sending -servers MUST apply a new epoch secret before encrypting any application -data. MLS_APPLICATION messages carrying re-wrapped keys MUST be sent -only after the sending server has processed the corresponding -MLS_COMMIT. - -Ordering and the DS. All ordering in this protocol derives from -MLS-authenticated metadata: Commits are ordered by the epoch they -advance, and FK updates by the (epoch, generation) of the enclosing -PrivateMessage. No unauthenticated transport counter is relied upon. -Servers in the DS role can still delay, drop, or selectively withhold -messages, but cannot reorder them undetectably or forge them, consistent -with the MLS threat model ([RFC9420] Section 16.9). - -Reinitialisation continuity. A reinitialisation Welcome is accepted -only with a resumption PSK from the old group's final epoch and after -verification of the old group's ReInit Commit and of membership -preservation (). A party that was not a member of the old -group's final epoch cannot produce that PSK, so the binding between a -group's OCM Address and its MLS group state cannot be hijacked through a -forged reinitialisation. - -Handshake message confidentiality. Proposals and Commits are sent as -PublicMessage, so group operations are visible to the servers that -handle them. The MLS architecture [RFC9750] recommends encrypting -handshake messages to hide membership changes and signatures from the -Delivery Service; this protocol deliberately departs from that -recommendation because the servers performing the DS role must know the -group's membership anyway: sending servers derive notification -recipients from the ratchet tree, and receiving servers resolve -federation shares to their local users. No information is exposed to -those servers beyond what their OCM duties already require, and -transport protection (TLS and HTTP Signatures [RFC9421]) prevents -exposure to outside observers. Application Messages, which carry key -material, are always encrypted as PrivateMessage. - -Group membership privacy. The ratchet tree contains every member's -OCM Address and is held by every Member Server, so the full membership -of a group is visible to all servers that have a member in it. This is -inherent to the design - servers route shares and notifications using -exactly this information - but it sets the privacy baseline: federated -groups are not anonymous, and membership of a group is as visible to the -participating servers as membership of a shared folder. The tree is not -exposed to servers outside the group, and transport protection prevents -exposure to third parties. - -Admin set integrity. The admin set and the group's OCM Address are -carried in the GroupContext (), so they are covered by the -MLS confirmation tag and agreed upon by all members of every epoch. A -malicious server cannot unilaterally appoint admins or seize the Group -Owner Server role; changing the admin set requires a Commit constructed -by an existing admin client. - -Post-compromise security. Member Servers SHOULD periodically rotate -their users' leaf keys via Update proposals to maintain post-compromise -security ([RFC9420] Section 16.6). Members that do not update SHOULD -eventually be removed from the group. - -Key material deletion. Security-sensitive values MUST be deleted as -soon as they are consumed, per [RFC9420] Section 9.2. In particular, -the exporter_secret used to derive the Group Key must not be retained -after the Group Key has been derived. - -KeyPackage reuse. KeyPackages MUST be one-time use, except for a -designated last resort KeyPackage used when a user's single-use -KeyPackages are exhausted ([RFC9420] Section 16.8). Servers MUST remove -a KeyPackage that has been consumed, and SHOULD rate-limit KeyPackage -requests to make exhaustion attacks impractical. - -User enumeration. A server MUST only reply to HTTPS GET requests -signed using HTTP Message Signatures [RFC9421] and SHOULD implement rate -limiting and other access control methods on the /mls-key-packages -endpoint to avoid user enumeration. - -
-
IANA Considerations - -The MLS Exporter label "ocm-group-key" used in the Group Key -Derivation section is to be registered in the "MLS Exporter Labels" -registry defined in [RFC9420] Section 17.8, to avoid collisions with -other applications using the MLS Exporter: - - - Label: "ocm-group-key" - Recommended: N - Reference: This document - - -The GroupContext extension ocm_federated_group defined in - is to be registered in the "MLS Extension Types" registry -defined in [RFC9420] Section 17.3: - - - Value: TBD - Name: ocm_federated_group - Message(s): GC - Recommended: N - Reference: This document - - -
-
Open Issues - -This section collects open design issues and shall be removed before -publication. - - - Streaming decryption. A chunked AEAD construction enabling -streaming decryption of large files should be specified for native -client implementations. The specific construction and its interaction -with the FK wrapping model needs to be defined. - Application Message batching. The frequency and batching of -MLS_APPLICATION messages carrying wrapped FKs needs to be defined. -Since every epoch transition triggers a re-wrap of every shared -resource's FK (), batching is load-bearing when many shares -exist and epoch transitions are frequent. - Commit retransmission. A missed Commit is detected directly from -the MLS epoch: a Commit arriving for a later epoch than the next -expected one indicates a gap. A mechanism for requesting retransmission -of missed Commits, from the Group Owner Server or any Admin Server, -needs to be specified. Retransmission is the first remedy for a gap; -the rejoin procedure () is the fallback when retransmitted -Commits can no longer be applied. The proposed OCM Journaling mechanism -can be useful in this context. - - -
-
References - -
Normative References - -[OCM] Lo Presti, G., de Jong, M.B., Baghbani, M. and Nordin, M. "Open -Cloud -Mesh", -Work in Progress, Internet-Draft. - -[RFC2119] Bradner, S. "Key words for use in RFCs to Indicate -Requirement Levels", -March 1997. - -[RFC7517] Jones, M., "JSON Web Key -(JWK)", May 2015. - -[RFC8174] Leiba, B. "Ambiguity of Uppercase vs Lowercase in RFC 2119 -Key Words", May 2017. - -[RFC9180] Barnes, R., Bhargavan, K., Lipp, B. and Wood, C. A. "Hybrid -Public Key Encryption", -February 2022. - -[RFC9420] Barnes, R., Beurdouche, B., Robert, R., Millican, J., Omara, -E. and Cohn-Gordon, K. "The Messaging Layer Security (MLS) -Protocol", July 2023. - -[RFC9421] Backman, A., Richer, J. and Sporny, M. "HTTP Message -Signatures", February -2024. - -
-
Informative References - -[RFC4918] Dusseault, L. M. "HTTP Extensions for Web Distributed -Authoring and -Versioning", June 2007. - -[RFC9750] Beurdouche, B., Rescorla, E., Omara, E., Inguva, S. and Duric, -A. "The Messaging Layer Security (MLS) -Architecture", April -2025. - -
-
-
Acknowledgements - -This work builds on the Open Cloud Mesh specification and the -discussions in the OCM community. - -Work on this document has been funded by [Sovereign Tech Agency][sta] -through the Tech Fund, with a specific project. - -
- - -
- - - - - - - - - - - - -
-