From a8d71bddb144c4fdf20f998a73c31a7de9a3320e Mon Sep 17 00:00:00 2001 From: glpatcern <6871173+glpatcern@users.noreply.github.com> Date: Sat, 13 Jun 2026 11:21:35 +0000 Subject: [PATCH 1/2] CI: regenerate IETF XML files for Datatracker Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- IETF-OCM-IP.xml | 2172 +++++++++++++++++++++++++++++++++++++ IETF-OCM-MLS.xml | 2666 ++++++++++++++++++++++++++++++++++++++++++++++ IETF-OCM.xml | 1726 ++++++++++++++++++------------ 3 files changed, 5907 insertions(+), 657 deletions(-) create mode 100644 IETF-OCM-IP.xml create mode 100644 IETF-OCM-MLS.xml diff --git a/IETF-OCM-IP.xml b/IETF-OCM-IP.xml new file mode 100644 index 0000000..5bd8cb6 --- /dev/null +++ b/IETF-OCM-IP.xml @@ -0,0 +1,2172 @@ + + + + + + + + + + +]> + + + + + Open Cloud Mesh Integration Protocol + + + 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 + + + + + + +The Open Cloud Mesh Integration Protocol (OCM-IP) defines how an Open +Cloud Mesh (OCM) Server can integrate supporting servers, such as +SSH/SFTP servers, web application platforms, or stand-alone WebDAV +servers, to perform protocol-specific work on its behalf. + +OCM-IP makes it possible for existing OCM Servers to offload protocol +specific interactions to stand-alone servers, or even implement OCM as a +lightweight server that handles only the OCM parts of a deployment: +discovery, share creation, token issuance and signing. Anything +protocol-specific, such as serving files over WebDAV, providing SSH +access, or running an interactive web application, can be handed off to +one or more Protocol Servers running elsewhere, possibly operated with +different software and on different infrastructure. + +OCM-IP defines three integration modes: a provisioned mode, in which the +OCM Server pushes Share information to the Protocol Server over a signed +back channel; a self-contained mode, in which the Share information is +embedded in the signed access token itself, so that the Protocol Server +needs no per-share state and no inbound API at all; and an introspected +mode, in which the Protocol Server validates presented credentials +through a token introspection endpoint, restoring compatibility with +Receiving Servers that do not support token exchange. + +OCM-IP is a protocol between the Sending OCM Server and its Protocol +Servers only. The Receiving Server is not involved in, and does not +need to be aware of, this protocol: everything it observes is +indistinguishable from the Sending Server serving the access protocols +itself. For this reason, an OCM Sending Server MAY adopt a +different strategy to interoperate with Protocol Servers, including +e.g. establishing trust via shared keys, without compromising +compliance with the OCM protocol. + + + + + + + +
+ + + + + + +
Introduction + +Open Cloud Mesh [OCM] is a server federation protocol used to notify a +Receiving Party that they have been granted access to some Resource. +OCM deliberately handles interactions only up to the point where the +Receiving Party is informed of their access; actual Resource access is +subsequently managed by other protocols, such as WebDAV [RFC4918], SSH, +or application-specific web protocols. + +In existing deployments, the Sending Server typically implements both +the OCM endpoints and all of the access protocols it offers. This +couples the federation logic to the storage and application logic, and +makes it hard to: + + + implement OCM as a small, auditable component in front of existing +infrastructure, + reuse a protocol implementation (for example a WebDAV server, an SFTP +server, or a computational notebook platform) across multiple OCM +deployments and vendors, + operate the access protocol on separate infrastructure from the OCM +Server, for example running a web application platform in a different +security domain than the file sync and share system. + + +This document defines the Open Cloud Mesh Integration Protocol (OCM-IP), +which decouples the two concerns. An OCM Server delegates the serving +of one or more access protocols to one or more Protocol Servers. The +OCM Server remains the single party that the rest of the federation +interacts with: it performs OCM API Discovery, receives and sends Share +Creation Notifications. The Protocol Server serves the actual Resource +access protocol, authorizing requests by independently verifying the +access tokens issued by the OCM Server. + +Two properties of [OCM] make this delegation possible without sharing +secrets between the OCM Server and the Protocol Server: + + + The OCM Server publishes its public keys at the Well-Known [RFC8615] +path /.well-known/jwks.json in JWK format [RFC7517], and signs its +server-to-server requests using HTTP Message Signatures [RFC9421]. + The Code Flow lets the Receiving Server exchange the sharedSecret +for an access token whose format [OCM] leaves entirely at the issuer's +discretion. + + +OCM-IP uses that freedom: it requires the OCM Server to issue these +access tokens as JWTs conforming to the JWT Profile for OAuth 2.0 Access +Tokens [RFC9068], signed with the OCM Server's published key. Any +party, including a third-party service, can then verify such a token +without contacting the OCM Server on a per-request basis. + +OCM-IP defines three integration modes that share a common authorization +core: + + + Provisioned integration: a small back-channel API through which the +OCM Server provisions and revokes Share records on the Protocol Server, +ahead of any Resource access. + Self-contained integration: the OCM Server embeds the Share +information in the access token itself, as an additional JWT claim. The +Protocol Server keeps no per-share state and exposes no inbound API; +everything it needs arrives inside the signed token. + Introspected integration: the Protocol Server validates each presented +credential through a token introspection endpoint [RFC7662] at the OCM +Server. This is the compatibility mode: it is the only one that can +serve Receiving Servers that directly presents the legacy sharedSecret +instead of performing the token exchange. + + +In all modes, normative rules define how the Protocol Server authorizes +front-channel Resource access using the OCM credentials. + +This document is intended to be useful to anyone who wants to write a +reusable server component for use with OCM, such that one implementation +of, say, a notebook platform integration can be used unchanged behind +OCM Servers from different vendors. + +
+
Terms + +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 reuses the following terms as defined in [OCM]: +Resource, Share, Share Creation Notification, Sending Server, +Receiving Server, Sending Party, Receiving Party, OCM Address, +OCM Server, and Code Flow. + +In addition, we define: + + + Protocol Server - A server that serves one or more access +protocols (e.g., WebDAV, SSH, a web application) for Resources shared +through an OCM Server, on that OCM Server's behalf. + Integration API - The back-channel HTTP API exposed by a Protocol +Server, through which a paired OCM Server provisions and revokes Share +records. + Pairing - The out-of-band configuration step by which an OCM +Server and a Protocol Server are introduced to each other, establishing +mutual trust (see Pairing section). + Share Provisioning Request - A signed back-channel request from +the OCM Server to the Protocol Server, transferring the information the +Protocol Server needs in order to serve a Share. + Share Revocation Request - A signed back-channel request from the +OCM Server to the Protocol Server, instructing it to stop serving a +Share and release any associated resources. + Share Record - The Protocol Server's stored representation of a +provisioned Share, keyed by the pair (sender domain, providerId). + Provisioned Integration - The integration mode in which the OCM +Server transfers Share information to the Protocol Server over the back +channel, before any Resource access takes place. + Self-Contained Integration - The integration mode in which the +Share information travels inside the access token, in the ocm_ip +claim, and no back channel is used. + Introspected Integration - The integration mode in which the +Protocol Server validates a presented credential by querying a token +introspection endpoint [RFC7662] hosted by the OCM Server (or its +delegated Token Server). Defined for backwards compatibility with +Receiving Servers that do not support the Code Flow. + ocm_ip Claim - A JWT claim, defined by this document, whose value +is an object carrying the Share information a Protocol Server needs in +order to serve a Share in Self-Contained Integration. + Front Channel - The path through which Resource access requests +reach the Protocol Server, originating from the Receiving Server or from +the Receiving Party's user agent, carrying a credential issued by the +OCM Server: an access token or, in Introspected Integration, possibly +the legacy sharedSecret. + Back Channel - The direct, signed, server-to-server path between +the OCM Server and the Protocol Server, carrying the Integration API +requests. + + +
+
Architecture + +
Integration Modes + +An OCM Server that delegates protocol work takes on the Sending Server +role of [OCM] towards the federation. Towards its Protocol Servers it +uses one of three integration modes, chosen per pairing and per Share: + + + In Provisioned Integration, the OCM Server acts as a client of the +Protocol Server's Integration API: it pushes a Share Record over the +signed back channel before the Share is created, and revokes it when the +Share ends. This mode supports the full Share lifecycle, including +prompt revocation and the release of per-share resources, and is the +only mode that supports SSH. + In Self-Contained Integration, there is no back channel at all: +the OCM Server embeds the Share information in the access token, in the +ocm_ip claim. The Protocol Server is stateless with respect to +Shares, which makes this mode attractive for simple gateways (for +example a token-verifying WebDAV front end to an existing storage +system), at the cost of revocation latency bounded only by token +lifetime (see Lifecycle). + In Introspected Integration, the Protocol Server validates each +presented credential by querying a token introspection endpoint +[RFC7662] at the OCM Server (or its delegated Token Server). This is a +compatibility mode: it is the only mode that can serve Receiving Servers +that do not support the exchange-token capability and therefore +present the legacy sharedSecret directly on the front channel. It +reintroduces a per-request dependency on the OCM Server, which the other +two modes avoid. + + +A Protocol Server MAY support any combination of the modes. Protocols +that allocate per-share resources or sessions (for example a notebook +platform that starts a computational session per Share) SHOULD use +Provisioned Integration, since Self-Contained Integration provides no +signal to release such resources. Introspected Integration SHOULD be +used only where it is needed, namely for Shares towards Receiving +Servers that cannot perform the token exchange; where the Code Flow is +available, the other two modes avoid the per-request coupling. + +
+
Provisioned Integration Flow + +
| | | | + | | 2. Share | | | + | | Provisioning | | | + | | Request | | | + | |------------->| | | + | | 3. 201 | | | + | |<-------------| | | + | | 4. Share Creation | | + | | Notification | | + | |--------------------------->| | + | | | | 5. notify | + | | | |----------->| + | | 6. Token Request | | + | | (Code Flow) | | + | |<---------------------------| | + | | 7. access_token (JWT) | | + | |--------------------------->| | + | | | 8. Resource access | + | | | with access_token | + | | |<------------+------------| + | | | 9. verify token against | + | | | OCM Server's JWKS, | + | | | look up Share Record, | + | | | serve the protocol | +]]>
+ +The numbered steps are: + + + The Sending Party makes a Sending Gesture to the OCM Server, as +described in [OCM]. + The OCM Server sends a Share Provisioning Request over the back +channel to the Protocol Server responsible for (one or more of) the +protocols offered in the Share. + The Protocol Server verifies the request signature, stores the Share +Record and acknowledges. + The OCM Server sends the Share Creation Notification to the Receiving +Server, exactly as specified in [OCM]. The protocol endpoints +advertised in the notification point (directly or via a reverse proxy) +at the Protocol Server. + The Receiving Server notifies the Receiving Party as usual. + The Receiving Server exchanges the sharedSecret for an access token +at the OCM Server's tokenEndPoint, using the Code Flow of [OCM]. + The OCM Server issues a signed JWT access token whose client_id +claim equals the providerId of the Share provisioned in step 2. + The Receiving Server (or the Receiving Party's user agent, depending +on the access protocol) presents the access token to the Protocol +Server. + The Protocol Server verifies the token against the OCM Server's +published keys, looks up the Share Record by (issuer domain, +client_id), cross-checks the identities bound into the token, and +serves the protocol-specific Resource access. + + +
+
Self-Contained Integration Flow + +
| | | | + | | 2. Share Creation | | + | | Notification | | + | |--------------------------->| | + | | | | 3. notify | + | | | |----------->| + | | 4. Token Request | | + | | (Code Flow) | | + | |<---------------------------| | + | | 5. access_token (JWT | | + | | with ocm_ip claim) | | + | |--------------------------->| | + | | | 6. Resource access | + | | | with access_token | + | | |<------------+------------| + | | | 7. verify token against | + | | | OCM Server's JWKS, | + | | | check issuer pairing, | + | | | serve per the ocm_ip | + | | | claim | +]]>
+ +The flow is the OCM flow unchanged, except that the token issued in step +5 carries the ocm_ip claim, and that the protocol endpoints advertised +in step 2 point at the Protocol Server. The Protocol Server is not +contacted before Resource access, holds no Share Records, and learns of +each Share only when the first request for it arrives. + +
+
Introspected Integration Flow + +
| | | | + | | 2. Share Creation | | + | | Notification | | + | | (legacy sharedSecret) | | + | |--------------------------->| | + | | | | 3. notify | + | | | |----------->| + | | | 4. Resource access | + | | | with sharedSecret | + | | |<------------+------------| + | | 5. Token Introspection | | + | | Request (signed) | | + | |<-------------| | | + | | 6. active + Share | | + | | information | | + | |------------->| | | + | | | 7. serve per the | + | | | introspection | + | | | response | +]]>
+ +The Share Creation Notification in step 2 is a legacy [OCM] share: it +carries the sharedSecret and does not include must-exchange-token, +because the Receiving Server cannot honor it. The Protocol Server +validates the presented credential by introspecting it at the OCM Server +(steps 5 and 6) and authorizes the request from the introspection +response. + +Introspected Integration composes with Provisioned Integration for the +same Share: in that case the introspection response identifies the +provisioned Share Record via client_id, and introspection replaces +only the credential validation, not the lifecycle handling. + +
+
Relationship to Open Cloud Mesh + +OCM-IP is layered strictly behind the Sending Server role of [OCM]: + + + The OCM Server remains the Discoverable Server. Protocol Servers MUST +NOT be required to expose /.well-known/ocm. + The OCM Server remains the recipient of Invite Acceptance Requests, +Share Acceptance Notifications and all other OCM endpoints. + The OCM Server remains the OAuth Authorization Server towards the +federation: access tokens are issued under its identity and verified +against the keys it publishes. The hosting of the tokenEndPoint +itself MAY however be delegated as well; see the note below. + The Protocol Server takes on (part of) the OAuth Resource Server +function: it is the party that ultimately accepts access tokens in +exchange for Resource access. + + +Shares whose protocols are served by a Protocol Server MUST use the Code +Flow of [OCM] unless the Share uses Introspected Integration: the OCM +Server MUST include must-exchange-token in the requirements of every +protocol entry that a Protocol Server serves in Provisioned or +Self-Contained Integration. Legacy shared-secret access cannot be +verified by a Protocol Server on its own, because the long-lived secret +is deliberately never replicated to it; Introspected Integration exists +precisely to close this gap for Receiving Servers that cannot perform +the token exchange, at the cost of a per-request callback (see Token +Introspection and Security Considerations). + +
Note: Delegating the Token Endpoint + +This note is non-normative. + +The tokenEndPoint is advertised as an absolute URL in the OCM Server's +discovery document, and nothing in [OCM] requires it to be served from +the OCM Server's own host. Token issuance can therefore, in principle, +be delegated to a separate Token Server, in the same spirit as the rest +of this document: + + + The Token Server holds its own signing keypair, and the OCM Server +publishes the public key in its own /.well-known/jwks.json under a +kid in its own domain. The iss and kid rules of this document +(see Token Issuance by the OCM Server) are then satisfied without any +private key leaving the Token Server, and token +verification by Receiving Servers and Protocol Servers is unchanged. + The Token Server learns about Shares through a special case of the +back channel: a share preparation request, by which the OCM Server sends +the information needed for issuance (the parties, the providerId or +the ocm_ip contents, the expiration) and receives in response a +sharedSecret minted by the Token Server. The OCM Server forwards that +secret to the Receiving Server in the Share Creation Notification, +without needing to retain it. The code presented in the Code Flow is +thereby validated by the very server that minted it, and the secret is +never stored outside the Token Server. + + +In such a deployment the OCM Server is reduced to pure federation logic: +discovery, Share bookkeeping, notifications and invites, with both token +issuance and Resource access served elsewhere. The share preparation +request is identical to a request sent over the normal back channel, the +only difference being that the response from the Token Server includes +the sharedSecret. + +
+
+
The Transparency Requirement + +OCM-IP is purely a protocol between the Sending Server and the Protocol +Server. The Receiving Server MUST NOT be required to implement, or even +be aware of, OCM-IP. + +Concretely, everything observable by the Receiving Server and the +Receiving Party MUST be indistinguishable from a deployment in which the +Sending Server serves the access protocols itself: + + + The protocol endpoints advertised in OCM API Discovery and in Share +Creation Notifications are ordinary URIs (or host:port addresses for +SSH); whether they are served by the OCM Server, by a reverse proxy in +front of a Protocol Server, or by a Protocol Server on a different +hostname is invisible at the OCM layer. + Access tokens are obtained from the OCM Server's tokenEndPoint and +presented to the advertised protocol endpoint, exactly as specified in +[OCM]. + Errors returned by the Protocol Server on the front channel use the +semantics of the access protocol concerned. + + +A consequence of this requirement is that no OCM capability or criterium +is defined for OCM-IP: there is nothing for a remote peer to discover. + +
+
Topologies + +The mapping between OCM Servers and Protocol Servers is many-to-many: + + + An OCM Server MAY pair with multiple Protocol Servers, for example one +serving WebDAV and another serving a web application platform, and MAY +provision the same Share to more than one of them when the Share offers +multiple protocols. + A Protocol Server MAY be paired with multiple OCM Servers. Share +Records are keyed by the pair (sender domain, providerId), so records +provisioned by different OCM Servers cannot collide and access tokens +issued by one OCM Server cannot address records provisioned by another. +In Self-Contained Integration the same isolation holds trivially: a +token is honored only if its issuer is paired, and grants only what its +own claims describe. + + +
+
+
Pairing + +Before a Protocol Server serves any Share, the OCM Server and the +Protocol Server MUST be paired. Pairing is performed out of band, +typically by the operators of the two systems, and consists of at least: + + + On the OCM Server: which protocols and resource types the Protocol +Server is responsible for, which integration mode(s) to use, and, for +Provisioned Integration, the base URL of the Integration API of the +Protocol Server (referred to as {integrationAPI} below). For +Introspected Integration, additionally the domain of the Protocol +Server, used to verify its introspection requests. + On the Protocol Server: the domain(s) of the paired OCM Server(s) and +the integration mode(s) permitted for each. The Protocol Server MUST +maintain an allowlist of paired OCM Server domains, MUST reject +Integration API requests whose sender is not on that allowlist, and MUST +NOT honor the ocm_ip claim of tokens whose issuer is not paired for +Self-Contained Integration. For Introspected Integration, additionally +the URL of the introspection endpoint (referred to as +{introspectionEndPoint} below). + + +No shared secret is exchanged during pairing. All trust on the back +channel derives from HTTP Message Signatures [RFC9421] made with the OCM +Server's signatory key, verified against the keys the OCM Server +publishes at https://<domain>/.well-known/jwks.json [RFC7517], as +specified in [OCM]. All trust on the front channel derives from the JWT +signatures on the access tokens, verified against the same published +keys. Trust in introspection requests derives, symmetrically, from HTTP +Message Signatures made with the Protocol Server's key, published at the +Protocol Server's own /.well-known/jwks.json. + +The Protocol Server consequently does not need a signing keypair of its +own to implement this protocol, unless it uses Introspected Integration, +which requires it to sign its introspection requests (see Token +Introspection). + +
+
Integration API + +The Integration API is the back channel of Provisioned Integration. A +Protocol Server that supports only Self-Contained Integration does not +expose it, and an OCM Server never calls it for self-contained Shares. + +
General Requirements + +All Integration API requests: + + + MUST be made over TLS (implementations MAY fall back to plain HTTP in +testing setups only), + MUST use the HTTP POST method with application/json as the +Content-Type request header, + MUST be signed with an HTTP Message Signature [RFC9421] carrying the +label ocm, following the same rules as server-to-server requests in +[OCM]: the signature MUST cover at least @method, @target-uri, +content-digest, content-length and date, MUST include the +created parameter, and MUST be made with an asymmetric algorithm using +a key advertised in the OCM Server's /.well-known/jwks.json. + + +On receipt of an Integration API request, the Protocol Server: + + + MUST parse the sender field from the request body and derive the +sender domain from the part after the last @ sign. + MUST verify that the sender domain is on its allowlist of paired OCM +Servers, and reject the request with HTTP status 401 otherwise. + MUST verify the ocm-labeled signature against the JWKS of the +sender domain, following the verification rules of [OCM] (single ocm +label, required covered components, content-digest match [RFC9530], +created +within a freshness window, keyid domain equal to the sender domain), +and reject the request with HTTP status 401 on any failure. + + +Note that, unlike the Share Creation Notification of [OCM], where the +verification key is discovered from the sender field of an arbitrary +remote server, the allowlist check in step 2 happens before any key +fetching: a Protocol Server never fetches keys from, or processes +payloads of, servers it is not paired with. + +If the Protocol Server is deployed behind a TLS-terminating reverse +proxy, it MUST reconstruct the @target-uri that the OCM Server signed +(i.e., the public URL) when verifying signatures, for example from +forwarding headers set by the proxy. + +
+
Share Provisioning Request + +To provision a Share, the OCM Server MUST send a Share Provisioning +Request: + + + to {integrationAPI}/shares, + before sending the corresponding Share Creation Notification to the +Receiving Server (see Lifecycle below), + with a request body containing a JSON document as described below. + + +
Fields + +The request body is the Share Creation Notification object of [OCM] that +the OCM Server intends to send to the Receiving Server, with one +transformation applied: every sharedSecret field, in every protocol +entry, MUST be removed. The Protocol Server never receives, stores, or +needs any OCM secret. + +The fields used by the Protocol Server are thus: + + + REQUIRED sender (string) - OCM Address of the user that creates the +Share. The domain part identifies the paired OCM Server and selects the +verification keys, as described above. + REQUIRED owner (string) - OCM Address of the user that owns the +Resource. Used for identity binding on the front channel. + REQUIRED shareWith (string) - OCM Address of the Receiving Party. +Used for identity binding on the front channel. + REQUIRED providerId (string) - as in [OCM]; opaque identifier of the +Share at the OCM Server, unique per Share. It keys the Share Record and +links the back channel to the front channel (see below). + REQUIRED shareType (string) - as in [OCM]. + REQUIRED resourceType (string) - as in [OCM]. + REQUIRED protocol (object) - as in [OCM], transformed as described +above. The protocol entries carry the protocol-specific information the +Protocol Server needs to serve the Share (for example the webdav +entry's uri and permissions, or the webapp entry's viewMode). + OPTIONAL name, description, ownerDisplayName, +senderDisplayName, expiration - as in [OCM]; informational, except +expiration, which the Protocol Server SHOULD honor (see Lifecycle). + + +Additional fields from the Share Creation Notification MAY be present +and MUST be ignored if not understood. + +
+
The providerId + +The providerId is the link between the back channel and the front +channel, and the following rules apply: + + + [OCM] guarantees that the providerId is unique per Share, so the +pair (sender domain, providerId) identifies exactly one Share Record. + The OCM Server MUST set the client_id claim of every access token it +issues for this Share (via its tokenEndPoint) to exactly the +providerId. This constrains a value that the token profile of this +document (see Token Issuance by the OCM Server) otherwise leaves at the +OCM Server's discretion. + The providerId is an identifier, not a credential: the Receiving +Server learns it from the Share Creation Notification anyway. +Possession of a providerId MUST NOT grant any access by itself; all +front channel authorization derives from the verified access token. +Consequently, the providerId does not need to be unguessable, and it +MAY appear in URLs and logs. + + +
+
Response + +On success the Protocol Server MUST respond with HTTP status 201 and a +JSON object with the following fields: + + + OPTIONAL status (string) - e.g. "stored". + OPTIONAL protocol (object) - protocol details allocated by the +Protocol Server for this Share, in the same format as the protocol +object of [OCM]. + + +When the response contains a protocol object, the OCM Server SHOULD +use its field values (for example, a per-share uri allocated by the +Protocol Server) when constructing the corresponding protocol entries of +the outbound Share Creation Notification, in place of statically +configured values from the pairing. This allows a Protocol Server to +allocate endpoints dynamically, per Share. + +Two restrictions apply to the response protocol object: + + + It MUST NOT contain sharedSecret fields, and an OCM Server MUST +ignore any sharedSecret found in a Share Provisioning Response. +(Delegated token issuance is the exception: the share preparation +request is this same request sent to a Token Server, whose response +legitimately carries the sharedSecret it minted; see the note on +delegating the token endpoint.) + The OCM Server MUST NOT take permissions from the response: the +Share's permissions are decided by the Sending Party and the OCM Server, +never by the Protocol Server. + + +Fields in the response protocol object that the OCM Server does not +understand MUST be ignored. + +A Share Provisioning Request for a (sender domain, providerId) pair that +already has a Share Record MUST replace the existing record and respond +with HTTP status 201. This makes provisioning idempotent and gives the +OCM Server a way to update a Share (for example after a permissions +change) by re-provisioning it. + +Error responses: + + + 400 - the request body is not valid JSON, or a required field is +missing or malformed. + 401 - the signature is missing, malformed, stale or invalid, or the +sender domain is not on the allowlist of paired OCM Servers. + 503 - the Protocol Server is temporarily unable to provision the +Share. + + +
+
+
Share Revocation Request + +When a Share is deleted, expires, is declined by the Receiving Party, or +access is otherwise withdrawn, the OCM Server SHOULD send a Share +Revocation Request: + + + to {integrationAPI}/revoke, + with a request body containing a JSON document with the following +fields: + REQUIRED sender (string) - an OCM Address whose domain part +identifies the paired OCM Server, subject to the same allowlist and +signature checks as all Integration API requests. + REQUIRED providerId (string) - the providerId of the Share to +revoke. + + +On receipt of a valid Share Revocation Request, the Protocol Server MUST +stop serving the identified Share, MUST delete the Share Record, and +SHOULD release any resources associated with it (for example, stopping a +computational session that was started for the Share, or invalidating +local sessions derived from its access tokens). + +
Response + +Revocation MUST be idempotent: if no Share Record exists for the given +(sender domain, providerId), the Protocol Server MUST respond with HTTP +status 200, so that the OCM Server can treat revocation as +fire-and-forget. This document defines one OPTIONAL response field: + + + OPTIONAL status (string) - e.g. "revoked" when a record was found +and revoked, "gone" when there was nothing to revoke. + + +Error responses are as for Share Provisioning. + +
+
+
Liveness + +A Protocol Server SHOULD respond to a GET request to {integrationAPI} +(or {integrationAPI}/) with HTTP status 200 and a JSON object, so that +operators and OCM Servers can verify reachability of the Integration +API. The contents of the object are not specified. + +
+
+
Token Introspection + +Token introspection is the credential validation path of Introspected +Integration. The introspection endpoint is hosted by the OCM Server or, +when token issuance is delegated, by its Token Server; its URL, +{introspectionEndPoint}, is exchanged during pairing. It is not +advertised in the OCM discovery document: like the Integration API, it +is invisible to the federation. + +Note that a legacy credential is opaque and carries no issuer +information, so the Protocol Server has no way to determine which paired +OCM Server to introspect against; Introspected Integration therefore +cannot work in multi-tenant deployments, where one Protocol Server +serves more than one OCM Server through the same protocol endpoint. + +
Request + +To validate a presented credential, the Protocol Server sends an HTTP +POST request to {introspectionEndPoint} as specified by [RFC7662]: the +request body is application/x-www-form-urlencoded with a token +parameter carrying the credential exactly as presented on the front +channel. The credential MAY be a legacy sharedSecret or a JWT access +token; the endpoint MUST accept any credential that is valid for a Share +at this OCM Server. + +The request MUST be made over TLS and MUST be signed with an HTTP +Message Signature [RFC9421] carrying the label ocm, with the same +covered components and created rules as Integration API requests. The +keyid MUST identify a key in the Protocol Server's own JWKS, published +at https://<protocol-server-domain>/.well-known/jwks.json [RFC7517]. +The introspection endpoint MUST verify that the keyid domain belongs +to a paired Protocol Server and MUST verify the signature against that +domain's JWKS before evaluating the credential; unauthenticated or +unpaired requests MUST be rejected without revealing whether the +presented credential is valid. This authentication requirement is what +keeps the endpoint from acting as a credential-validity oracle (Section +4 of [RFC7662]). + +
+
Response + +The response is an [RFC7662] introspection response. For an unknown, +expired or revoked credential the endpoint MUST respond with {"active": +false} and no other members. For a valid credential the response +object MUST contain: + + + active (boolean) - true. + iss, sub, aud (strings) - with the claim semantics this document +defines for access tokens (see Token Issuance by the OCM Server). + exp (integer) - for a JWT, the token's own exp; for a legacy +sharedSecret, the time until which the Protocol Server may rely on +this response. The endpoint MUST set a short horizon (on the order of +minutes), since exp also bounds revocation latency. + client_id (string) - the Share's providerId, when the Share is +provisioned to the calling Protocol Server. + ocm_ip (object) - the Share information as defined for the ocm_ip +claim, when the Share is not provisioned to the calling Protocol Server. + + +The Protocol Server uses exactly one of these: a client_id naming a +Share Record, or the ocm_ip member, as described in Token +Verification. + +The Protocol Server MAY cache a positive response until its exp and +MUST NOT rely on it beyond that. Negative responses SHOULD NOT be +cached for more than a brief interval. + +
+
+
Front Channel: Resource Access + +
Token Issuance by the OCM Server + +Token issuance follows the Code Flow of [OCM]: the Receiving Server +exchanges the sharedSecret from the Share Creation Notification for an +access token at the OCM Server's tokenEndPoint. [OCM] treats the +issued access_token as an opaque bearer credential and leaves its +format at the issuer's discretion. This document profiles that format. + +For every Share in Provisioned or Self-Contained Integration, the +access_token MUST be a JWT conforming to the JWT Profile for OAuth 2.0 +Access Tokens [RFC9068]. The JOSE header MUST include typ with the +value set to at+jwt and MUST include a kid parameter identifying the +OCM Server's signatory key advertised in /.well-known/jwks.json, and +MUST NOT use none as the alg. The JWT MUST be signed with the +private key corresponding to that signatory key, allowing anyone with +access to the corresponding public key, including a Protocol Server, to +verify the token independently. The expires_in value of the token +response MUST agree with the exp claim. Receiving Servers are +unaffected: they continue to treat the token as opaque, per [OCM]. + +The JWT Claims Set MUST include the claims required by [RFC9068], with +the following OCM-specific semantics, on which the Protocol Server +relies: + + + iss - the Sending Server identifier, derived from the scheme and +authority of the signatory keyId. + sub - the Share owner on the Sending Server. + aud - the OCM principal authorized by the token, i.e. the +shareWith value of the Share. Per Section 4.1.3 of [RFC7519] the +interpretation of audience values is application-specific, and this +document defines that interpretation. + client_id - as defined in Section 4.3 of [RFC8693], which forwards +to Section 2.2 of [RFC6749]. Verifiers MUST NOT assume a particular +size or format beyond what this document specifies per integration +mode. + iat, exp, jti - as in [RFC9068]. + + +Further requirements apply per integration mode. + +For a Share in Provisioned Integration: + + + The client_id claim MUST equal the providerId of the Share. + The token MUST NOT carry the ocm_ip claim. Mixing the modes for a +single Share would allow a self-contained token to outlive the +revocation of the Share Record (see Security Considerations). + + +For a Share in Self-Contained Integration: + + + The token MUST carry the ocm_ip claim described in the next section. + The exp claim MUST NOT be later than the Share's expiration, when +the Share has one. + The token SHOULD be short-lived: the RECOMMENDED lifetime is on the +order of minutes or for special use-cases, hours, relying on the +Receiving Server to re-exchange the sharedSecret for a fresh token per +[OCM]. Because no revocation signal exists in this mode, the remaining +lifetime of the longest-lived valid token is exactly how long access +survives the end of the Share. + Once the Share ends, the OCM Server MUST NOT issue further tokens for +it. This holds in all modes, but in Self-Contained Integration it is +the only revocation mechanism. + + +For a Share in Introspected Integration, no additional issuance +requirements apply. Typically no token is issued at all, since this +mode serves Receiving Servers that present the legacy sharedSecret +directly. Should such a Share nevertheless be exchanged for tokens, the +Protocol Server can validate those tokens through the same introspection +endpoint. + +
+
The ocm_ip Claim + +The value of the ocm_ip claim is a JSON object carrying the Share +information that the Share Provisioning Request carries in Provisioned +Integration. The Share's parties are deliberately not part of the +claim: the owner and the Receiving Party are already bound by the sub, +iss and aud claims of the enclosing token. + +Fields: + + + REQUIRED protocol (object) - as the protocol object of [OCM], +restricted to the protocol entries this token grants access to. It MUST +NOT contain sharedSecret fields. + REQUIRED providerId (string) - as in [OCM]; opaque identifier of the +Share at the OCM Server, useful for logging and correlation. + REQUIRED resourceType (string) - as in [OCM]. + OPTIONAL name (string) - as in [OCM]. + OPTIONAL shareType (string) - as in [OCM]. + OPTIONAL expiration (integer) - as in [OCM]. + + +Fields in the ocm_ip claim that the Protocol Server does not +understand MUST be ignored. + +
+
Token Verification by the Protocol Server + +When a front-channel request presents a credential, the Protocol Server +MUST authorize it as follows: + + + If the credential parses as a JWT, extract the iss claim without +trusting it; reject the credential if iss is missing or is not an +https URL, and continue with step 2. If it does not parse as a JWT, +or when the Protocol Server prefers introspection over local +verification, validate the credential through Token Introspection +instead: an active response supplies the fields (iss, sub, aud, +exp, client_id, ocm_ip) used in steps 4 to 6, and steps 2 and 3 +are skipped; an inactive response means the request is rejected. + Resolve the signing key: fetch (or use a cached copy of) the JWKS at +https://<iss-host>/.well-known/jwks.json and select the key matching +the token's kid header parameter. + Verify the token signature and validity per [RFC9068]: the algorithm +MUST be an asymmetric algorithm matching the key, MUST NOT be none, +and the exp claim MUST be in the future. The claims iss, sub, +aud, exp and client_id MUST all be present. + Determine the integration mode: + + If a Share Record exists for the pair (host part of iss, +client_id claim), the token is authorized against that record +(Provisioned Integration). Any ocm_ip claim in the token MUST be +ignored. + Otherwise, if the verified token carries an ocm_ip claim and the +host part of iss is paired for Self-Contained Integration, or the +introspection response carries an ocm_ip member, the credential is +authorized against those claims. + Otherwise, reject the request. Because Share Records only come +into existence through signed back-channel requests from paired OCM +Servers, the ocm_ip claim is only honored for paired issuers, and +introspection only ever consults paired endpoints, credentials from +unrelated issuers, however validly signed, grant nothing. + + Perform identity binding (next section). + Serve the request according to the protocol entry of the Share Record +or of the ocm_ip claim or member, honoring its permissions (e.g. +protocol.webdav.permissions), its expiration if present, and any +protocol-specific restrictions. + + +The token's exp claim is authoritative for token lifetime. Any expiry +hint delivered alongside the token on the front channel (such as the +access_token_ttl form field used by WOPI-style web applications) MUST +agree with the exp claim, otherwise the access MUST be rejected. + +The Protocol Server MAY cache JWKS documents. It SHOULD bound the cache +lifetime so that key rotation and key revocation at the OCM Server take +effect within a reasonable time. + +
+
Identity Binding + +In Provisioned Integration, a valid signature and a matching Share +Record are not sufficient: the token MUST also be bound to the +identities stored in the record. The Protocol Server MUST verify that: + + + the OCM Address formed as <sub>@<iss-host> equals the Share Record's +owner, and + the aud claim equals the Share Record's shareWith. + + +Comparison of OCM Addresses SHOULD be performed after canonicalising the +host part (lowercasing, removing any stray scheme prefix or trailing +slash); the identifier part is opaque and MUST be compared byte for +byte. + +These checks ensure that an access token can only be used for the exact +Share it was issued for: a token legitimately issued to one Receiving +Party for one Resource cannot be replayed against a Share Record +involving any other party or Resource, even at the same Protocol Server +and from the same OCM Server. The same checks apply when the fields +come from an introspection response that names a Share Record via +client_id. + +In Self-Contained Integration, and when serving from the ocm_ip member +of an introspection response, there is no stored record to compare +against: the credential itself is the authority, and the owner and the +Receiving Party are read directly from <sub>@<iss-host> and aud. +The cross-checks above therefore do not apply; what remains is to +enforce the scope of the ocm_ip claim (protocol entries, permissions, +expiration) and, where the protocol concerned authenticates the +Receiving Party, to derive that identity from aud using the same +canonicalisation rules. + +
+
Token Presentation per Protocol + +How the access token reaches the Protocol Server depends on the access +protocol, and follows [OCM] and its protocol-specific companion +specifications. Non-normative summary: + + + webdav - the Receiving Server acts as the API client and presents +the token in the Authorization: Bearer header of its WebDAV requests +to the advertised webdav endpoint. + webapp - the Receiving Server delivers the token to the Receiving +Party's user agent, which presents it to the advertised webapp +endpoint via a form POST (access_token field), keeping the token out +of URLs. The Protocol Server typically responds by establishing a +session (e.g. a cookie scoped to the application) and serving the +application. + ssh - SSH access is authenticated with the recipient's public key +per [OCM] rather than with a bearer token. An SSH/SFTP Protocol Server +uses the Share Provisioning Request to learn which key material and +paths to authorize, and the Share Revocation Request to withdraw that +authorization. The token verification rules of this section do not +apply to the SSH data channel itself, and Self-Contained Integration is +consequently not applicable to ssh: there is no token presentation +through which an ocm_ip claim could travel. + + +
+
+
Lifecycle + +
Ordering + +In Provisioned Integration, the OCM Server MUST send the Share +Provisioning Request, and receive a success response, before sending the +Share Creation Notification to the Receiving Server. If provisioning +fails, the OCM Server MUST NOT create the Share: otherwise the Receiving +Party would be notified of a Share whose Resource access cannot work. + +
+
Revocation and Expiration + +The OCM Server SHOULD send a Share Revocation Request whenever a Share +ends, whatever the cause: unshared by the Sending Party, declined by the +Receiving Party (e.g. on receipt of a SHARE_DECLINED notification), or +administratively removed. + +Revocation is deliberately fire-and-forget: because it is idempotent on +the Protocol Server side, the OCM Server MAY retry it at any time, and a +failure to deliver it MUST NOT block the unshare operation on the OCM +Server. + +The Protocol Server SHOULD apply its own bounds on Share Record lifetime +as a backstop against missed revocations: + + + If the provisioned Share carries an expiration, the Protocol Server +SHOULD stop serving the Share at that time. + The Protocol Server MAY additionally expire Share Records after an +implementation-defined maximum lifetime; an OCM Server can always +re-provision (idempotently) to extend it. + + +Note that token expiry alone already limits the damage of a missed +revocation on bearer-token protocols: once the OCM Server stops issuing +fresh tokens for a Share, access ends when the last issued token +expires. + +
+
Lifecycle in Self-Contained Integration + +Self-Contained Integration has no provisioning step and no revocation +push. The Share's lifecycle is enforced entirely at token issuance: + + + The OCM Server MUST stop issuing tokens for a Share when it ends, +whatever the cause: unshared by the Sending Party, declined by the +Receiving Party, expired, or administratively removed. + Until the last issued token expires, the Protocol Server will continue +to honor it. Revocation latency is therefore bounded by the maximum +token lifetime, which is why the issuance rules require short-lived +tokens in this mode. + + +Because the Protocol Server keeps no per-share state, there is nothing +for it to expire or reap. Protocols that do allocate per-share state +are steered to Provisioned Integration (see Integration Modes); a +Protocol Server that nevertheless creates transient state in this mode +(such as login sessions) SHOULD bound its lifetime independently of the +tokens that created it. + +
+
Lifecycle in Introspected Integration + +Introspected Integration needs neither provisioning nor a revocation +push for credential validity: every authorization consults the OCM +Server, modulo response caching, so a revoked or expired Share stops +being served as soon as cached introspection responses expire. +Revocation latency is bounded by the exp horizon of the responses, +which the introspection endpoint MUST keep short (see Token +Introspection). + +Note that introspection only validates credentials. If the Protocol +Server allocates per-share resources, it still needs the Share +Revocation Request of Provisioned Integration to release them, which is +one reason the two modes compose. + +
+
+
Security Considerations + +
No Secret Replication + +A central design goal of OCM-IP is that delegating protocol work does +not multiply the places where secrets live: + + + The sharedSecret of a Share is never stored on the Protocol Server: +it is stripped from the provisioning payload and absent from the +ocm_ip claim. A compromise of the Protocol Server therefore does not +leak credentials that could be exchanged for tokens at the OCM Server's +tokenEndPoint. (In Introspected Integration the Receiving Server does +present the legacy secret on the front channel; the Protocol Server +forwards it for introspection but MUST NOT retain it beyond the +request.) + No pairing secret exists; the back channel is authenticated by HTTP +Message Signatures against published keys, the front channel by JWT +signatures against the same keys, and introspection requests by HTTP +Message Signatures against the Protocol Server's published keys. + The Protocol Server holds no signing keys for this protocol, with two +exceptions: a Protocol Server using Introspected Integration holds a +request-signing key, published at its own /.well-known/jwks.json, and +a delegated Token Server (sketched in the note on delegating the token +endpoint) holds its own token-signing key, whose public part is +published through the OCM Server's JWKS. + + +The Protocol Server does handle bearer access tokens on the front +channel. These MUST be treated as confidential, MUST NOT be placed in +URLs, and SHOULD NOT be logged or persisted beyond their lifetime, +consistent with the Code Flow considerations of [OCM]. + +
+
Legacy Shared-Secret Access Requires Introspection + +Without the Code Flow, the only credential is the long-lived +sharedSecret itself, which the Receiving Server presents directly on +the front channel. The Protocol Server cannot verify it on its own: the +secret is deliberately never replicated to it. A Protocol Server MUST +NOT accept any front-channel credential other than a verifiable access +token or a credential validated through Token Introspection (or, for +SSH, the public-key mechanism of [OCM]). + +Introspected Integration therefore reintroduces, deliberately and only +for compatibility, the per-request coupling to the OCM Server that the +other modes remove. Deployments that do not need to serve legacy +Receiving Servers SHOULD NOT enable it. + +The introspection endpoint is a sensitive interface: left +unauthenticated, it would let anyone test guessed or stolen credentials +for validity (Section 4 of [RFC7662]). The signature and pairing +requirements of the Token Introspection section are therefore mandatory, +and the endpoint SHOULD additionally rate-limit failed introspections +per caller. + +
+
Trust Granted to the Paired OCM Server + +Pairing grants the OCM Server significant power over the Protocol +Server: every accepted Share Provisioning Request may consume resources +(storage, compute sessions) and instructs the Protocol Server to serve +content to third parties. The allowlist is therefore REQUIRED, and an +empty allowlist means the Integration API rejects all requests. + +The Protocol Server SHOULD apply resource limits per paired OCM Server +(number of Share Records, concurrent sessions, storage) so that a +misbehaving or compromised OCM Server cannot exhaust it. + +Conversely, the OCM Server places trust in the Protocol Server to +enforce the permissions and identity bindings of this document. +Operators SHOULD treat the Protocol Server as part of the Sending +Server's trusted computing base for the protocols it serves. + +
+
Self-Contained Tokens + +Self-Contained Integration shifts all authority into the token, with +three major consequences: + + + Revocation latency. An issued token cannot be withdrawn; it can only +expire. The normative cap on token lifetime in the issuance rules is +what keeps "unshare" meaningful in this mode, and implementations MUST +NOT relax it by issuing long-lived self-contained tokens for +convenience. + Metadata exposure. The ocm_ip claim is readable by anyone who holds +the token. For webapp Shares in particular, the token transits the +Receiving Party's user agent, so the embedded Share metadata is visible +to the Receiving Party. The OCM Server MUST NOT place information in +the ocm_ip claim that the Receiving Party is not entitled to see, and +SHOULD keep the claim minimal. + Allowlist is mandatory. In Provisioned Integration, pairing is +implicitly enforced by the existence of the Share Record. In +Self-Contained Integration the issuer allowlist is the only thing +standing between any internet-hosted JWKS and Resource access; the +requirement to check the token's issuer against the pairing allowlist +before honoring an ocm_ip MUST be enforced. + + +Provisioned and Self-Contained Integration MUST NOT be mixed for a +single Share. If a provisioned Share's tokens also carried ocm_ip +claims, a token issued before a Share Revocation Request would continue +to grant access through the self-contained path until it expired, +silently surviving the revocation. This is why the issuance rules +forbid the ocm_ip claim on tokens for provisioned Shares, and why +verification gives an existing Share Record precedence over the claim. +Introspected Integration, by contrast, composes safely with Provisioned +Integration: the introspection response names the Share Record via +client_id, and revocation of the record takes effect immediately. + +
+
Signature and Token Verification Considerations + +All the verification rules of [OCM] for HTTP Message Signatures apply to +the back channel, in particular: exactly one ocm-labeled signature, +required covered components, created freshness, keyid domain +matching the sender domain, and rejection of symmetric algorithms. Two +considerations deserve emphasis in the Protocol Server context: + + + Reverse proxies: when TLS terminates in front of the Protocol Server, +the internally observed URI differs from the signed @target-uri. The +Protocol Server MUST reconstruct the public URL for verification, and +MUST only trust forwarding headers set by its own proxy. + Issuer/key binding: on the front channel, the key used to verify a +token MUST be fetched from the JWKS of the token's own iss host, and +the Share Record lookup MUST use that same host. An implementation that +verifies against one domain's keys but looks up records under another's +would allow cross-tenant confusion on multi-tenant Protocol Servers. + + +
+
Denial of Service + +The Integration API performs the allowlist check before fetching any +keys, so unsolicited requests from arbitrary servers are rejected +without outbound traffic. Front-channel token verification does fetch +JWKS documents from token-asserted issuers; implementations SHOULD +rate-limit verification failures and SHOULD restrict JWKS fetching to +the domains of paired OCM Servers, since no unpaired issuer's credential +can ever be honored in any integration mode. In Introspected +Integration the Protocol Server additionally generates one introspection +request per uncached front-channel credential; implementations SHOULD +apply negative caching with a short lifetime so that a flood of invalid +credentials does not translate into a flood of introspection traffic +towards the OCM Server. + +
+
+
IANA Considerations + +
JSON Web Token Claims Registry + +The following claim is to be registered in the "JSON Web Token Claims" +registry (using the template from [RFC7519]): Claim Name: ocm_ip Claim +Description: Open Cloud Mesh Share information for self-contained +Protocol Server integration Change Controller: IETF Specification +Document(s): the present Draft, once in RFC form + +
+
OAuth Token Introspection Response Registry + +The following member is to be registered in the "OAuth Token +Introspection Response" registry established by [RFC7662]: Name: ocm_ip +Description: Open Cloud Mesh Share information for Protocol Server +integration Change Controller: IETF Specification Document(s): the +present Draft, once in RFC form + +No other IANA actions are required. Neither the Integration API nor the +introspection endpoint is exposed at a Well-Known URI; their locations +are exchanged during pairing. + +
+
+
Copying conditions + +The author(s) agree to grant third parties the irrevocable right to +copy, use and distribute the work, with or without modification, in any +medium, without royalty, provided that, unless separate permission is +granted, redistributed modified works do not contain misleading author, +version, name of work, or endorsement information. + +
+
References + +
Normative References + +[OCM] Lo Presti, G., de Jong, M.B., Baghbani, M. and Nordin, M. "Open +Cloud Mesh", Work +in Progress. + +[RFC2119] Bradner, S. "Key words for use in RFCs to Indicate +Requirement Levels", +March 1997. + +[RFC7517] Jones, M., "JSON Web Key (JWK)", May 2015. + +[RFC7519] Jones, M., Bradley, J., Sakimura, N., "JSON Web Token +(JWT)", May 2015. + +[RFC7662] Richer, J. (ed), "OAuth 2.0 Token Introspection", October 2015. + +[RFC8174] Leiba, B. "Ambiguity of Uppercase vs Lowercase in RFC 2119 +Key Words", May 2017. + +[RFC8615] Nottingham, M. "Well-Known Uniform Resource Identifiers +(URIs)", May 2019. + +[RFC9068] Bertocci, V., "JSON Web Token (JWT) Profile for OAuth 2.0 +Access Tokens", October +2021. + +[RFC9421] Backman, A., Richer, J. and Sporny, M. "HTTP Message +Signatures", February 2024. + +[RFC9530] Polli, R., Marwood, D., "Digest Fields", February 2024. + +
+
Informative References + +[RFC4918] Dusseault, L. M. "HTTP Extensions for Web Distributed +Authoring and Versioning", +June 2007. + +[RFC6749] Hardt, D. (ed), "The OAuth 2.0 Authorization Framework", October 2012. + +[RFC8693] Jones, M., Nadalin, A., Campbell, B., Bradley, J. and +Mortimore, C., "OAuth 2.0 Token Exchange", January 2020. + +
+
+
Appendix A: Examples + +The first set of examples shows Provisioned Integration: +cloud.example.org is the OCM Server and hub.example.org is a +Protocol Server running a computational notebook platform, paired with +cloud.example.org and serving the webapp protocol. Alice +(alice@cloud.example.org) shares a notebook with Bob +(bob@receiver.example.org). Self-Contained and Introspected +Integration examples follow at the end. + +
Share Provisioning Request + +The OCM Server pushes the Share to the Protocol Server before notifying +the Receiving Server. The body is the Share Creation Notification with +every sharedSecret removed (line breaks in the signature headers for +display purposes only): + +
+ +The Protocol Server stores the Share Record under (cloud.example.org, +7c084226-d9a1-11e6-bf26-cec0c932ce01) and responds: + +
+ +The OCM Server then sends the Share Creation Notification to +receiver.example.org per [OCM], with must-exchange-token in the +protocol requirements and with the webapp entry pointing at the +Protocol Server (and a fresh sharedSecret, which only the Receiving +Server learns). + +
+
Access Token + +When the Receiving Server performs the Code Flow at +https://cloud.example.org/ocm/token, the issued JWT carries the JOSE +header: + +
+ +and the Claims Set: + +
+ +
+
Front-Channel Access + +Bob's user agent form-POSTs the token to the advertised webapp +endpoint: + +
+ +The Protocol Server verifies the JWT against +https://cloud.example.org/.well-known/jwks.json, looks up the Share +Record by (cloud.example.org, +7c084226-d9a1-11e6-bf26-cec0c932ce01), checks that +alice@cloud.example.org equals the stored owner and that +bob@receiver.example.org equals the stored shareWith, and then +starts (or resumes) the notebook session for the Share. + +
+
Share Revocation Request + +When Alice unshares the notebook (body shown without the signature +headers, which are as in the provisioning example): + +
+ +
+ +A repeated revocation for the same providerId returns { "status": +"gone" } with HTTP status 200. + +
+
Self-Contained Integration + +dav.example.org is a stateless WebDAV gateway in front of an existing +storage system, paired with cloud.example.org for Self-Contained +Integration. No provisioning takes place; the gateway exposes no +Integration API and keeps no Share Records. Alice shares a folder with +Bob, and the OCM Server advertises a webdav endpoint at the gateway in +the Share Creation Notification. + +When the Receiving Server performs the Code Flow at +https://cloud.example.org/ocm/token, the issued JWT carries: + +
+ +Note the short lifetime (300 seconds): the Receiving Server re-exchanges +the sharedSecret at the tokenEndPoint for a fresh token before each +expiry, per [OCM], and unsharing takes effect within at most that +lifetime. + +The Receiving Server accesses the Resource directly: + +
+ +The gateway verifies the JWT against +https://cloud.example.org/.well-known/jwks.json, finds no Share Record +for (cloud.example.org, receiver.example.org), confirms that +cloud.example.org is paired for Self-Contained Integration, and serves +the PROPFIND read-only, scoped to the uri in the ocm_ip claim. + +
+
Introspected Integration + +legacy.example.com is a Receiving Server that does not support the +exchange-token capability. Alice shares the same kind of folder with +Carol (carol@legacy.example.com). The Share Creation Notification is +a legacy [OCM] share: the webdav entry points at dav.example.org and +carries a sharedSecret, with no must-exchange-token requirement. +dav.example.org is paired with cloud.example.org for Introspected +Integration and holds a request-signing key published at +https://dav.example.org/.well-known/jwks.json. + +The Receiving Server presents the secret directly, per the legacy +resource access flow of [OCM]: + +
+ +The credential does not parse as a JWT, so the gateway introspects it +(signature headers as in the provisioning example, but signed by the +gateway with keyid="dav.example.org#key1"): + +
+ +
+ +The gateway serves the PROPFIND read-only and MAY cache this response +until exp. When Alice unshares the folder, introspection starts +returning {"active": false}, and Carol's access ends as soon as the +cached response expires. + +
+
+
Changes + +This section collects the changes with respect to the previous version +in the IETF datatracker. It is meant to ease the review process and it +shall be removed when going to RFC last call. + +
Version 00 + + + Initial version. + + +
+
+
Acknowledgements + +This protocol generalizes a working integration between Nextcloud and +JupyterHub developed at SUNET, and builds directly on the Code Flow, JWT +access token, and HTTP Message Signature work in the Open Cloud Mesh +specification. Thanks to the OCM community for the discussions that +shaped the webapp sharing design this document extends, and in +particular to Enrique Pérez Arnaud and Matthias Kraus who helped shape +the format of this protocol. + +Work on this document has been funded by [Sovereign Tech Agency][sta] +through the Tech Fund, with a specific project. + +
+ + +
+ + + + + + + + + + + + + + +
+ diff --git a/IETF-OCM-MLS.xml b/IETF-OCM-MLS.xml new file mode 100644 index 0000000..1fe653c --- /dev/null +++ b/IETF-OCM-MLS.xml @@ -0,0 +1,2666 @@ + + + + + + + + + + +]> + + + + + 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. + +
+ + +
+ + + + + + + + + + + + + + +
+ diff --git a/IETF-OCM.xml b/IETF-OCM.xml index 6d3e078..95b20d0 100644 --- a/IETF-OCM.xml +++ b/IETF-OCM.xml @@ -1,6 +1,6 @@ - + - + Applications and Real-Time @@ -225,7 +225,7 @@ The identifier is an opaque, case-sensitive UTF-8 string. It is separated from the host by the last "@" in the OCM Address. It is possible to have multiple @-signs in a OCM-address, e.g. when an email address is the local part of the address like - nomen.nescio@example.org@ocm.example.org. + nomen.nescio@example.org@cloud.example.org. host is an IP literal encapsulated within square brackets, an IPv4 address in dotted decimal form, or a registered name as described in [RFC3986]. @@ -720,15 +720,11 @@ from it (the part after the last @ sign). Step 2: The Discovering Server SHOULD attempt OCM API Discovery via a HTTP GET request to https://<fqdn>/.well-known/ocm. Step 3: If that results in a valid HTTP response with a valid JSON -response body within reasonable time, go to step 7. -Step 4: If not, try a HTTP GET with https://<fqdn>/ocm-provider as -the URL instead. -Step 5: If that results in a valid HTTP response with a valid JSON -response body within reasonable time, go to step 7. -Step 6: If not, fail. Implementations MAY fallback to HTTP instead -of HTTPS in testing setups and retry steps 2-5, in particular when +response body within reasonable time, go to step 5. +Step 4: If not, fail. Implementations MAY fallback to HTTP instead +of HTTPS in testing setups and retry steps 2-3, in particular when an optional port is given in the address. -Step 7: The JSON response body is the data that was discovered. +Step 5: The JSON response body is the data that was discovered.
Fields @@ -769,39 +765,66 @@ of Resources and protocols is optional. Example:
+The protocols object distinguishes a server's role for each +protocol: a property named after the protocol (e.g. webdav, +webapp, ssh) advertises support for acting as a Sending +Server, while a property suffixed with -receive (e.g. +webdav-receive, webapp-receive, ssh-receive) advertises +support for acting as a Receiving Server. Fields: - webdav (string) - The top-level WebDAV [RFC4918] path at this endpoint. In order to access a Remote Resource, implementations SHOULD use this path as a prefix (see sharing examples). -- webapp (string) - The top-level path for web apps at this - endpoint. In order to access a remote web app, implementations - SHOULD use this path as a prefix (see sharing examples). +- webdav-receive (object) - Advertised by implementations that + support receiving WebDAV shares. It contains a uri property + whose value MUST be either "absolute" or "relative", + signalling the URI format this endpoint accepts. Note that + older implementations MAY not support this property. +- webapp (object) - Advertised, as an empty object, by + implementations that support sending WebApp shares. +- webapp-receive (object) - Advertised by implementations that + support receiving WebApp shares. It contains a targets + array listing the ways this endpoint is able to present a + WebApp share to the user. A subset of: + - blank - the endpoint can open the URI in a top-level + browsing context, such as a new window or tab, or a full page + navigation in the current window. + - iframe - the endpoint can embed the URI in an iframe + within its own UI, when the Sending Server allows framing + by this receiver. - ssh (string) - The top-level address in the form host:port of an endpoint that supports ssh and scp with a public/private key based authentication. +- ssh-receive (object) - Advertised, as an empty object, by + implementations that support receiving SSH shares. - Any additional protocol supported for this Resource type MAY be advertised here, where the value MAY correspond to - a top-level URI to be used for that protocol. + a top-level URI to be used for that protocol. Similarly, + additional receiving capabilities for custom protocols SHOULD + be advertised using a -receive suffixed property. OPTIONAL: capabilities (array of string) - The optional capabilities supported by this OCM Server. As implementations MUST accept Share Creation Notifications to be compliant, it is not necessary to expose that as a capability. -Example: ["exchange-token", "webdav-uri"]. The array MAY +Example: ["exchange-token", "protocol-object"]. The array MAY include one or more of the following items: "enforce-mfa" - to indicate that this OCM Server can apply a Sending Server's MFA requirements for a Share on their behalf. - "exchange-token" - to indicate that this OCM Server exposes a -[RFC6749]-compliant endpoint, which allows to exchange a secret -received in the protocol properties of a Share Creation Notification -for a short-lived bearer token. + "exchange-token" - to indicate that this OCM Server supports the +OCM code flow via an [RFC6749]-compliant token endpoint. When this +OCM Server acts as Sending Server, it hosts tokenEndPoint. When it +acts as Receiving Server, it can honor inbound shares that require +token exchange. "http-sig" - to indicate that this OCM Server supports [RFC9421] HTTP Message Signatures and advertises public keys in the format specified by [RFC7517] at the /.well-known/jwks.json @@ -814,9 +837,6 @@ to the more secure (and possibly required) invite flow. notifications to exchange updates on shares and invites. "invite-wayf" - to indicate that this OCM Server exposes a WAYF Page to facilitate the Invite flow. - "webdav-uri" - to indicate that this OCM Server can append a -relative URI to the path listed for WebDAV [RFC4918] in the -appropriate resourceTypes entry "protocol-object" - to indicate that this OCM Server can receive a Share Creation Notification whose protocol object contains one property per supported protocol instead of containing @@ -826,24 +846,27 @@ the standard name and options["http-request-signatures"]. The array MAY include +Example: ["must-use-http-sig"]. The array MAY include for instance: - "http-request-signatures" - to indicate that API requests + "must-use-http-sig" - to indicate that API requests without http signatures will be rejected. - "token-exchange" - to indicate that API requests without -token exchange will be rejected (see the Code Flow -section). + "must-exchange-token" - to indicate that when this OCM Server +acts as Receiving Server, it requires the code flow for all inbound +shares. Shares that do not include must-exchange-token in +the requirements of each protocol offered for access will be +rejected. An +OCM Server advertising this criterium MUST also expose the +exchange-token capability. See the Code Flow +section. "denylist" - some servers MAY be blocked based on their IP address "allowlist" - unknown servers MAY be blocked based on their IP address - "invite" - an invite MUST have been exchanged between the + "must-invite" - an invite MUST have been exchanged between the sender and the receiver before a Share Creation Notification can be sent - DEPRECATED: publicKey (object) - Use public keys at -/.well-known/jwks.json instead for RFC 9421 support. OPTIONAL: inviteAcceptDialog (string) - URL path of a web page where a user can accept an invite, when query parameters "token" and "providerDomain" are provided. Implementations that offer the @@ -852,8 +875,10 @@ enhance the UX of the Invite Flow. If for example "/index.php/apps/sciencemesh/accept" is specified here then a WAYF Page SHOULD redirect the end-user to /index.php/apps/sciencemesh/ accept?token=zi5kooKu3ivohr9a&providerDomain=cloud.example.org. - OPTIONAL: tokenEndPoint (string) - URL of the token endpoint where the -Sending Server can exchange a secret for a short-lived bearer token. + OPTIONAL: tokenEndPoint (string) - URL of the token endpoint hosted by +this OCM Server. When this OCM Server acts as Sending Server, the +Receiving Server POSTs here to exchange a sharedSecret for a +short-lived bearer token. Implementations that offer the "exchange-token" capability MUST provide this URL as well. Example: "https://cloud.example.org/ocm/token". @@ -874,6 +899,29 @@ with the fields as described below using httpsig [RFC9421] +Before constructing the notification, the Sending Server MUST query +the Receiving Server's OCM API Discovery endpoint. If the Receiving +Server advertises must-exchange-token in its criteria and the +Sending Server exposes the exchange-token capability with a +tokenEndPoint, the Sending Server MUST include must-exchange-token +in the requirements of each protocol offered for access and MUST NOT +fall back to legacy shared-secret access. If the Receiving +Server advertises must-exchange-token but the Sending Server does +not expose the exchange-token capability or does not have a +tokenEndPoint, the Sending Server MUST NOT create the share, +as the Receiving Server would reject any notification that lacks +the code-flow requirement. +If the Receiving Server does not advertise must-exchange-token in its +criteria, the Sending Server MAY still include must-exchange-token +voluntarily. + +When the notification includes protocol.webapp, the Sending Server +MUST expose the exchange-token capability and a tokenEndPoint, +because WebApp access requires the Receiving Server to exchange +protocol.webapp.sharedSecret before presenting the WebApp to the +browser. If the Sending Server cannot offer this code flow, it MUST NOT +include protocol.webapp in the notification. +
Fields @@ -882,7 +930,7 @@ OCM Address of the user, group or federation the provider wants to share the Resource with. This MUST be known in advance, either via a previous Invitation or through other means. -Example: "51dc30ddc473d43a6011e9ebba6ca770@geant.org" +Example: "51dc30ddc473d43a6011e9ebba6ca770@cloud.example.org" REQUIRED name (string) Name of the Resource (file or folder). Example: "resource.txt" @@ -898,11 +946,11 @@ Example: 7c084226-d9a1-11e6-bf26-cec0c932ce01 REQUIRED owner (string) - OCM Address of the user who owns the Resource. -Example: "6358b71804dfa8ab069cf05ed1b0ed2a@apiwise.nl" +Example: "6358b71804dfa8ab069cf05ed1b0ed2a@cloud.example.org" REQUIRED sender (string) - OCM Address of the user that wants to share the Resource. -Example: "527bd5b5d689e2c32ae974c6229ff785@apiwise.nl" +Example: "527bd5b5d689e2c32ae974c6229ff785@cloud.example.org" OPTIONAL ownerDisplayName (string) Display name of the owner of the Resource Example: "Dimitri" @@ -984,10 +1032,13 @@ cache operations on the Sending Server. The recipient MAY delegate a third-party service to execute the data transfer on their behalf. REQUIRED uri (string) -A URI to access the Remote Resource. The URI -SHOULD be relative, in which case the prefix -exposed by the /.well-known/ocm endpoint MUST -be used. Absolute URIs are deprecated. +A URI to access the Remote Resource. The URI MAY be relative, +such as a key or a UUID, in which case the prefix exposed by the +/.well-known/ocm endpoint MUST be used to access the Resource, +or it MAY be absolute, including a hostname. In all cases, for a +folder Resource, the composed URI acts as the root path, such +that other files located within it MUST be accessible by +appending their relative path to that URI. REQUIRED sharedSecret (string) A secret to be used to access the Resource, such as a bearer token. To prevent leaking it in logs it @@ -1003,14 +1054,16 @@ The permissions granted to the sharee. A subset of: The requirements that the sharee MUST fulfill to access the Resource. A subset of: - must-use-mfa requires the consumer to be MFA-authenticated. -This MAY be used if the recipient provider exposes the -enforce-mfa capability. must-exchange-token requires the recipient to exchange the given sharedSecret via a signed HTTPS request to the Sending Server's {tokenEndPoint} [RFC6749]. +This MAY be used if the Sending Server exposes the +exchange-token capability and tokenEndPoint, and MUST be +included when the Receiving Server advertises must-exchange-token +in criteria. + must-use-mfa requires the consumer to be MFA-authenticated. This MAY be used if the recipient provider exposes the -exchange-token capability. +enforce-mfa capability. OPTIONAL size (integer) The size of the resource to be transferred, useful @@ -1019,22 +1072,70 @@ especially in case of datatx access type. Protocol details for webapp MAY contain: REQUIRED uri (string) -A URI to a client-browsable view of the Shared -Resource, such that users MAY use the web -applications available at the site. The URI SHOULD -be relative, in which case the prefix exposed by -the /.well-known/ocm endpoint MUST be used. -Absolute URIs are deprecated. - REQUIRED viewMode (string) -The permissions granted to the sharee. A subset of: +A URI to a client-browsable view of the Shared Resource, such +that users MAY use a web application available at the Sending +Server. The URI MUST be absolute, including a hostname. In +case the underlying Resource is a folder, the URI MUST act as a +root path, such that files located within the folder are made +accessible in the web app by appending their relative path to +the URI. + REQUIRED targets (array of strings) - How the recipient SHOULD +present the URI to the user. The targets array MUST NOT be +empty. A subset of: + + blank signals the recipient to open the URI in a top-level +browsing context chosen by the receiver, such as a new window or +tab, or a full page navigation in the current window. + iframe signals the recipient to embed the URI in an iframe +within its own UI, when the Sending Server allows framing by +this receiver. +A Sending Server MUST NOT offer a target that the recipient did +not advertise in its webapp-receive discovery property. + + REQUIRED permissions (array of strings) - +The permissions granted to the sharee. MUST NOT be empty. +A subset of: view allows access to the web app in view-only mode. read allows read and download access via the web app. write allows full editing rights via the web app. + share allows re-share rights on the Resource. This only +applies to web apps that provide a mechanism for re-sharing. - OPTIONAL sharedSecret (string) -An optional secret to be used to access the remote -web app, for example in the form of a bearer token. + REQUIRED requirements (array of strings) - +The requirements that the sharee MUST fulfill to +access the Resource. The requirements MUST at least include +must-exchange-token. If multiple protocols are present in the +share payload, the requirements for the different protocols MUST +agree. For example, if a webapp share is sent in the same payload +as a webdav share, both protocols MUST carry the same +requirements, and both requirement arrays MUST include +must-exchange-token. + REQUIRED sharedSecret (string) +A secret for accessing the remote web app. To give access to the +remote app, the receiver MUST first exchange this value at the +Sending Server's {tokenEndPoint} using the Code Flow, then perform +an HTTP POST request to the given uri with the resulting bearer +token in a form field named access_token (see +Resource Access). The shared secret MUST NOT +be exposed to the browser and MUST NOT appear in any URI. + OPTIONAL appName (string) +A human-friendly name of the web application, to be used in user +interfaces when referring to this Share. + OPTIONAL appIconHint (string) +A string in the form of a media type (MIME type) that describes the +share as a whole, primarily intended as a way for the receiving +server to select an appropriate local icon for the share. This is +display metadata and MUST NOT be interpreted as fetchable or +executable content. It does not need to appear in mediaTypes, but +SHOULD describe the primary shared resource. [RFC6838] + OPTIONAL mediaTypes (array of strings) +An array of media types (MIME types) the webapp server can handle. +This can be any media type entries from the IANA Media Type +registry. The receiver MAY use this as a hint for UI or routing +decisions, and MAY ignore values it does not understand. Unlike +appIconHint, this describes formats the webapp can open rather +than the share-level icon hint. [RFC6838] Protocol details for ssh MAY contain: @@ -1126,6 +1227,42 @@ instance a push notification or an email message. share, or add the share automatically and only send an informational notification that this happened. +
+
+
Request for a Share + +If the Receiving Party knows of a resource that has not yet +been shared, the Receiving Party MAY make an HTTP POST request + + + to the /request-share path in the Sending Server's OCM API + using application/json as the Content-Type HTTP request +header + its request body containing a JSON document representing an +object with the fields as described below + using TLS + using httpsig [RFC9421] + + +
Fields + + + REQUIRED owner (string) +OCM Address of the user who will be requested to share +the resource. + REQUIRED shareWith (string) +OCM Address of the user, group or federation that wants to +receive a share of the resource. +Example: "51dc30ddc473d43a6011e9ebba6ca770@cloud.example.org" + REQUIRED share (string) +A unique identifier for the resource. +Example: 1234567890abcdef or https://cloud.example.org/files/data.txt + + +After receiving a request for a Share, the Sending Party MAY +send a Share Creation Notification to the Receiving Party +using the OCM address in the shareWith field. +
Share Acceptance Notification @@ -1146,7 +1283,7 @@ with the fields as described below using httpsig [RFC9421] -
Fields +
Fields REQUIRED notificationType (string) - in a Share Acceptance @@ -1206,9 +1343,9 @@ to use it, the following steps are to be followed. token for a short-lived bearer token, and only use that bearer token to access the Resource (See the Code Flow section). If the must-exchange-token requirement is not present - and the Discovery endpoint inspected at step 1. exposes the - token-exchange capability, the receiver MAY attempt to perform - the token exchange as above, but it MUST fall back to the following + and the discovery inspected at step 1 exposes the exchange-token + capability with a tokenEndPoint, the receiver MAY attempt the + token exchange as above, but it MUST fall back to the following steps should the process fail. 3.2. If it includes must-use-mfa, the Receiving Server MUST ensure that the Receiving Party has been authenticated with MFA, or prompt @@ -1230,6 +1367,35 @@ this access method, based on Basic Auth, is deprecated and may be removed in a future release of the Protocol. If a secret cannot be identified (e.g. because protocol.options is undefined), then the receiver SHOULD discard the share as invalid. + For the specific case where protocol.webapp is available and the +receiver wants to use it, the receiver MUST present the web app to +the user by opening protocol.webapp.uri using a target selected +from the intersection of protocol.webapp.targets and the targets +advertised in the receiver's webapp-receive discovery property. +If this intersection is empty, the receiver MUST treat the webapp +option as unusable for this Share. If the selected target is +blank, the receiver MAY use _blank or _top according to its +local presentation policy. The receiver MUST inspect +protocol.webapp.requirements: if it includes must-use-mfa, the +Receiving Server MUST ensure that the Receiving Party has been +authenticated with MFA, or prompt the consumer in order to elevate +their session, if applicable. The receiver MUST NOT place the +protocol.webapp.sharedSecret in the URI and MUST NOT expose it to +the browser. Instead, the receiver MUST first exchange it at the +Sending Server's {tokenEndPoint} using the Code Flow, then deliver +the resulting bearer token to the web app via an HTTP POST to +protocol.webapp.uri with the token carried in a form field named +access_token along with another form field named +expired_session_redirect_uri. The +expired_session_redirect_uri value MUST be an absolute HTTPS URI +controlled by the Receiving Server. The Sending WebApp MAY navigate +the browser to this URI when the posted session expires so that the +Receiving Server can restart access and obtain a fresh token; it +MUST NOT place the shared secret or access token in that URI. +Sending WebApps that do not support session refresh MAY ignore this +field. This is typically achieved with an auto-submitting +HTML form whose target attribute selects the chosen +presentation (e.g. an iframe name, _blank, or _top). In all cases, in case the Shared Resource is a folder and the Receiving @@ -1265,11 +1431,11 @@ Content-Type: application/x-www-form-urlencoded Digest: SHA-256=ok6mQ3WZzKc8nb7s/Jt2yY1uK7d2n8Zq7dhl3Q0s1xk= Content-Length: 101 Signature-Input: - sig1=("@method" "@target-uri" "content-digest" "date"); + ocm=("@method" "@target-uri" "content-digest" "date"); created=1730815200; keyid="receiver.example.org#key1"; - alg="rsa-sha256" -Signature: sig1=:bM2sV2a4oM8pWc4Q8r9Zb8bQ7a2vH1kR9xT0yJ3uE4wO5lV6bZ1cP + alg="ed25519" +Signature: ocm=:bM2sV2a4oM8pWc4Q8r9Zb8bQ7a2vH1kR9xT0yJ3uE4wO5lV6bZ1cP 2rN3qD4tR5hC=: grant_type=authorization_code& @@ -1323,6 +1489,67 @@ response with a JSON object containing an OAuth 2.0 error code Permitted error codes are invalid_request, invalid_client, invalid_grant, unauthorized_client and unsupported_grant_type. +
+
Decision Table + +The directional contract depends first on whether the share is strict. +For strict shares, the Receiving Server's advertised behavior determines +whether the Sending Server can require code flow. For non-strict +shares, the Sending Server's advertised behavior determines whether +token exchange is available in addition to legacy access. + + + If the Sending Server includes must-exchange-token in +protocol.webdav.requirements and the Receiving Server exposes the +exchange-token capability, strict token exchange is required +before the Resource is accessed. + If the Sending Server includes must-exchange-token and the +Receiving Server does not expose the exchange-token capability, +the Sending Server SHOULD NOT include that requirement, because the +Receiving Server may be unable to complete the exchange. + If the Sending Server omits must-exchange-token and exposes the +exchange-token capability with a tokenEndPoint, the Receiving +Server MAY attempt token exchange first and MUST fall back to legacy +shared-secret access if that exchange fails. + If the Sending Server omits must-exchange-token and does not +expose the exchange-token capability, only legacy shared-secret +access is available. + + +The following examples illustrate typical end-to-end outcomes: + + + Strict required code flow: Provider A acts as Sending Server and +exposes the exchange-token capability with a tokenEndPoint. +Provider B acts as Receiving Server and advertises both +exchange-token and must-exchange-token. After discovering B's +must-exchange-token criteria, A MUST include must-exchange-token +in protocol.webdav.requirements. B MUST exchange the +sharedSecret at A's tokenEndPoint and then use only the bearer +token to access the Resource. + Optional exchange with fallback: Provider A acts as Sending Server +and exposes the exchange-token capability with a tokenEndPoint. +Provider B does not advertise must-exchange-token, so A sends a +share without must-exchange-token. When B later accesses the +Resource, it MAY attempt the token exchange at A's tokenEndPoint, +but if that exchange fails it MUST fall back to the legacy +sharedSecret. + Legacy share to a code-flow-capable peer: Provider A does not +expose the exchange-token capability. Provider B does expose +exchange-token, so B is capable of honoring strict inbound shares +from other peers. Because A does not advertise a tokenEndPoint, +A can only send a legacy share and B can only use legacy +shared-secret access for that share. + Asymmetric role behavior: Provider A exposes exchange-token and +must-exchange-token, so it can require code flow for inbound +shares when it acts as Receiving Server. When A later acts as +Sending Server toward Provider B, and B does not advertise +must-exchange-token, A MAY omit must-exchange-token. B may then +attempt token exchange against A's tokenEndPoint or fall back to +legacy access. A therefore accepts strict inbound shares while +still choosing a legacy-compatible outbound share. + +
Share Deletion @@ -1364,7 +1591,7 @@ a Resource without an explicit grant from the Sending Server.
Well-Known URI for the Discovery The following value is to be registered in the "Well-Known URIs" -registry (using the template from [RFC5785]): +registry (using the template from [RFC8615]): URI suffix: ocm Change controller: IETF Specification document(s): the present Draft, once in RFC form @@ -1389,7 +1616,7 @@ registry (using the template from [RFC9553]): "user@provider" where provider is the FQDN of an OCM-capable server. - "trusted" (Boolean, optional): Whether shares from this address - are automatically accepted. Default: false. + are automatically accepted. Default: false. - "source" (String, optional): How this address was established. See "JSContact Enum Values" registry for allowed values. - "label" (String, optional): Human-readable label for this @@ -1410,7 +1637,7 @@ registry (using the template from [RFC9553]): Change Controller: IETF Reference or Description: -A map of OCM addresses for a contact. The keys are arbitrary +A map of OCM addresses for a contact. The keys are arbitrary identifiers (e.g., "primary", "work") and the values are ocmAddress objects as defined in the JSContact Types Registry. @@ -1451,7 +1678,7 @@ Values" registry (using the template from [RFC9553]). There are several areas that are not covered by this specification. Most importantly we do not provide a way of establishing trust between servers, even though some features of the protocol rely on trust, such -as the mfa-enforced requirement. +as the must-use-mfa requirement. Trust needs to be established out of band, but there are some features of the protocol that can be used to assist operators in establishing @@ -1486,6 +1713,15 @@ confidential and never logged, persisted beyond their lifetime, or transmitted over unsecured channels.
+
+
Copying conditions + +The author(s) agree to grant third parties the irrevocable right to +copy, use and distribute the work, with or without modification, in +any medium, without royalty, provided that, unless separate permission +is granted, redistributed modified works do not contain misleading +author, version, name of work, or endorsement information. +
References @@ -1505,6 +1741,10 @@ June 2007. [RFC6749] Hardt, D. (ed), "The OAuth 2.0 Authorization Framework", October 2012. +[RFC6838] Freed, N., Klensin, J., Hansen, T. "Media Type +Specifications and Registration Procedures +", January 2013. + [RFC7515] Jones, M., Bradley, J., Sakimura, N., "JSON Web Signature (JWS)", May 2015. @@ -1522,6 +1762,8 @@ Key Words", May 2017. [RFC9421] Backman, A., Richer, J. and Sporny, M. "HTTP Message Signatures", February 2024. +[RFC9530] Polli, R., Marwood, D., "Digest Fields", February 2024. + [RFC9553] Stepanek, R., Loffredo, M., "JSContact: A JSON Representation of Contact Data, May 2024" @@ -1532,10 +1774,10 @@ Representation of Contact Data, May 2024" If a Receiving Server exposes the capability enforce-mfa, it indicates that it will try and comply with a MFA requirement set on a Share. If the Sending Server trusts the Receiving Server, the Sending -Server MAY set the requirement mfa-enforced on a Share, which the +Server MAY set the requirement must-use-mfa on a Share, which the Receiving Server MUST honor. A compliant Receiving Server that signals that it is MFA-capable MUST NOT allow access to a Resource protected -with the mfa-enforced requirement, if the Receiving Party has not +with the must-use-mfa requirement, if the Receiving Party has not provided a second factor to establish their identity with greater confidence. @@ -1612,27 +1854,72 @@ breaks in @signature-params for display purposes only): "@method": POST "@target-uri": https://receiver.example.org/ocm/shares -"content-digest": sha-256=:[digest-value]=: -"@signature-params": ("@method" "@target-uri" "content-digest"); +"content-digest": sha-256=:[digest-value]: +"content-length": [body-length] +"date": [date] +"@signature-params": ("@method" "@target-uri" "content-digest" + "content-length" "date"); created=[timestamp]; keyid="sender.example.org#key1"; alg="ed25519" Sign this base using for example Ed25519 ([RFC8032]) to produce the -signature, then add headers (line breaks for display purposes only): +signature, using the ocm label, and then add headers (line breaks +for display purposes only): -Signature-Input: sig1=("@method" "@target-uri" "content-digest"); +Content-Digest: sha-256=:[digest-value]: +Content-Length: [body-length] +Date: [date] +Signature-Input: ocm=("@method" "@target-uri" "content-digest" + "content-length" "date"); created=[timestamp]; keyid="sender.example.org#key1"; alg="ed25519" -Signature: sig1=:[signature-value]=: +Signature: ocm=:[signature-value]=: +A signed request MUST cover at least the following Signature-Input +components: + + + "@method" - HTTP method + "@target-uri" - full request URI (scheme, authority, + path, query) + "content-digest" - [RFC9530] digest of the body + "content-length" - bound message size + "date" - bound clock time + + +The Signature-Input parameters MUST include created. Verifiers MUST +reject signatures that omit any of the above components or the created +parameter, and MUST reject signatures whose created value is more than +a small implementation-defined skew tolerance in the future, or older +than the verifier's freshness window. + +A Content-Digest header value carrying multiple algorithms MUST have +every recognised digest match the body; a single match alongside a +recognised mismatch MUST be treated as an integrity failure. + +A request signed in the context of OCM MUST include one and only one +signature with the label ocm in its Signature and Signature-Input +headers. + +A symmetric signing algorithm MUST NOT be used to sign the +request, as the Receiving Server would not be able to verify the +signature without having access to the shared secret in advance. +
Verifying a Signature (Receiver) +Verifiers MUST locate the ocm-labeled entry and verify only that one. +If multiple ocm signatures are present, the entire message MUST be +rejected. Verifiers MUST reject requests for which no ocm-labeled entry +is present. Other labels MAY coexist (e.g. proxy-attached signatures) +but verifiers MUST NOT process them as part of OCM signature +processing. + To verify an incoming signed request: @@ -1640,6 +1927,8 @@ Signature: sig1=:[signature-value]=: request body Fetch the public key from https://<provider-domain>/.well-known/jwks.json + Locate the unique signature with the label ocm in the +Signature-Input header Extract keyid from Signature-Input header and find the key matching the kid value in the [RFC7517] response Reconstruct the signature base from the request using the @@ -1698,11 +1987,11 @@ Example: "federation": "The ScienceMesh Directory", "servers": [ { - "url": "https://ocm-server-1.example.org", + "url": "https://ocm-server.example.org", "displayName": "OCM Server 1" }, { - "url": "https://ocm-server-2.example.org:4443", + "url": "https://ocm-server.example.com:4443", "displayName": "OCM Server 2" }, { @@ -1711,7 +2000,7 @@ Example: } ] }, - "protected": {"alg": "RS256"}, + "protected": {"alg": "ES256"}, "signature": "..." } ]]> @@ -1871,7 +2160,7 @@ implementor might find it useful to have a Provider object model to store the discovered information about federation peers or other remote OCM Providers. -The following diagram is illustrative and non-exhaustive. The single +The following diagram is illustrative and non-exhaustive. The single source of truth for Provider properties is the OCM API Discovery Fields section; for the box contents below, see the Properties subsection and the normative capability, criteria, and resource type definitions in @@ -1887,7 +2176,6 @@ that section. | - endPoint | | - inviteAcceptDialog | | - provider | - | - publicKey | | - tokenEndPoint | | - ... | +-----------------------+ @@ -1906,7 +2194,6 @@ that section. | - ... | | - invites | | +------------------+ | - notifications | | | | - protocol-object| | - | | - webdav-uri | | | | - ... | | | +------------------+ | | | @@ -1918,9 +2205,9 @@ that section. | +--------------------------+ | | - allowlist | | | - denylist | - | | - http-request-signatures| - | | - invite | - | | - token-exchange | + | | - must-use-http-sig | + | | - must-invite | + | | - must-exchange-token | | | - ... | | +--------------------------+ | @@ -1930,8 +2217,11 @@ that section. | Protocols | +------------------+ | - ssh | +| - ssh-receive | | - webapp | +| - webapp-receive | | - webdav | +| - webdav-receive | | - ... | +------------------+ ]]> @@ -1945,7 +2235,6 @@ that section. enabled: Boolean indicating if OCM service is active endPoint: Base URI for OCM API endpoints provider: Friendly branding name - publicKey: Optional public key for HTTP signatures resourceTypes: Array of supported resource types with protocols @@ -2195,11 +2484,32 @@ Andreas Klotz, Matthias Knoll, Christian Kracher, Mario Lassnig, Claudius Laumanns, Anthony Leroy, Patrick Maier, Vladislav Makarenko, Anna Manou, Rita Meneses, Zheng Meyer-Zhao, Crystal Michelle Chua, Yoann Moulin, Daniel Müller, Frederik Müller, Rasmus Munk, -Michał Orzechowski, Jacek Pawel Kitowski, Iosif Peterfi, -Alessandro Petraro, Rene Ranger, Angelo Romasanta, David Rousse, -Carla Sauvanaud, Klaus Scheibenberger, Marcin Sieprawski, +Michał Orzechowski, Jacek Pawel Kitowski, Enrique Pérez Arnaud, Iosif +Peterfi, Alessandro Petraro, Rene Ranger, Angelo Romasanta, David +Rousse, Carla Sauvanaud, Klaus Scheibenberger, Marcin Sieprawski, Tilo Steiger, C.D. Tiwari, Alejandro Unger and Tom Wezepoel. +Work on this document has been partially funded over the years by +multiple projects and funding agencies: + + + The CS3MESH4EOSC project "Interactive and agile/responsive +sharing mesh of storage, data and applications for EOSC", whose key +result was Science Mesh, received funding from the +European Union's Horizon 2020 research and innovation programme under +Grant Agreement no. 863353. + NLnet through the NGI0 Core Fund, with +financial support from the European Commission's +Next Generation Internet programme under grant agreement +No. 101092990. + The EOSC Data Commons project "Services for inter- and +cross-disciplinary data discovery, access, sharing and reuse in the +EOSC Federation", received funding from the European Union under Grant +Agreement no. 101188179. + Sovereign Tech Agency through the Tech Fund, with +a specific project. + +
@@ -2217,576 +2527,678 @@ Tilo Steiger, C.D. Tiwari, Alejandro Unger and Tom Wezepoel. From 5ca80258e3a9dd0925acc64be0dc5f1eb68accdc Mon Sep 17 00:00:00 2001 From: Giuseppe Lo Presti Date: Sat, 13 Jun 2026 13:22:45 +0200 Subject: [PATCH 2/2] Delete IETF-OCM.xml, to be regenerated at a later time --- IETF-OCM.xml | 3206 -------------------------------------------------- 1 file changed, 3206 deletions(-) delete mode 100644 IETF-OCM.xml diff --git a/IETF-OCM.xml b/IETF-OCM.xml deleted file mode 100644 index 95b20d0..0000000 --- a/IETF-OCM.xml +++ /dev/null @@ -1,3206 +0,0 @@ - - - - - - - - - - -]> - - - - - Open Cloud Mesh - - - CERN -
- giuseppe.lopresti@cern.ch - https://cern.ch/lopresti -
-
- - Ponder Source -
- michiel@pondersource.org - https://pondersource.com -
-
- - Ponder Source -
- mahdi@pondersource.org - https://pondersource.com -
-
- - SUNET -
- kano@sunet.se - https://code.smolnet.org/micke -
-
- - - - Applications and Real-Time - - Internet-Draft - - - - - - -Open Cloud Mesh (OCM) is a server federation protocol that is used to -notify a Receiving Party that they have been granted access to some -Resource. It has similarities with authorization flows such as -OAuth, as well as with social internet protocols such as ActivityPub -and email. - -A core use case of OCM is when a user (e.g., Alice on System A) wishes -to share a resource (e.g., a file) with another user (e.g., Bob on -System B) without transferring the resource itself or requiring Bob to -log in to System A. - -While this scenario is illustrative, OCM is designed to support a -broader range of interactions, including but not limited to file -transfers. - -Open Cloud Mesh handles interactions only up to the point where the -Receiving Party is informed of their access to the Resource. Actual -Resource access is subsequently managed by other protocols, such as -WebDAV. - - - - - - - -
- - - - - - -
Introduction - -Open Cloud Mesh was initially conceived of in 2015 and has been deployed -since 2016. OCM has been implemented by several platforms, including -CERNBox, Nextcloud, OpenCloud, ownCloud, and Seafile. - -The goal of OCM is to provide a secure, scalable, and flexible -infrastructure for securely sharing and collaborating on resources and -has seen wide adoption, not least in the academic sector. - -The core idea of OCM is to make it simple for users to do the right -thing. This is achieved by providing a protocol that abstracts away -security and authentication details from the users to the servers acting -on behalf of the users. Another important point of the protocol is the -invitation mechanism that lets users connect over established human -relationships and use those connections to establish contact between -their respective OCM servers. - -
-
Terms - -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. - -We define the following concepts, with some non-normative references to -related concepts from OAuth [RFC6749] and elsewhere: - - - Resource - The piece of data or interaction to which access is -being granted, including but not limited to: a file or folder, a video -call, a contact, a printer queue, etc. - Remote Resource - A Resource provided by the Sending Server. - Shared Resource - A Resource shared by an OCM Server, becoming a -Remote Resource if accepted by the Invite Receiver OCM Server. - Share - A policy rule stating that certain actors have specific -access rights to a Resource; it MAY also refer to a record in a -database representing this rule. - Sending Party - A person or party who is authorized to create -Shares; similar to "Resource Owner" in OAuth [RFC6749], identified by -its OCM Address. - Receiving Party - A person, group or party who is granted access -to the Resource through the Share; similar to "Requesting Party / RqP" -in OAuth-UMA, identified by its OCM Address. - Share Creation Notification - A server-to-server request from the -sending server to the receiving server, notifying the receiving server -that a Share has been created. - Sending Server - The server that: - - holds the Resource ("file server" or "Entreprise File Sync and Share -(EFSS) server" role), - provides access to it (by exposing at least one "API"), - takes the decision to create the Share based on user interface -gestures from the Sending Party (the "Authorization Server" role in -OAuth [RFC6749]), - takes the decision about authorizing attempts to access the Resource -(the "Resource Server" role in OAuth [RFC6749]), - sends out Share Creation Notifications when appropriate (see below). - - Receiving Server - The server that: - - receives Share Creation Notifications (see below), - actively or passively notifies the receiving user or group of any -incoming Share Creation Notification, - acts as an API client, allowing the receiving user to access the -Resource through an API (e.g., WebDAV [RFC4918]) of the sending -server. - - Sending Gesture - A user interface interaction from the Sending -Party to the Sending Server, conveying the intention to create a -Share. - Share Creation - The addition of a Share to the database state of -the Sending Server, in response to a successful Sending Gesture or for -another reason. - Sharing User - A user providing access to a Resource through a -Share. - FQDN - Fully Qualified Domain Name, such as "cloud.example.org". - OCM Server - A server that supports OCM. - OCM API Discovery - Process of evaluating properties of a Remote -Resource, after establishing contact with an OCM Server. - Discovering Server - A server that tries to obtain information in -OCM API Discovery. - Discoverable Server - A server that tries to supply information in -OCM API Discovery. - Federation - A group of OCM Providers that have established -mutual trust and agree on certain policies for interaction. A -Federation MAY be facilitated by a Directory Service. - FQDN - Fully Qualified Domain Name, such as "cloud.example.com". - Invite Acceptance Gesture - Gesture from the Invite Receiver to -the Invite Receiver OCM Server, supplying the Invite Token as well as -the OCM Address of the Invite Sender, effectively allowlisting the -Invite Sender OCM Server for sending Share Creation Notifications to -the Invite Receiver OCM Server. - Invite Acceptance Response - HTTP response to the Invite -Acceptance Request. - Invite Acceptance Request - API call from the Invite Receiver OCM -Server to the Invite Sender OCM Server, supplying the Invite Token as -well as the OCM Address of the Invite Receiver, effectively -allowlisting the Invite Sender OCM Server for sending Share Creation -Notifications to the Invite Receiver OCM Server. - Invite Creation Gesture - Gesture from the Invite Sender to the -Invite Sender OCM Server, resulting in the creation of an Invite -Token. - Invite Message - Out-of-band message used to establish contact -between parties and servers in the Invite Flow, containing an Invite -Token (see below) and the Invite Sender's OCM Address. - Invite Receiver - The party receiving an Invite, identified by its -OCM Address. - Invite Receiver OCM Server - The server holding an address book -used by the Invite Receiver, to which details of the Invite Sender are -to be added. - Invite Sender - The party sending an Invite, identified by its -OCM Address. - Invite Sender OCM Server - The server holding an address book -used by the Invite Sender, to which details of the Invite Receiver are -to be added. - Invite String - A base64 encoded string containing an Invite Token -and the FQDN of an Invite Sender OCM Server joined by an @-sign. - Invite Token - A hard-to-guess string used in the Invite Flow, -generated by the Invite Sender OCM Server and linked uniquely to the -Invite Sender's OCM Address. - OCM Address - identifies a user or group "at" an OCM Server. -The OCM Address contains a server specific Party identifier, a host -locating the OCM Server and an optional port. The OCM Address is not a -URI as it does not have scheme and the identifier may contain reserved -characters. -
- -The identifier is an opaque, case-sensitive UTF-8 string. It is - separated from the host by the last "@" in the OCM Address. It is - possible to have multiple @-signs in a OCM-address, e.g. when an - email address is the local part of the address like - nomen.nescio@example.org@cloud.example.org. -host is an IP literal encapsulated within square brackets, an IPv4 - address in dotted decimal form, or a registered name as described in - [RFC3986]. -
- -The optional port subcomponent can be used to specify a port to use - for discovery (see Discovery Process). -The OCM Server MUST be discoverable at the given host and optional - port via the Well-Known [RFC8615] path /.well-known/ocm. The OCM - Address MUST NOT contain a path.
- OCM API Discovery - Process of evaluating properties of a Remote -Resource, after establishing contact with an OCM Server. - OCM Server - A server that has the OCM Provider function. - Discovering Server - A server that tries to obtain information in -OCM API Discovery. - OCM Notification - A message from the Receiving Server to the -Sending Server or vice versa, using the OCM Notifications endpoint. - Receiving Party - A person, group or party who is granted access -to the Resource through the Share; similar to "Requesting Party / RqP" -in OAuth-UMA, identified by its OCM Address. - Receiving Server - The server that: - - receives Share Creation Notifications (see below), - actively or passively notifies the receiving user or group of any -incoming Share Creation Notification, - acts as an API client, allowing the receiving user to access the -Resource through an API (e.g., WebDAV [RFC4918]) of the sending -server. - - Remote Resource - A Resource provided by the Sending Server. - Resource - The piece of data or interaction to which access is -being granted, including but not limited to: a file or folder, a video -call, a contact, a printer queue, etc. - Sending Gesture - A user interface interaction from the Sending -Party to the Sending Server, conveying the intention to create a -Share. - Sending Party - A person or party who is authorized to create -Shares; similar to "Resource Owner" in OAuth [RFC6749], identified by -its OCM Address. - Sending Server - The server that: - - holds the Resource for instance, a file server, - provides access to it (by exposing at least one "API"), - takes the decision to create the Share based on user interface -gestures from the Sending Party (the "Authorization Server" role in -OAuth [RFC6749]), - takes the decision about authorizing attempts to access the Resource -(the "Resource Server" role in OAuth [RFC6749]), - sends out Share Creation Notifications when appropriate (see below). - - Share - A policy rule stating that certain actors have specific -access rights to a Resource; it MAY also refer to a record in a -database representing this rule. - Share Creation - The addition of a Share to the database state of -the Sending Server, in response to a successful Sending Gesture or for -another reason. - Share Creation Notification - A server-to-server request from the -sending server to the receiving server, notifying the receiving server -that a Share has been created. - Share Name - A human-readable string, provided by the Sending -Party or the Sending Server, to help the Receiving Party understand -which Resource the Share grants access to. - Share Permissions - protocol-specific allowances granted to the -Receiving Party on the modes of accessing the Resource. - Share Requirements - Protocol-specific restrictions on the modes -of accessing the Resource. - Shared Resource - A Resource shared by an OCM Server, becoming a -Remote Resource if accepted by the Invite Receiver OCM Server. - Sharing User - A user providing access to a Resource through a -Share. - Trusted Server - An OCM Server that is considered trustworthy by - another OCM Server, based on out-of-band information, federation - membership or prior interactions, SHOULD be recorded in an internal - registry of trusted servers, that SHOULD be updated over time based - on new information. The registry SHOULD include the FQDN of the - trusted server and the Public Key used for HTTP Signatures. It MAY - also include additional metadata such as the inviteAcceptDialog URL - or supported capabilities. - WAYF Page - A Where-Are-You-From page is a discovery service used -to identify the OCM Server of an Invite Receiver. -
- -
Functions - -Open Cloud Mesh defines distinct functions. It is not necessary for an -implementation to provide all of them. In fact, it may be useful to -have separate implementations for different functions. - -
OCM Provider - -An OCM Provider is an entity that can take on the two roles of a -Sending Server and a Receiving Server. An OCM Provider MUST be a -Discoverable Server and SHOULD be able to receive Notifications. - -
-
OCM Directory Service - -An OCM Directory Service is an entity that exposes information about a -Federation of OCM Providers. - -
-
-
Roles - -Open Cloud Mesh defines two distinct roles that an OCM Provider MUST -take on: the Sending Server role and the Receiving Server role. - -
Sending Server - -A Sending Server is an OCM Provider that holds Resources and exposes -APIs to allow access to them. It allows its users to create Shares -to give other users access to those Resources. A Sending Server MAY -provide its users with the ability to generate Invites to establish -contact with other users on other OCM Providers. When doing so it MAY -provide a WAYF Page to facilitate the Invite Flow. The WAYF page MAY -be limited to a set of trusted OCM Providers, for instance those in the -same Federation. - -
-
Receiving Server - -A Receiving Server is an OCM Provider that receives Share Creation -Notifications from Sending Servers, notifies its users about incoming -Shares, and acts as an API client to allow its users to access Remote -Resources. It MAY provide its users with an Address Book of -Contacts and the ability to accept Invites. - -In Appendix D, an object model is presented as a non-normative guide for -implementers to understand the relationships between these terms. - -
-
-
-
General Flow - -The lifecycle of an Open Cloud Mesh Share starts with prerequisites such -as establishing trust, establishing contact, and OCM API Discovery. - -Then the share creation involves the Sending Party making a Sending -Gesture to the Sending Server, the Sending Server carrying out the -actual Share Creation, and the Sending Server sending a Share Creation -Notification to the Receiving Server. - -After this, the Receiving Server MAY notify the Receiving Party and/or -the Sending Server, and will act as an API client through which the -Receiving Party can access the Resource. The Receiving Party or -the Sending Party MAY then update or delete the Share: the respective -Server MAY send a Notification to the other party about the change. - -
-
Establishing Contact - -Before the Sending Server can send a Share Creation Notification to the -Receiving Server, it MUST establish the Receiving Party's OCM -Address (containing the Receiving Server's FQDN, and the Receiving -Party's identifier), among other things. Some steps may preceed the -Sending Gesture, allowing the Sending Party to establish (with some -level of trust) the OCM Address of the Receiving Party. In other cases, -establishing the OCM Address of the Receiving Party happens as part of -the Sending Gesture. - -
Direct Entry - -The simplest way for this is if the Receiving Party shares their OCM -Address with the Sending Party through some out-of-band means, and the -Sending Party enters this string into the user interface of the Sending -Server, by means of typing or pasting into an HTML form, or clicking a -link to a URL that includes the string in some form. - -
-
Public Link Flow - -An interface for anonymously viewing a Resource on the Sending Server -MAY allow any internet user to type or paste an OCM address into an HTML -form, as a Sending Gesture. This means that the Sending Party and the -Receiving Party could be the same person, so contact between them does -not need to be explicitly established. - -
-
Public Invite Flow - -Similarly, an interface on the Sending Server MAY allow any internet -user to type or paste an OCM address into an HTML form, as a Sending -Gesture for a given Resource, without itself providing a way to access -that particular Resource. A link to this interface could then for -instance be shared on a mailing list, allowing all subscribers to -effectively request access to the Resource by making a Sending Gesture -to the Sending Server with their own OCM Address. - -
-
Invite Flow - -
Rationale - -Many methods for establishing contact allow unsolicited contact with the -prospective Receiving Party whenever that party's OCM Address is known. -The Invite Flow requires the Receiving Party to explicitly accept it -before it can be used, which establishes bidirectional trust between the -two parties involved. - -OCM Servers MAY enforce a policy to only accept Shares between such -trusted contacts, or MAY display a warning to the Receiving Party when a -Share Creation Notification from an unknown Sending Party is received - -
-
Steps - - - the Invite Sender OCM Server generates a unique Invite Token and helps -the Invite Sender to create the Invite Message - the Invite Sender uses some out-of-band communication to send the -Invite Message, containing the Invite Token and the Invite Sender OCM -Server FQDN, to the Invite Receiver - the Invite Receiver navigates to the Invite Receiver OCM Server and -makes the Invite Acceptance Gesture. This step MAY be facilitated if -the Invite Sender OCM Server implements a WAYF Page, such that the -Invite Message would include a link to it for the Invite Receiver to -navigate to: the Invite Receiver would then be able to indicate their -OCM Server and proceed with the Invite Acceptance Gsture without -manually copying the Invite Token. - the Invite Receiver OCM Server discovers the OCM API of the Invite -Sender OCM Server using generic OCM API Discovery (see section below) - the Invite Receiver OCM Server sends the Invite Acceptance Request to -the Invite Sender OCM Server - - -
-
Invite Acceptance Request Details - -Whereas the precise syntax of the Invite Message and the Invite -Acceptance Gesture will differ between implementations, the Invite -Acceptance Request SHOULD be a HTTP POST request: - - - to the /invite-accepted path in the Invite Sender OCM Server's OCM -API - using application/json as the Content-Type HTTP request header - its request body containing a JSON document representing an object -with the following string fields: - - REQUIRED: recipientProvider - FQDN of the Invite Receiver OCM -Server. - REQUIRED: token - The Invite Token. The Invite Sender OCM Server -SHOULD recall which Invite Sender OCM Address this token was linked -to. - REQUIRED: userID - The Invite Receiver's identifier at their OCM -Server. - REQUIRED: email - Non-normative / informational; an email address -for the Invite Receiver. Not necessarily at the same FQDN as their -OCM Server. - REQUIRED: name - Human-readable name of the Invite Receiver, as a -suggestion for display in the Invite Sender's address book - - using TLS - using httpsig [RFC9421] - - -The Invite Receiver OCM Server SHOULD apply its own policies for -trusting the Invite Sender OCM Server before making the Invite -Acceptance Request. - -Since the Invite Flow does not require either Party to type or remember -the userID, this string does not need to be human-memorable. Even if -the Invite Receiver has a memorable username at the Invite Receiver OCM -Server, this userID that forms part of their OCM Address does not need -to match it. - -Also, a different userID could be given out to each contact, to avoid -correlation of identities. - -If the Invite Sender OCM Server implements a WAYF Page, such a page MAY -include a fixed list of servers, in addition to, or instead of, a -free-text input where any OCM Server can be entered. This is especially -useful if the Invite Sender is part of a federation of associated OCM -Servers. In order to populate the list of associated OCM Servers, the -Invite Sender's server MAY make use of a Directory Service, which is -expected to follow the specification detailed in Appendix C. - -Implementors that provide a WAYF Page SHOULD make the URL for the API -endpoint of such a Directory Service configurable, allowing the OCM -Server to be part of a network of associated OCM Servers. The -configuration mechanism MAY allow an OCM Server to be part of multiple -networks, thus displaying a union of multiple lists in its WAYF Page. - -
-
Invite Acceptance Response Details - -The Invite Acceptance Response SHOULD be a HTTP response: - - - in response to the Invite Acceptance Request - using application/json as the Content-Type HTTP response header - its response body containing a JSON document representing an object -with the following string fields: - - REQUIRED: userID - the Invite Sender's identifier at their OCM -Server - REQUIRED: email - non-normative / informational; an email address -for the Invite Sender. Not necessarily at the same FQDN as their -OCM Server - REQUIRED: name - human-readable name of the Invite Sender, as a -suggestion for display in the Invite Receiver's address book - - - -A 200 response status means the Invite Acceptance Request was -successful. -A 400 response status means the Invite Token is invalid or does not -exist. -A 403 response status means the Invite Receiver OCM Server is not -trusted to accept this Invite. -A 409 response status means the Invite was already accepted. - -The Invite Sender OCM Server SHOULD verify the HTTP Signature on the -Invite Acceptance Request and apply its own policies for trusting the -Invite Receiver OCM Server before processing the Invite Acceptance -Request and sending the Invite Acceptance Response. - -As with the userID in the Invite Acceptance Request, the one in the -Response also doesn't need to be human-memorable, doesn't need to match -the Invite Sender's username at their OCM Server. - -
-
Addition into address books - -Following these step, both servers MAY display the name of the other -party as a trusted or allowlisted contact, and enable selecting them as -a Receiving Party. OCM Servers MAY enforce a policy to only accept -Share Creation Notifications from such trusted contacts, or MAY display -a warning to users when a Share Creation Notification from an unknown -party is received. - -Both servers MAY also allowlist each other as a server with which at -least one of their users wishes to interact. - -In addition, if the identity provider of either server supports the -registration of external users, it may happen that the just received -email contact from the other party matches an external user already -known in the local identity provider, and therefore already present -in the address book. In such a case, implementers MAY support linking -of the two identities belonging to that same user, so that when a Share -Creation gesture is made to that recipient, both a regular share and an -OCM Share Creation Notification are issued. - -Note that Invites act symmetrically, so once contact has been -established, both the Invite Sender and the Invite Receiver MAY take on -either the Sending Party or the Receiving Party role in subsequent -Share Creation events. - -Both parties MAY delete the other party from their address book at any -time without notifying them. - -
-
Invite format -To accept an invite, two pieces of information are required: a token -and a provider. There are two recognized formats: - - - Invite string format: -A base64-encoded string containing the token and the provider’s FQDN, -joined by an @ sign. Example: -If the token is a55a966e-15c1-4cb9-a39d-4e4c54399baf and the -provider is cloud.example.org, the combined string is -a55a966e-15c1-4cb9-a39d-4e4c54399baf@cloud.example.org, -which when base64-encoded becomes -YTU1YTk2NmUtMTVjMS00Y2I5LWEzOWQtNGU0YzU0Mzk5YmFmQG15LWNsb3VkLXN0b -3JhZ2Uub3Jn. -When parsing an invite string, implementors must base64-decode it, -then split on the last @ sign, taking care to allow multiple @ -characters in the token part. - Link format: -If the inviting OCM Server supports a WAYF page, the invite may be -provided as a link with the token as a request parameter. Example: -https://cloud.example.org/wayf?token= -a55a966e-15c1-4cb9-a39d-4e4c54399baf - - -Implementations MUST be able to accept invites in the invite string -format. This format is considered canonical. The link format is only -useful if the Receiving OCM Server exposes the inviteAcceptDialog -in its Discovery endpoint. Implmentations SHOULD support the link -format when they implement a WAYF Page that leverages those -inviteAcceptDialog targets. - -
-
Security Advantages - -It is important to underscore the value of the Invite in this scenario, -as it provides four important security advantages. First of all, if the -Receiving Server blocks Share Creation Notifications from Sending -Parties who are not in the address book of the Receiving Party, then -this protects the Receiving Party from receiving unsolicited Shares. An -attacker could still send the Receiving Party an unsolicited Share, but -they would first need to convince the Receiving Party through an -out-of-band communication channel to accept their invite. In many use -cases, the Receiving Party has had other forms of contact with the -Sending Party (e.g., in-person or email back-and-forth). The -out-of-band Invite Message thus leverages the filters and context which -the Receiving Party may already benefit from in that out-of-band -communication. For instance, a careful Receiving Party MAY choose to -only accept Invites that reach them via a private or moderated -messaging platform. - -Second, when the Receiving Party accepts the Invite, the Receiving -Server knows that the Sending Server they are about to interact with is -trusted by the Sending Party, which in turn is trusted by the Receiving -Party, which in turn is trusted by them. In other words, one of their -users is requesting the allowlisting of a server they wish to interact -with, in order to interact with a party they know out-of-band. This -gives the Receiving Server reason to put more trust in the Sending -Server than it would put into an arbitrary internet-hosted server. - -Third, equivalently, the Sending Server knows it is essentially -registering the Receiving Server as an API client at the request of the -Receiving Party, to whom the right to request this has been traceably -delegated by the Sending Party, which is one of its registered users. - -Fourth, related to the second one, it removes the partial 'open relay' -problem that exists when the Sending Server is allowed to include any -Receiving Server FQDN in the Sending Gesture. Without the use of -Invites, a Distributed Denial of Service attack could be organised if -many internet users collude to flood a given OCM Server with Share -Creation Notifications which will be hard to distinguish from -legitimate requests without human interaction. An unsolicited (invalid) -Invite Acceptance Request is much easier to filter out than an -unsolicited (possibly valid, possibly invalid) Share Creation -Notification Request, since the Invite Acceptance Request needs to -contain an Invite Token that was previously uniquely generated at the -Invite Sender OCM server. - -
-
-
-
OCM API Discovery - -
Introduction - -After establishing contact as discussed in the previous section, the -Sharing User MAY send the Share Creation Gesture to the Sending Server. -The Sharing User MUST provide the following information: - - - Resource to be shared - Protocol to be offered for access - Sending Party's identifier - Receiving Party's identifier - Receiving Server FQDN - OPTIONAL: Share Requirements - OPTIONAL: Share Name - OPTIONAL: Share Permissions - - -The next step is for the Sending Server to additionally discover: - - - if the Receiving Server is trusted - if the Receiving Server supports OCM - if so, which version and with which optional functionality - at which URL - the public key the Receiving Server will use for HTTP Signatures (if -any) - - -The Sending Server MAY first perform denylist and allowlist checks on -the FQDN. - -If a finite allowlist of Receiving Servers exists on the Sending Server -side, then this list MAY already contain all necessary information. - -If the FQDN passes the denylist and/or allowlist checks, but no details -about its OCM API are known, the Sending Server can use the following -process to try to fetch this information from the Receiving Server. - -This process MAY be influenced by a VPN connection and/or IP -allowlisting. - -When OCM API Discovery can occur in preparation of a Share Creation -Notification, the Sending Server takes on the 'Discovering Server' role -and the Receiving Server plays the role of 'Discoverable Server'. - -
-
Process - -At the start of the process, the Discovering Server has either an OCM -Address, or just an FQDN from for instance the recipientProvider -field of an Invite Acceptance Request. - -Step 1: In case it has an OCM Address, it SHOULD first extract <fqdn> -from it (the part after the last @ sign). -Step 2: The Discovering Server SHOULD attempt OCM API Discovery via a -HTTP GET request to https://<fqdn>/.well-known/ocm. -Step 3: If that results in a valid HTTP response with a valid JSON -response body within reasonable time, go to step 5. -Step 4: If not, fail. Implementations MAY fallback to HTTP instead -of HTTPS in testing setups and retry steps 2-3, in particular when -an optional port is given in the address. -Step 5: The JSON response body is the data that was discovered. - -
-
Fields - -The JSON response body offered by the Discoverable Server SHOULD -contain the following information about its OCM API: - - - REQUIRED: enabled (boolean) - Whether the OCM service is enabled at -this endpoint - REQUIRED: apiVersion (string) - The OCM API version this endpoint -supports. Example: "1.3.0" - REQUIRED: endPoint (string) - The URI of the OCM API available at -this endpoint. Example: "https://cloud.example.org/ocm" - OPTIONAL: provider (string) - A friendly branding name of this -endpoint. Example: "MyCloudStorage" - REQUIRED: resourceTypes (array) - A list of all resource types this -server supports in both the Sending Server role and the Receiving -Server role, with their access protocols. Each item in this list -MUST itself be an object containing the following fields: - - name (string) - A supported resource type (file, calendar, -contact, ...). -Implementations MUST offer support for at least one -resource type, where file is the commonly supported -one. Each resource type is identified by its name: -the list MUST NOT contain more than one resource type -object per given name. - shareTypes (array of string) - -The supported recipient share types. MUST contain -"user" at a minimum, plus optionally "group" and -"federation". -Example: ["user"] - protocols (object) - The supported protocols for accessing Shared -Resources of this type. Implementations that offer file -Resources MUST support at least webdav, any other combination -of Resources and protocols is optional. Example: -
- -The protocols object distinguishes a server's role for each -protocol: a property named after the protocol (e.g. webdav, -webapp, ssh) advertises support for acting as a Sending -Server, while a property suffixed with -receive (e.g. -webdav-receive, webapp-receive, ssh-receive) advertises -support for acting as a Receiving Server. -Fields: -- webdav (string) - The top-level WebDAV [RFC4918] path at this - endpoint. In order to access a Remote Resource, implementations - SHOULD use this path as a prefix (see sharing examples). -- webdav-receive (object) - Advertised by implementations that - support receiving WebDAV shares. It contains a uri property - whose value MUST be either "absolute" or "relative", - signalling the URI format this endpoint accepts. Note that - older implementations MAY not support this property. -- webapp (object) - Advertised, as an empty object, by - implementations that support sending WebApp shares. -- webapp-receive (object) - Advertised by implementations that - support receiving WebApp shares. It contains a targets - array listing the ways this endpoint is able to present a - WebApp share to the user. A subset of: - - blank - the endpoint can open the URI in a top-level - browsing context, such as a new window or tab, or a full page - navigation in the current window. - - iframe - the endpoint can embed the URI in an iframe - within its own UI, when the Sending Server allows framing - by this receiver. -- ssh (string) - The top-level address in the form host:port - of an endpoint that supports ssh and scp with a public/private - key based authentication. -- ssh-receive (object) - Advertised, as an empty object, by - implementations that support receiving SSH shares. -- Any additional protocol supported for this Resource type MAY be - advertised here, where the value MAY correspond to - a top-level URI to be used for that protocol. Similarly, - additional receiving capabilities for custom protocols SHOULD - be advertised using a -receive suffixed property.
-
- OPTIONAL: capabilities (array of string) - The optional capabilities -supported by this OCM Server. -As implementations MUST accept Share Creation Notifications -to be compliant, it is not necessary to expose that as a -capability. -Example: ["exchange-token", "protocol-object"]. The array MAY -include one or more of the following items: - - "enforce-mfa" - to indicate that this OCM Server can apply a -Sending Server's MFA requirements for a Share on their behalf. - "exchange-token" - to indicate that this OCM Server supports the -OCM code flow via an [RFC6749]-compliant token endpoint. When this -OCM Server acts as Sending Server, it hosts tokenEndPoint. When it -acts as Receiving Server, it can honor inbound shares that require -token exchange. - "http-sig" - to indicate that this OCM Server supports -[RFC9421] HTTP Message Signatures and advertises public keys in the -format specified by [RFC7517] at the /.well-known/jwks.json -endpoint for signature verification. - "invites" - to indicate the server would support acting as an -Invite Sender or Invite Receiver OCM Server. This might be useful -for suggesting to a user that existing contacts might be upgraded -to the more secure (and possibly required) invite flow. - "notifications" - to indicate that this OCM Server handles -notifications to exchange updates on shares and invites. - "invite-wayf" - to indicate that this OCM Server exposes a WAYF -Page to facilitate the Invite flow. - "protocol-object" - to indicate that this OCM Server can -receive a Share Creation Notification whose protocol object -contains one property per supported protocol instead of containing -the standard name and options properties. - - OPTIONAL: criteria (array of string) - The criteria for accepting a -Share Creation Notification. -As all Receiving Servers SHOULD require the use of TLS in API -calls, it is not necessary to expose that as a criterium. -Example: ["must-use-http-sig"]. The array MAY include -for instance: - - "must-use-http-sig" - to indicate that API requests -without http signatures will be rejected. - "must-exchange-token" - to indicate that when this OCM Server -acts as Receiving Server, it requires the code flow for all inbound -shares. Shares that do not include must-exchange-token in -the requirements of each protocol offered for access will be -rejected. An -OCM Server advertising this criterium MUST also expose the -exchange-token capability. See the Code Flow -section. - "denylist" - some servers MAY be blocked based on their IP -address - "allowlist" - unknown servers MAY be blocked based on their IP -address - "must-invite" - an invite MUST have been exchanged between the -sender and the receiver before a Share Creation Notification can be -sent - - OPTIONAL: inviteAcceptDialog (string) - URL path of a web page where -a user can accept an invite, when query parameters "token" and -"providerDomain" are provided. Implementations that offer the -"invites" capability SHOULD provide this URL as well in order to -enhance the UX of the Invite Flow. If for example -"/index.php/apps/sciencemesh/accept" is specified here then a WAYF -Page SHOULD redirect the end-user to /index.php/apps/sciencemesh/ -accept?token=zi5kooKu3ivohr9a&providerDomain=cloud.example.org. - OPTIONAL: tokenEndPoint (string) - URL of the token endpoint hosted by -this OCM Server. When this OCM Server acts as Sending Server, the -Receiving Server POSTs here to exchange a sharedSecret for a -short-lived bearer token. -Implementations that offer the "exchange-token" capability MUST -provide this URL as well. -Example: "https://cloud.example.org/ocm/token". -
- -
-
-
Share Creation Notification - -To create a Share, the Sending Server SHOULD make a HTTP POST request - - - to the /shares path in the Receiving Server's OCM API - using application/json as the Content-Type HTTP request header - its request body containing a JSON document representing an object -with the fields as described below - using TLS - using httpsig [RFC9421] - - -Before constructing the notification, the Sending Server MUST query -the Receiving Server's OCM API Discovery endpoint. If the Receiving -Server advertises must-exchange-token in its criteria and the -Sending Server exposes the exchange-token capability with a -tokenEndPoint, the Sending Server MUST include must-exchange-token -in the requirements of each protocol offered for access and MUST NOT -fall back to legacy shared-secret access. If the Receiving -Server advertises must-exchange-token but the Sending Server does -not expose the exchange-token capability or does not have a -tokenEndPoint, the Sending Server MUST NOT create the share, -as the Receiving Server would reject any notification that lacks -the code-flow requirement. -If the Receiving Server does not advertise must-exchange-token in its -criteria, the Sending Server MAY still include must-exchange-token -voluntarily. - -When the notification includes protocol.webapp, the Sending Server -MUST expose the exchange-token capability and a tokenEndPoint, -because WebApp access requires the Receiving Server to exchange -protocol.webapp.sharedSecret before presenting the WebApp to the -browser. If the Sending Server cannot offer this code flow, it MUST NOT -include protocol.webapp in the notification. - -
Fields - - - REQUIRED shareWith (string) -OCM Address of the user, group or federation the provider -wants to share the Resource with. This MUST be known -in advance, either via a previous Invitation or through -other means. -Example: "51dc30ddc473d43a6011e9ebba6ca770@cloud.example.org" - REQUIRED name (string) -Name of the Resource (file or folder). -Example: "resource.txt" - OPTIONAL description (string) -Optional description of the Resource (file or folder). -Example: "This is the Open API Specification file (in YAML -format) of the Open Cloud Mesh API." - REQUIRED providerId (string) -Opaque value to identify the Shared Resource at the provider side. -This MUST be unique per Resource and per share, such that multiple -shares of a given Resource are guaranteed to get different values. -Example: 7c084226-d9a1-11e6-bf26-cec0c932ce01 - REQUIRED owner (string) - -OCM Address of the user who owns the -Resource. -Example: "6358b71804dfa8ab069cf05ed1b0ed2a@cloud.example.org" - REQUIRED sender (string) - -OCM Address of the user that wants to share -the Resource. -Example: "527bd5b5d689e2c32ae974c6229ff785@cloud.example.org" - OPTIONAL ownerDisplayName (string) -Display name of the owner of the Resource -Example: "Dimitri" - OPTIONAL senderDisplayName (string) -Display name of the user that wants to share the Resource -Example: "John Doe" - REQUIRED shareType (string) -SHOULD have a value of "user", "group", or "federation", to -indicate that the first part of the shareWith OCM Address refers -to a Receiving Party who is a single user of the Receiving Server, -a group of users at the Receiving Server, or a group of users that -spans multiple OCM Servers belonging to a federation as exposed by -a Directory Service, including at least one user at the Receiving -Server. -In the federation case, OCM Servers MAY resolve the actual -recipients by either querying external AAI systems, or exchanging -the groups' metadata between themselves. Such exchange is out of -scope for this version of the this specification. -Alternatively, the Receiving Server MAY hold the federated groups' -metadata and act as an OCM proxy, forwarding the OCM requests to -the actual members of the federation. - REQUIRED resourceType (string) -Resource type (file, folder, calendar, contact, ...). If the -Resource is a folder, implementations SHOULD advertise it as -folder rather than file, in order to streamline the processing -by the Receiving Server. - OPTIONAL expiration (integer) -The expiration time for the OCM share, in seconds -of UTC time since Unix epoch. If omitted, it is assumed that the -share does not expire. A sender server MAY use it to signal that -the resource represents a cached copy of a dataset that was made -available for an efficient data transfer to the destination server. - REQUIRED protocol (object) -JSON object with specific options for each protocol. -The supported protocols are: - webdav, to access the data - -webapp, to access remote web applications - ssh, to access -the data via a public/private key pair. -Other custom protocols might be added in the future. -In case a single protocol is offered, there are three ways to -specify this object: -Option 1: Set the name field to the name of the protocol, -and put the protocol details in a field named options. -Option 2: Set the name field to the name of the protocol, -and put the protocol details in a field carrying the name of -the protocol. -Option 3: Set the name field to multi, and put the -protocol details in a field carrying the name of the protocol. -Option 1 using the options field is now deprecated. -Implementations are encouraged to transition to the new -optional properties defined below, such that this field -may be removed in a future major version of the spec. -When specifying more than one protocol as different ways to -access the Share, the name field needs to be set to multi. -If multi is given, one or more protocol -endpoints are expected to be defined according to the -optional properties specified below. -Otherwise, at least webdav is expected to be -supported, and its options MAY be given in the opaque -options payload for compatibility with v1.0 -implementations (see examples). Note though that this -format is deprecated. -Warning: client implementers should be aware that v1.1+ -servers MAY support both webdav and multi, but v1.0 -servers MAY only support webdav. - Protocol details for webdav MAY contain: - - OPTIONAL accessTypes (array of strings) - The type of access -being granted to the remote resource. If omitted, it defaults to -['remote']. A subset of: - - remote signals the recipient that the resource is available -for remote access and interactive browsing. - datatx signals the recipient that the resource is -available for data transfer. If no expiration is given, the share -is suitable e.g. for sync use-cases, whereas if an expiration date -is set, the above clause MAY apply and the recipient SHOULD notify -the sender upon completing the data transfer, in order to ease -cache operations on the Sending Server. The recipient MAY delegate -a third-party service to execute the data transfer on their behalf. - - REQUIRED uri (string) -A URI to access the Remote Resource. The URI MAY be relative, -such as a key or a UUID, in which case the prefix exposed by the -/.well-known/ocm endpoint MUST be used to access the Resource, -or it MAY be absolute, including a hostname. In all cases, for a -folder Resource, the composed URI acts as the root path, such -that other files located within it MUST be accessible by -appending their relative path to that URI. - REQUIRED sharedSecret (string) -A secret to be used to access the Resource, such as -a bearer token. To prevent leaking it in logs it -MUST NOT appear in any URI. - OPTIONAL permissions (array of strings) - -The permissions granted to the sharee. A subset of: - - read allows read-only access including download of a copy. - write allows create, update, and delete rights on the Resource. - share allows re-share rights on the Resource. - - OPTIONAL requirements (array of strings) - -The requirements that the sharee MUST fulfill to -access the Resource. A subset of: - - must-exchange-token requires the recipient to -exchange the given sharedSecret via a signed HTTPS request -to the Sending Server's {tokenEndPoint} [RFC6749]. -This MAY be used if the Sending Server exposes the -exchange-token capability and tokenEndPoint, and MUST be -included when the Receiving Server advertises must-exchange-token -in criteria. - must-use-mfa requires the consumer to be MFA-authenticated. -This MAY be used if the recipient provider exposes the -enforce-mfa capability. - - OPTIONAL size (integer) -The size of the resource to be transferred, useful -especially in case of datatx access type. - - Protocol details for webapp MAY contain: - - REQUIRED uri (string) -A URI to a client-browsable view of the Shared Resource, such -that users MAY use a web application available at the Sending -Server. The URI MUST be absolute, including a hostname. In -case the underlying Resource is a folder, the URI MUST act as a -root path, such that files located within the folder are made -accessible in the web app by appending their relative path to -the URI. - REQUIRED targets (array of strings) - How the recipient SHOULD -present the URI to the user. The targets array MUST NOT be -empty. A subset of: - - blank signals the recipient to open the URI in a top-level -browsing context chosen by the receiver, such as a new window or -tab, or a full page navigation in the current window. - iframe signals the recipient to embed the URI in an iframe -within its own UI, when the Sending Server allows framing by -this receiver. -A Sending Server MUST NOT offer a target that the recipient did -not advertise in its webapp-receive discovery property. - - REQUIRED permissions (array of strings) - -The permissions granted to the sharee. MUST NOT be empty. -A subset of: - - view allows access to the web app in view-only mode. - read allows read and download access via the web app. - write allows full editing rights via the web app. - share allows re-share rights on the Resource. This only -applies to web apps that provide a mechanism for re-sharing. - - REQUIRED requirements (array of strings) - -The requirements that the sharee MUST fulfill to -access the Resource. The requirements MUST at least include -must-exchange-token. If multiple protocols are present in the -share payload, the requirements for the different protocols MUST -agree. For example, if a webapp share is sent in the same payload -as a webdav share, both protocols MUST carry the same -requirements, and both requirement arrays MUST include -must-exchange-token. - REQUIRED sharedSecret (string) -A secret for accessing the remote web app. To give access to the -remote app, the receiver MUST first exchange this value at the -Sending Server's {tokenEndPoint} using the Code Flow, then perform -an HTTP POST request to the given uri with the resulting bearer -token in a form field named access_token (see -Resource Access). The shared secret MUST NOT -be exposed to the browser and MUST NOT appear in any URI. - OPTIONAL appName (string) -A human-friendly name of the web application, to be used in user -interfaces when referring to this Share. - OPTIONAL appIconHint (string) -A string in the form of a media type (MIME type) that describes the -share as a whole, primarily intended as a way for the receiving -server to select an appropriate local icon for the share. This is -display metadata and MUST NOT be interpreted as fetchable or -executable content. It does not need to appear in mediaTypes, but -SHOULD describe the primary shared resource. [RFC6838] - OPTIONAL mediaTypes (array of strings) -An array of media types (MIME types) the webapp server can handle. -This can be any media type entries from the IANA Media Type -registry. The receiver MAY use this as a hint for UI or routing -decisions, and MAY ignore values it does not understand. Unlike -appIconHint, this describes formats the webapp can open rather -than the share-level icon hint. [RFC6838] - - Protocol details for ssh MAY contain: - - OPTIONAL accessTypes (array of strings) - The type of access -being granted to the remote resource. If omitted, it defaults to -['remote']. A subset of: - - remote signals the recipient that -the resource is available for remote access, e.g. via sshfs. - datatx signals the recipient to transfer the resource -from the given URI via scp. The recipient MAY delegate a -third-party service to execute the data transfer on their behalf. - - REQUIRED uri (string) -The full address to be used for ssh or scp access, in the form -username@host.fqdn:port/resource/path, where the username is -chosen by the Sending Server and does not necessarily need to match -the recipient's OCM Address. Authentication is expected to take -place via public/private key: the Receiving Server MUST reply to -such a Share Creation Notification by sending back their public -key, for the Sender Server to authorize access to the Resource. - - - -
-
Response - -The Share Creation Notification Response SHOULD be a HTTP response: - - - in response to the Share Creation Notification Request - using application/json as the Content-Type HTTP response header - - -A 201 response status means the Share Creation Notification Request was -successful. In this case, the response body MUST contain a JSON -document representing an object with the following string fields: - - REQUIRED: recipientDisplayName - the Recipient's display name. - - OPTIONAL: recipientPublicKeys - the Recipient's public key(s). - This property MUST be returned when the protocol of the incoming - share was ssh. -A 400 response status means some parameters were invalid or missing. -A 401 response status means the Sender cannot be authenticated as -a trusted service. -A 403 response status means the Sender is not authorized to create -shares. -A 501 response status means either the Receiver does not support -incoming external shares, or the share type or the resource type -are not supported. -A 503 response status means that the Receiver is temporary unavailable. - -
-
Decision to Discard - -The Receiving Server MAY discard the notification if any of the -following hold true: - - - the HTTP Signature is missing but the Sending Server does expose a -keypair discoverable from the FQDN part of the sender field in the -request body - the HTTP Signature is missing - the HTTP Signature is not valid - no keypair is trusted or discoverable from the FQDN part of the -sender field in the request body - the keypair used to generate the HTTP Signature doesn't match the one -trusted or discoverable from the FQDN part of the sender field -in the request body - the Sending Server is denylisted - the Sending Server is not allowlisted - the Sending Party is not trusted by the Receiving Party (e.g., no -Invite was exchanged and/or the Sending Party's OCM Address does not -appear in the Receiving Party's address book) - the Receiving Server is unable to act as an API client for (any of) -the protocol(s) listed for accessing the Resource - an initial check shows that the Resource cannot successfully be -accessed through (any of) the protocol(s) listed - - -
-
Receiving Party Notification - -If the Share Creation Notification is not discarded by the Receiving -Server, they MAY notify the Receiving Party passively by adding the -Share to some inbox list, and MAY also notify them actively through for -instance a push notification or an email message. - -They could give the Receiving Party the option to accept or reject the -share, or add the share automatically and only send an informational -notification that this happened. - -
-
-
Request for a Share - -If the Receiving Party knows of a resource that has not yet -been shared, the Receiving Party MAY make an HTTP POST request - - - to the /request-share path in the Sending Server's OCM API - using application/json as the Content-Type HTTP request -header - its request body containing a JSON document representing an -object with the fields as described below - using TLS - using httpsig [RFC9421] - - -
Fields - - - REQUIRED owner (string) -OCM Address of the user who will be requested to share -the resource. - REQUIRED shareWith (string) -OCM Address of the user, group or federation that wants to -receive a share of the resource. -Example: "51dc30ddc473d43a6011e9ebba6ca770@cloud.example.org" - REQUIRED share (string) -A unique identifier for the resource. -Example: 1234567890abcdef or https://cloud.example.org/files/data.txt - - -After receiving a request for a Share, the Sending Party MAY -send a Share Creation Notification to the Receiving Party -using the OCM address in the shareWith field. - -
-
-
Share Acceptance Notification - -In response to a Share Creation Notification, the Receiving Server MAY -discover the OCM API of the Sending Server, starting from the <fqdn> -part of the sender field in the Share Creation Notification. - -If the OCM API of the Sending Server is successfully discovered, the -Receiving Server MAY make a HTTP POST request - - - to the /notifications path in the Sending Server's OCM API - using application/json as the Content-Type HTTP request header - its request body containing a JSON document representing an object -with the fields as described below - using TLS - using httpsig [RFC9421] - - -
Fields - - - REQUIRED notificationType (string) - in a Share Acceptance -Notification it MUST be one of: - - 'SHARE_ACCEPTED' - 'SHARE_DECLINED' - - REQUIRED providerId (string) - copied from the Share Creation -Notification for the Share this notification is about - OPTIONAL resourceType (string) - copied from the Share Creation -Notification for the Share this notification is about - OPTIONAL notification (object) - optional additional parameters, -depending on the notification and the resource type - - -For example, a notification MAY be sent by a recipient to let the -provider know that the recipient declined a share. In this case, the -provider site MAY mark the share as declined for its user(s). -Similarly, it MAY be sent by a provider to let the recipient know that -the provider removed a given share, such that the recipient MAY clean -it up from its database. A notification MAY also be sent to let a -recipient know that the provider removed that recipient from the list -of trusted users, along with any related share. The recipient MAY -reciprocally remove that provider from the list of trusted users, along -with any related share. - -Notifications from Sending Server to Receiving Server SHOULD use -httpsig [RFC9421] so the Receiving Server can authenticate the origin -of the notification. Receiving Servers SHOULD decline notifications -from Sending Servers without httpsig as it can't identify where the -notification is coming from. - -
-
-
Resource Access - -To access the Resource, the Receiving Server MAY use multiple ways, -depending on the body of the Share Creation Notification and the -protocol required for access. The procedure is as follows: - - - The receiver MUST extract the OCM Server FQDN from the sender -field of the received share, and MUST query the -Discovery endpoint at that address: let -<sender-ocm-path> be the resourceTypes[0].protocols.webdav value -to be used later, if defined. - If protocol.name is multi, the receiver MUST inspect the -protocol.{protocolName} properties corresponding to the protocol -of concern, and act according to its semantics. For the specific -case where protocol.webdav is available and the receiver wants -to use it, the following steps are to be followed. - The protocol.webdav.requirements MUST be inspected: -3.1. If it includes must-exchange-token, the receiver MUST make a - signed POST request to the path in the Sending Server’s - {tokenEndPoint}, to exchange the protocol.webdav.sharedSecret - token for a short-lived bearer token, and only use that bearer - token to access the Resource (See the Code Flow - section). If the must-exchange-token requirement is not present - and the discovery inspected at step 1 exposes the exchange-token - capability with a tokenEndPoint, the receiver MAY attempt the - token exchange as above, but it MUST fall back to the following - steps should the process fail. -3.2. If it includes must-use-mfa, the Receiving Server MUST ensure - that the Receiving Party has been authenticated with MFA, or prompt - the consumer in order to elevate their session, if applicable. - The protocol.webdav.uri property MUST now be inspected: if it's a -complete URI, the receiver MUST make a HTTP PROPFIND request against -it to access the Remote Resource, otherwise it is to be taken as an -identifier <id>, in which case the receiver MUST make a HTTP -PROPFIND request to: https://<sender-host><sender-ocm-path>/<id> -in order to access to the Remote Resource. The receiver MUST pass -an Authorization: bearer header with either the short-lived bearer -token obtained in step 3.1., if applicable, or the -protocol.webdav.sharedSecret value. - Otherwise, if protocol.name is webdav the receiver SHOULD inspect -the protocol.options property: if protocol.options.sharedSecret -is defined, then the receiver SHOULD make a HTTP PROPFIND request to -https://<sharedSecret>:@<sender-host><sender-ocm-path>. Note that -this access method, based on Basic Auth, is deprecated and may be -removed in a future release of the Protocol. If a secret cannot be -identified (e.g. because protocol.options is undefined), then -the receiver SHOULD discard the share as invalid. - For the specific case where protocol.webapp is available and the -receiver wants to use it, the receiver MUST present the web app to -the user by opening protocol.webapp.uri using a target selected -from the intersection of protocol.webapp.targets and the targets -advertised in the receiver's webapp-receive discovery property. -If this intersection is empty, the receiver MUST treat the webapp -option as unusable for this Share. If the selected target is -blank, the receiver MAY use _blank or _top according to its -local presentation policy. The receiver MUST inspect -protocol.webapp.requirements: if it includes must-use-mfa, the -Receiving Server MUST ensure that the Receiving Party has been -authenticated with MFA, or prompt the consumer in order to elevate -their session, if applicable. The receiver MUST NOT place the -protocol.webapp.sharedSecret in the URI and MUST NOT expose it to -the browser. Instead, the receiver MUST first exchange it at the -Sending Server's {tokenEndPoint} using the Code Flow, then deliver -the resulting bearer token to the web app via an HTTP POST to -protocol.webapp.uri with the token carried in a form field named -access_token along with another form field named -expired_session_redirect_uri. The -expired_session_redirect_uri value MUST be an absolute HTTPS URI -controlled by the Receiving Server. The Sending WebApp MAY navigate -the browser to this URI when the posted session expires so that the -Receiving Server can restart access and obtain a fresh token; it -MUST NOT place the shared secret or access token in that URI. -Sending WebApps that do not support session refresh MAY ignore this -field. This is typically achieved with an auto-submitting -HTML form whose target attribute selects the chosen -presentation (e.g. an iframe name, _blank, or _top). - - -In all cases, in case the Shared Resource is a folder and the Receiving -Server accesses a Resource within that shared folder, it SHOULD append -its relative path to that URL. In other words, the Sending Server -SHOULD support requests to URLs such as -https://<sender-host><sender-ocm-path>/path/to/resource.txt. - -
-
Code Flow - -This section defines the procedure for issuing short-lived bearer access -tokens for use by the Receiving Server when accessing a resource shared -through OCM. The mechanism is aligned with the OAuth 2.0 -authorization_code grant type but is performed entirely as a -server to server interaction between the Sending and Receiving Servers. -No user interaction or redirect is involved. [RFC6749] - -
Token Request - -To obtain an access token, the Receiving Server MUST send an HTTP POST -request to the Sending Server’s {tokenEndPoint} as discovered in the -OCM provider metadata, following section 4.4.2 of [RFC6749]. The -request payload MUST be in x-www-form-urlencoded form, as shown -in the following example (with line breaks in the Signature headers -for display purposes only): - - -POST {tokenEndPoint} HTTP/1.1 -Host: cloud.example.org -Date: Wed, 05 Nov 2025 14:00:00 GMT -Content-Type: application/x-www-form-urlencoded -Digest: SHA-256=ok6mQ3WZzKc8nb7s/Jt2yY1uK7d2n8Zq7dhl3Q0s1xk= -Content-Length: 101 -Signature-Input: - ocm=("@method" "@target-uri" "content-digest" "date"); - created=1730815200; - keyid="receiver.example.org#key1"; - alg="ed25519" -Signature: ocm=:bM2sV2a4oM8pWc4Q8r9Zb8bQ7a2vH1kR9xT0yJ3uE4wO5lV6bZ1cP - 2rN3qD4tR5hC=: - -grant_type=authorization_code& -client_id=receiver.example.org& -code=my_secret_code - - -The request MUST be signed using an HTTP Message Signature -[RFC9421]. The client_id identifies the Receiving Server and MUST be -set to its fully qualified domain name. The code parameter carries -the authorization secret that was issued by the Sending Server in the -Share Creation Notification. It is allowed to send the additional -parameters defined in [RFC6749] for the authorization_code grant type, -but they MUST be ignored. - -
-
Token Response - -If the request is valid and the code is accepted, the Sending Server -MUST respond with HTTP 200 OK and a OAuth-compliant JSON object -containing the issued token: - -
- -The access_token is an opaque bearer credential with no internal -structure visible to the Receiving Server. The token authorizes the -Receiving Server to access the shared resource using the appropriate -transport protocol (e.g., WebDAV). The expires_in value indicates -the token lifetime in seconds. No refresh_token is issued, instead -the same request to the {tokenEndPoint} MUST be repeated before the -access_token has expired, to recieve a new access_token that can -then be used in the same manner. - -
-
Error Responses - -If the request is invalid, the Sending Server MUST return an HTTP 400 -response with a JSON object containing an OAuth 2.0 error code -[RFC6749]: - -
- -Permitted error codes are invalid_request, invalid_client, -invalid_grant, unauthorized_client and unsupported_grant_type. - -
-
Decision Table - -The directional contract depends first on whether the share is strict. -For strict shares, the Receiving Server's advertised behavior determines -whether the Sending Server can require code flow. For non-strict -shares, the Sending Server's advertised behavior determines whether -token exchange is available in addition to legacy access. - - - If the Sending Server includes must-exchange-token in -protocol.webdav.requirements and the Receiving Server exposes the -exchange-token capability, strict token exchange is required -before the Resource is accessed. - If the Sending Server includes must-exchange-token and the -Receiving Server does not expose the exchange-token capability, -the Sending Server SHOULD NOT include that requirement, because the -Receiving Server may be unable to complete the exchange. - If the Sending Server omits must-exchange-token and exposes the -exchange-token capability with a tokenEndPoint, the Receiving -Server MAY attempt token exchange first and MUST fall back to legacy -shared-secret access if that exchange fails. - If the Sending Server omits must-exchange-token and does not -expose the exchange-token capability, only legacy shared-secret -access is available. - - -The following examples illustrate typical end-to-end outcomes: - - - Strict required code flow: Provider A acts as Sending Server and -exposes the exchange-token capability with a tokenEndPoint. -Provider B acts as Receiving Server and advertises both -exchange-token and must-exchange-token. After discovering B's -must-exchange-token criteria, A MUST include must-exchange-token -in protocol.webdav.requirements. B MUST exchange the -sharedSecret at A's tokenEndPoint and then use only the bearer -token to access the Resource. - Optional exchange with fallback: Provider A acts as Sending Server -and exposes the exchange-token capability with a tokenEndPoint. -Provider B does not advertise must-exchange-token, so A sends a -share without must-exchange-token. When B later accesses the -Resource, it MAY attempt the token exchange at A's tokenEndPoint, -but if that exchange fails it MUST fall back to the legacy -sharedSecret. - Legacy share to a code-flow-capable peer: Provider A does not -expose the exchange-token capability. Provider B does expose -exchange-token, so B is capable of honoring strict inbound shares -from other peers. Because A does not advertise a tokenEndPoint, -A can only send a legacy share and B can only use legacy -shared-secret access for that share. - Asymmetric role behavior: Provider A exposes exchange-token and -must-exchange-token, so it can require code flow for inbound -shares when it acts as Receiving Server. When A later acts as -Sending Server toward Provider B, and B does not advertise -must-exchange-token, A MAY omit must-exchange-token. B may then -attempt token exchange against A's tokenEndPoint or fall back to -legacy access. A therefore accepts strict inbound shares while -still choosing a legacy-compatible outbound share. - - -
-
-
Share Deletion - -A "SHARE_ACCEPTED" notification followed by a "SHARE_UNSHARED" -notification is equivalent to a "SHARE_DECLINED" notification. - -Note that the Sending Server MAY at any time revoke access to a -Resource (effectively undoing or deleting the Share) without notifying -the Receiving Server. - -
-
Share Updating - -Some implementations have experimented with a -"RESHARE_CHANGE_PERMISSION"notification, but the payload and side -effects such a notification may have are out of scope of this version -of this specification. -The Receiving Party sending such a notification has no way of knowing -if the Sending Party understood and processed the reshare request -or not. - -
-
Resharing - -The "REQUEST_RESHARE" and "RESHARE_UNDO" notification types MAY be -used by the Receiving Server to persuade the Sending Server to share the -same Resource with another Receiving Party. -The details of the payload and side effects such a notification may -have are out of scope of this version of this specification. -Note that the Receiving Party sending such a notification has no way of -knowing if the Sending Party understood and processed the reshare -request or not. In all cases, the Receiving Server MUST NOT reshare -a Resource without an explicit grant from the Sending Server. - -
-
IANA Considerations - -
Well-Known URI for the Discovery - -The following value is to be registered in the "Well-Known URIs" -registry (using the template from [RFC8615]): - URI suffix: ocm - Change controller: IETF - Specification document(s): the present Draft, once in RFC form - Related information: N/A - -
-
JSContact Types Registry - -The following entry is to be registered in the "JSContact Types" -registry (using the template from [RFC9553]): - Type Name: ocmAddress - Intended Usage: common - Since Version: 1.0 - Until Version: N/A - Change Controller: IETF - Reference or Description: - -An object representing an OCM address. The object contains: - -
- -
-
JSContact Properties Registry - -The following entry is to be registered in the "JSContact Properties" -registry (using the template from [RFC9553]): - Property Name: ietf.org:ocmAddresses - Property Type: String[ocmAddress] - Property Context: Card - Intended Usage: common - Since Version: 1.0 - Until Version: N/A - Change Controller: IETF - Reference or Description: - -A map of OCM addresses for a contact. The keys are arbitrary - identifiers (e.g., "primary", "work") and the values are ocmAddress - objects as defined in the JSContact Types Registry. - -
-
JSContact Enum Values Registry - -The following entries are to be registered in the "JSContact Enum -Values" registry (using the template from [RFC9553]). - Property Name: ietf.org:ocmAddresses/source - Context: Card - Since Version: 1.0 - Until Version: N/A - Change Controller: IETF - Reference or Description: - -Values indicating how an OCM address was established. - -Initial Contents: - -
- -
-
-
Security Considerations - -
Trust - -There are several areas that are not covered by this specification. -Most importantly we do not provide a way of establishing trust between -servers, even though some features of the protocol rely on trust, such -as the must-use-mfa requirement. - -Trust needs to be established out of band, but there are some features -of the protocol that can be used to assist operators in establishing -trust. For instance, invite flow can be used to establish that users -know and have out of band connections with other users on an OCM server. - -Further more the Directory Service feature can be used to establish a -trusted federation, where a central authority can be trusted to -implement measures for auditing and adding only trusted servers into the -discovery service. - -
httpsig - -It is RECOMMENDED to use signed messages, "httpsig" [RFC9421], to -verify that an OCM server is the server you expect it to be, and SHOULD -be done unless you have a niche use case. - -
-
-
Legacy shared secrets - -The legacy format of an OCM Share Notification with shared secrets is -only provided for backwards compatibility with existing implementations. -Implementers SHOULD NOT use it and prefer short-lived tokens instead. - -
-
Code Flow - -All {tokenEndPoint} requests MUST be transmitted over HTTPS and -signed using HTTP Signatures. Bearer tokens MUST be treated as -confidential and never logged, persisted beyond their lifetime, or -transmitted over unsecured channels. - -
-
-
Copying conditions - -The author(s) agree to grant third parties the irrevocable right to -copy, use and distribute the work, with or without modification, in -any medium, without royalty, provided that, unless separate permission -is granted, redistributed modified works do not contain misleading -author, version, name of work, or endorsement information. - -
-
References - -
Normative References - -[RFC2119] Bradner, S. "Key words for use in RFCs to Indicate -Requirement Levels", -March 1997. - -[RFC3986] Berners-Lee, T., Fielding, R. and Masinter, L. -"Uniform Resource Identifier (URI): Generic Syntax -", January 2005 - -[RFC4918] Dusseault, L. M. "HTTP Extensions for Web Distributed -Authoring and Versioning", -June 2007. - -[RFC6749] Hardt, D. (ed), "The OAuth 2.0 Authorization Framework", October 2012. - -[RFC6838] Freed, N., Klensin, J., Hansen, T. "Media Type -Specifications and Registration Procedures -", January 2013. - -[RFC7515] Jones, M., Bradley, J., Sakimura, N., "JSON Web Signature -(JWS)", May 2015. - -[RFC7517] Jones, M., "JSON Web Key (JWK)", May 2015. - -[RFC8032] Josefsson, S., Liusvaara, I., "Edwards-Curve Digital -Signature Algorithm (EdDSA)", January 2017. - -[RFC8174] Leiba, B. "Ambiguity of Uppercase vs Lowercase in RFC 2119 -Key Words", May 2017. - -[RFC8615] Nottingham, M. "Well-Known Uniform Resource Identifiers -(URIs)", May 2019 - -[RFC9421] Backman, A., Richer, J. and Sporny, M. "HTTP Message -Signatures", February 2024. - -[RFC9530] Polli, R., Marwood, D., "Digest Fields", February 2024. - -[RFC9553] Stepanek, R., Loffredo, M., "JSContact: A JSON -Representation of Contact Data, May 2024" - -
-
-
Appendix A: Multi-factor Authentication - -If a Receiving Server exposes the capability enforce-mfa, it -indicates that it will try and comply with a MFA requirement set on a -Share. If the Sending Server trusts the Receiving Server, the Sending -Server MAY set the requirement must-use-mfa on a Share, which the -Receiving Server MUST honor. A compliant Receiving Server that signals -that it is MFA-capable MUST NOT allow access to a Resource protected -with the must-use-mfa requirement, if the Receiving Party has not -provided a second factor to establish their identity with greater -confidence. - -Since there is no way to guarantee that the Receiving Server will -actually enforce the MFA requirement, it is up to the Sending Server to -establish a trust with the Receiving Server such that it is reasonable -to assume that the Receiving Server will honor the MFA requirement. -This establishment of trust will inevitably be implementation -dependent, and can be done for example using a pre approved allow list -of trusted Receiving Servers. The procedure of establishing trust is -out of scope for this specification: a mechanism similar to the -ScienceMesh integration for the -Invite capability may be envisaged. - -
-
Appendix B: JWKS and HTTP Signature Examples - -
JWKS Endpoint - -An OCM Server that advertises the http-sig capability MUST expose its -public keys at /.well-known/jwks.json in the format specified by -[RFC7517]. Here is an example response from -https://sender.example.org/.well-known/jwks.json: - -
- -
-
Signing a Request (Sender) - -Given a Share Creation Notification request: - - -POST /ocm/shares HTTP/1.1 -Host: receiver.example.org -Date: Fri, 16 Jan 2026 13:37:00 GMT -Content-Type: application/json -Content-Digest: sha-256=:LkpHyFOVbBDPxc7YbHDOWNzAv88qWuVfLNf4TUf9Uo8=: - -{ - "shareWith": "marie@receiver.example.org", - "name": "spec.yaml", - "providerId": "7c084226-d9a1-11e6-bf26-cec0c932ce01", - "owner": "einstein@sender.example.org", - "sender": "einstein@sender.example.org", - "ownerDisplayName": "Albert Einstein", - "senderDisplayName": "Albert Einstein", - "shareType": "user", - "resourceType": "file", - "protocol": { - "name": "multi", - "webdav": { - "uri": "spec.yaml", - "sharedSecret": "hfiuhworzwnur98d3wjiwhr", - "permissions": ["read", "write"] - } - } -} - - -The signature base is constructed according to [RFC9421] (with line -breaks in @signature-params for display purposes only): - - -"@method": POST -"@target-uri": https://receiver.example.org/ocm/shares -"content-digest": sha-256=:[digest-value]: -"content-length": [body-length] -"date": [date] -"@signature-params": ("@method" "@target-uri" "content-digest" - "content-length" "date"); - created=[timestamp]; - keyid="sender.example.org#key1"; - alg="ed25519" - - -Sign this base using for example Ed25519 ([RFC8032]) to produce the -signature, using the ocm label, and then add headers (line breaks -for display purposes only): - - -Content-Digest: sha-256=:[digest-value]: -Content-Length: [body-length] -Date: [date] -Signature-Input: ocm=("@method" "@target-uri" "content-digest" - "content-length" "date"); - created=[timestamp]; - keyid="sender.example.org#key1"; - alg="ed25519" -Signature: ocm=:[signature-value]=: - - -A signed request MUST cover at least the following Signature-Input -components: - - - "@method" - HTTP method - "@target-uri" - full request URI (scheme, authority, - path, query) - "content-digest" - [RFC9530] digest of the body - "content-length" - bound message size - "date" - bound clock time - - -The Signature-Input parameters MUST include created. Verifiers MUST -reject signatures that omit any of the above components or the created -parameter, and MUST reject signatures whose created value is more than -a small implementation-defined skew tolerance in the future, or older -than the verifier's freshness window. - -A Content-Digest header value carrying multiple algorithms MUST have -every recognised digest match the body; a single match alongside a -recognised mismatch MUST be treated as an integrity failure. - -A request signed in the context of OCM MUST include one and only one -signature with the label ocm in its Signature and Signature-Input -headers. - -A symmetric signing algorithm MUST NOT be used to sign the -request, as the Receiving Server would not be able to verify the -signature without having access to the shared secret in advance. - -
-
Verifying a Signature (Receiver) - -Verifiers MUST locate the ocm-labeled entry and verify only that one. -If multiple ocm signatures are present, the entire message MUST be -rejected. Verifiers MUST reject requests for which no ocm-labeled entry -is present. Other labels MAY coexist (e.g. proxy-attached signatures) -but verifiers MUST NOT process them as part of OCM signature -processing. - -To verify an incoming signed request: - - - Extract the provider domain from the sender field in the -request body - Fetch the public key from -https://<provider-domain>/.well-known/jwks.json - Locate the unique signature with the label ocm in the -Signature-Input header - Extract keyid from Signature-Input header and find the key -matching the kid value in the [RFC7517] response - Reconstruct the signature base from the request using the -components listed in Signature-Input as specified in [RFC9421] - Verify the signature using the appropriate algorithm -(e.g., Ed25519 [RFC8032]) - - -
-
Validating the Payload - -Following the validation of the signature, the host SHOULD also confirm -the validity of the payload, that is ensuring that the actions implied -in the payload actually initiated on behalf of the source of the -request. - -As an example, if the payload is about initiating a new share, the file -owner has to be an account from the instance at the origin of the -request. - -
-
-
Appendix C: Directory Service - -A third-party Directory Service is a back-end service used to federate -multiple OCM Servers and facilitate the Invite flow. It is expected to -expose, via anonymous HTTPS GET, a signed JWS document [RFC7515], where -the signing key MUST be made available offline and the payload MUST -adhere to the following format: - - - REQUIRED: federation - a human-readable name for the list of OCM -Servers exposed by the Directory Service - REQUIRED: servers - a JSON array of objects to describe the list -of OCM Servers with the following string fields: - - REQUIRED: url - an absolute URL identifying the -OCM Server. It MUST: - - include scheme: either https:// or -(for testing purposes) http:// - include host (either a FQDN or an IP address) - MAY include a non-default port - MUST NOT include a base path (e.g., /ocm) - MUST NOT include userinfo, query, or fragment - - REQUIRED: displayName - a human-readable name -for the OCM Server -Example: - - - -
- -
-
Appendix D: Object models - -An implementor of OCM MAY choose any internal object model to represent -an Address Book, a Contact, an Invite, a Provider, a Share, -and a User. The following diagrams are provided to clarify -the concepts and their relationships, as a guide for implementors. - -
Address Book - -An OCM Provider MAY offer its Users an address book tool, where OCM -Addresses can be stored over time in a labeled and/or searchable way. -This decouples the act by which the OCM Address string is passed into -the Sending Server's database from the selection of the Receiving -Party in preparation for Share Creation. - -The Address Book entity maintains a collection of contacts for a user -within the OCM provider. It serves as the primary mechanism for -managing federated relationships between users across different OCM -Servers. Contacts may be added to the Address Book through the Invite -flow or direct entry. It provides a convenient way for users to -organize and access their federated contacts, and MAY allow users to -generate Invites. - -
- -
Properties - - - owner: Reference to the User who owns this address book - contacts: Array of Contact objects stored in the address book - - -
-
Relationships - - - An Address Book belongs one or more Users. - An Address Book contains zero or more Contacts. - An Address Book MAY allow its owner to generate Invites. - - -
-
-
Contact -A Contact represents a federated user relationship established through -the OCM protocol. Contacts are stored in Address Books and may be -created through the Invite process or via direct entry. A Contact MAY -of course contain much more detailed information about the referenced -user such as if it was added via Invites or direct entry. - -
- -
Properties - - - addedDate: Timestamp of when contact was added - email: Contact email address (informational) - name: Human-readable display name - userID: The identifier of the contact at their OCM Server - provider: The FQDN of the contact's OCM Server - - -
-
Relationships - - - A Contact may be referenced by one or more Address Books. - - -
-
-
Invite - -The Invite entity represents the bidirectional trust establishment -mechanism in OCM. It facilitates secure contact exchange between users -on different OCM Servers. - -
- -
Properties - - - acceptedTime: Timestamp of invite acceptance (if accepted) - createdTime: Timestamp of invite creation - sender: Reference to the User who sent the Invite - token: Unique, hard-to-guess string generated by Invite Sender - OCM Server - - -
-
Relationships - - - An Invite is generated by an Address Book entry action. - An Invite is associated with exactly one User as the sender. - - -
-
-
Provider - -The Provider entity represents an OCM Server's capabilities and -configuration as discovered through the OCM API Discovery process. It -represents both the Sending Server and Receiving Server roles, and an -implementor might find it useful to have a Provider object model to -store the discovered information about federation peers or other remote -OCM Providers. - -The following diagram is illustrative and non-exhaustive. The single -source of truth for Provider properties is the OCM API Discovery Fields -section; for the box contents below, see the Properties subsection and -the normative capability, criteria, and resource type definitions in -that section. - -
- -
Properties - - - apiVersion: Version string of supported OCM API - capabilities: Optional features supported - criteria: Requirements for accepting Share Creation Notifications - enabled: Boolean indicating if OCM service is active - endPoint: Base URI for OCM API endpoints - provider: Friendly branding name - resourceTypes: Array of supported resource types with protocols - - -
-
-
Share - -The Share entity represents a policy granting access to a Resource -from a Sending Party to a Receiving Party. - -
| Receiving Server | -+------------------+ +------------------+ -| - expiration | | -| - name | | mediates access to -| - owner | v -| - protocol | +------------------+ -| - providerId | | Resource (remote)| -| - requirements[] | +------------------+ -| - resourceType | -| - sender | -| - shareType | -| - shareWith | -| - state | -+------------------+ - | - | governs access to - v -+-----------------+ -| Resource | -+-----------------+ -]]>
- -
Properties - - - expiration: Optional expiration timestamp - name: Human-readable name of the shared Resource - owner: OCM Address of the Resource owner - protocol: Access protocol name and details (webdav, ssh, webapp) - providerId: Unique identifier for the Share at the provider - requirements: Array of access requirements (must-use-mfa, - must-exchange-token) - resourceType: Type of resource (file, folder, calendar, etc.) - sender: OCM Address of the party creating the Share - shareType: Type of recipient (user, group, federation) - shareWith: OCM Address of the Receiving Party - state: Current state of the Share (accepted, pending, deleted) - - -
Share States - - - Accepted: Share accepted, Resource accessible - Deleted: Share removed or expired - Pending: Awaiting acceptance by Receiving Party - - -
-
-
Relationships - - - A Share is created by a User (local). - A Share is received by a User (remote). - A Share governs access to a Resource. - - -
-
-
User - -The User entity represents the party in OCM who can send and receive -Shares and Invites and manage Contacts, and interact with Resources. - -
- -
Properties - - - email: User's email address - name: Human-readable display name - ocmAddress: Full OCM Address - uid: Unique identifier within the OCM Provider - - -
-
Relationships - - - A User owns one or more Address Book(s). - A User issues zero or more Invites. - A User participates in zero or more Shares as Sending or Receiving -Party. - - -
-
-
Resource - -The Resource entity represents the data or service being shared between -OCM Providers. It is the target of Shares and is accessed by the -Receiving Party through the Sending Server's API. In general a Resource -is a much more complex entity, but for the purpose of OCM we only need -to model a few key properties. - -
- -
Properties - - - location: URI or path to access the Resource - owner: Reference to the User who owns the Resource - resourceID: Unique identifier of the Resource - type: Type of Resource (file, folder, calendar, etc.) - - -
-
-
-
Changes - -This section collects the changes with respect to the previous -version in the IETF datatracker. It is meant to ease the review -process and it shall be removed when going to RFC last call. -The complete changelog is updated in the OCM-API GitHub repository. - -
Version 04 - - Clarified that the diagrams in Appendix D are illustrative and -not normative. - Minor formatting fixes. - - -
-
Version 03 - - Fixed formatting of artworks, code blocks and bullet lists. - - -
-
Version 02 - - Added the Changes section. - - -
-
Version 01 - - - Introduced functions, roles, and object models to the specification. - Added support for SSH as a share access method. - Introduced accessType property in shares and removed the datatx -"protocol" in favor of a cleaner access model. - Improved resource access description with token exchange, and -specified request payload format for the /token endpoint. - Added RFC 9421 HTTP Message Signatures support via http-sig -capability and RFC 7515 (JWS) compliant JWKS and prescribed use of -JWS for the Directory Service. - Updated and homogenized capabilities across the specification. - Added JSContact extension to IANA Considerations. - Changed example domain to use cloud.example.org per RFC 2606. - - -
-
-
Acknowledgements - -Our deepest thanks and appreciation go to the people who started the -work on what would become this specification in 2015. In particular we -want to thank (in alphabetical order) Guido Aben, Russell Albert, -Holger Angenent, David Antoš, Hrachya Astsatryan, Kurt Bauer, -Charles du Jeu, Andreas Eckey, David Gillard, Andranik Hayrapetyan Wahi, -Dimitri van Hees, Christoph Herzog, David Jericho, Frank Karlitschek, -Christian Kracher, Ralph Krimmel, Massimo Lamanna, Simon Leinen, -Jari Miettinen, Jakub Moscicki, Frederik Orellana, Vlad Roman, -Christian Schmitz, Woojin Seok, Rogier Spoor, Christian Sprajc, -Peter Szegedi, Ron Trompert, Benedikt Wegmann and Jonathan Xu. - -We would also like to thank Ishank Arora, Gianmaria Del Monte, -Jörn Friedrich Dreyer, Richard Freitag, Hugo González Labrador, -Matthias Kraus, Maxence Lange, Lovisa Lugnegård, Sandro Mesterheide, -Antoon Prins and Björn Schießle for their direct contributions -to the specification. - -Over the years many more people have been involved in the development -of OCM. We would like to thank all of them for their contributions, -including Jean-Thomas Acquaviva, Samuel Alfageme Sainz, -Karsten Asshauer, Miroslav Bauer, Felix Böhm, Maciej Brzeźniak, -Diogo Castro, Gavin Charles Kennedy, Jarosław Czub, Milan Danecek, -Michael D'Silva, Lukasz Dutka, Pedro Ferreira, Renato Furter, -Klaas Freitag, Raman Ganguly, Eva Gergely, Hilary Goodson, Daniel Halbe, -Dave Heyns, Jan Holesovsky, Jan Hornicek, Carina Kemp, Fergus Kerins, -Andreas Klotz, Matthias Knoll, Christian Kracher, Mario Lassnig, -Claudius Laumanns, Anthony Leroy, Patrick Maier, Vladislav Makarenko, -Anna Manou, Rita Meneses, Zheng Meyer-Zhao, Crystal Michelle Chua, -Yoann Moulin, Daniel Müller, Frederik Müller, Rasmus Munk, -Michał Orzechowski, Jacek Pawel Kitowski, Enrique Pérez Arnaud, Iosif -Peterfi, Alessandro Petraro, Rene Ranger, Angelo Romasanta, David -Rousse, Carla Sauvanaud, Klaus Scheibenberger, Marcin Sieprawski, -Tilo Steiger, C.D. Tiwari, Alejandro Unger and Tom Wezepoel. - -Work on this document has been partially funded over the years by -multiple projects and funding agencies: - - - The CS3MESH4EOSC project "Interactive and agile/responsive -sharing mesh of storage, data and applications for EOSC", whose key -result was Science Mesh, received funding from the -European Union's Horizon 2020 research and innovation programme under -Grant Agreement no. 863353. - NLnet through the NGI0 Core Fund, with -financial support from the European Commission's -Next Generation Internet programme under grant agreement -No. 101092990. - The EOSC Data Commons project "Services for inter- and -cross-disciplinary data discovery, access, sharing and reuse in the -EOSC Federation", received funding from the European Union under Grant -Agreement no. 101188179. - Sovereign Tech Agency through the Tech Fund, with -a specific project. - - -
- - -
- - - - - - - - - - - - - - -
-