<?xml version="1.0" encoding="UTF-8"?>
  <?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
  <!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.29 (Ruby 3.2.8) -->


<!DOCTYPE rfc  [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">

]>


<rfc ipr="trust200902" docName="draft-lopresti-open-cloud-mesh-02" category="std" consensus="true">
  <front>
    <title>Open Cloud Mesh</title>

    <author initials="G." surname="Lo Presti" fullname="Giuseppe Lo Presti">
      <organization>CERN</organization>
      <address>
        <email>giuseppe.lopresti@cern.ch</email>
        <uri>http://cern.ch/lopresti</uri>
      </address>
    </author>
    <author initials="M. B." surname="de Jong" fullname="Michiel de Jong">
      <organization>Ponder Source</organization>
      <address>
        <email>michiel@pondersource.com</email>
        <uri>https://pondersource.com</uri>
      </address>
    </author>
    <author initials="M." surname="Baghbani" fullname="Mahdi Baghbani">
      <organization>Ponder Source</organization>
      <address>
        <email>mahdi@pondersource.com</email>
        <uri>https://pondersource.com</uri>
      </address>
    </author>
    <author initials="M." surname="Nordin" fullname="Micke Nordin">
      <organization>SUNET</organization>
      <address>
        <email>kano@sunet.se</email>
        <uri>https://code.smolnet.org/micke</uri>
      </address>
    </author>

    <date year="2025" month="June" day="13"/>

    <area>Security</area>
    
    <keyword>Internet-Draft</keyword>

    <abstract>


<?line 37?>

<t>Open Cloud Mesh 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.</t>

<t>Open Cloud Mesh only handles the necessary interactions up to the point where the Receiving Party is informed that they were granted access to the Resource. The actual resource access is then left to protocols such as WebDAV and others.</t>



    </abstract>



  </front>

  <middle>


<?line 44?>

<section anchor="terms"><name>Terms</name>
<t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED",  "MAY", and
"OPTIONAL" in this document are to be interpreted as described in
RFC 2119.</t>

<t>We define the following concepts (with some non-normative references to related concepts from OAuth and elsewhere):</t>

<t><list style="symbols">
  <t><strong>Resource</strong> - the piece of data or interaction to which access is being granted, e.g. a file, folder, video call, or printer queue</t>
  <t><strong>Share</strong> - a policy rule stating that certain actors are allowed access to a Resource. Also: a record in a database representing this rule</t>
  <t><strong>Sending Party</strong> - a person or party who is authorized to create Shares (similar to "Resource Owner" in OAuth)</t>
  <t><strong>Receiving Party</strong> - a person, group or party who is granted access to the Resource through the Share (similar to "Requesting Party / RqP" in OAuth-UMA)</t>
  <t><strong>Sending Server</strong> - the server that:
  <list style="symbols">
      <t>holds the Resource ("file server" or "Entreprise File Sync and Share (EFSS) server" role),</t>
      <t>provides access to it (by exposing at least one "API"),</t>
      <t>takes the decision to create the Share based on user interface gestures from the Sending Party (the "Authorization Server" role in OAuth)</t>
      <t>takes the decision about authorizing attempts to access the Resource (the "Resource Server" role in OAuth)</t>
      <t>sends out Share Creation Notifications when appropriate (see below)</t>
    </list></t>
  <t><strong>Receiving Server</strong> - the server that:
  <list style="symbols">
      <t>receives Share Creation Notifications (see below)</t>
      <t>actively or passively notifies the receiving user or group of any incoming Share Creation Notification</t>
      <t>acts as an API client, allowing the receiving user to access the Resource through an API (e.g. WebDAV) of the sending server</t>
    </list></t>
  <t><strong>Sending Gesture</strong> - a user interface interaction from the Sending Party to the Sending Server, conveying the intention to create a Share</t>
  <t><strong>Share Creation</strong> - the addition of a Share to the database state of the Sending Server, in response to a successful Sending Gesture or for another reason</t>
  <t><strong>Share Creation Notification</strong> - a server-to-server request from the sending server to the receiving server, notifying the receiving server that a Share has been created</t>
  <t><strong>FQDN</strong> - Fully Qualified Domain Name, such as <spanx style="verb">"cloud.example.com"</spanx></t>
  <t><strong>OCM Server</strong> - a server that supports OCM.</t>
  <t><strong>Discovering Server</strong> - a server that tries to obtain information in OCM API discovery</t>
  <t><strong>Discoverable Server</strong> - a server that tries to supply information in OCM API discovery</t>
  <t><strong>OCM Address</strong> - a string of the form <spanx style="verb">&lt;Receiving Party's identifier&gt;@&lt;fqdn&gt;</spanx> which can be used to uniquely identify a user or group "at" an OCM Server. <spanx style="verb">&lt;Receiving Party's identifier&gt;</spanx> is an opaque string,
unique at the server. <spanx style="verb">&lt;fqdn&gt;</spanx> is the Fully Qualified Domain Name by which the server is identified. This MUST be the domain at which the <spanx style="verb">/.well-known/ocm</spanx> endpoint of that server is hosted.</t>
  <t><strong>OCM Notification</strong> - a message from the Receiving Server to the Sending Server or vice versa, using the OCM Notifications endpoint.</t>
  <t><strong>Invite Message</strong> - 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</t>
  <t><strong>Invite Sender</strong> - the party sending an Invite</t>
  <t><strong>Invite Receiver</strong> - the party receiving an Invite</t>
  <t><strong>Invite Sender OCM Server</strong> - the server holding an address book used by the Invite Sender, to which details of the Invite Receiver are to be added</t>
  <t><strong>Invite Receiver OCM Server</strong> - the server holding an address book used by the Invite Receiver, to which details of the Invite Sender are to be added</t>
  <t><strong>Invite Token</strong> - 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</t>
  <t><strong>Invite Creation Gesture</strong> - gesture from the Invite Sender to the Invite Sender OCM Server, resulting in the creation of an Invite Token.</t>
  <t><strong>Invite Acceptance Gesture</strong> - 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.</t>
  <t><strong>Invite Acceptance Request</strong> - 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.</t>
  <t><strong>Invite Acceptance Response</strong> - HTTP response to the Invite Acceptance Request</t>
  <t><strong>Share Name</strong> - 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</t>
  <t><strong>Share Permissions</strong> - protocol-specific allowances granted to the Receiving Party on the modes of accessing the Resource</t>
  <t><strong>Share Requirements</strong> - protocol-specific restrictions on the modes of accessing the Resource</t>
  <t><strong>WAYF Page</strong> - a Where-Are-You-From page is a discovery service used to identify the OCM Server of an Invite Receiver</t>
  <t><strong>Directory Service</strong> - a third-party service that exposes a list of trusted OCM Servers</t>
</list></t>

</section>
<section anchor="general-flow"><name>General Flow</name>
<t>The lifecycle of an Open Cloud Mesh Share starts with prerequisites such as
establishing trust, establishing contact, and OCM API discovery.</t>

<t>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.</t>

<t>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. After that, the Share may be updated, deleted, and/or reshared.</t>

</section>
<section anchor="establishing-contact"><name>Establishing Contact</name>
<t>Before the Sending Server can send a Share Creation Notification to the Receiving Server, it needs to 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.</t>

<section anchor="direct-entry"><name>Direct Entry</name>
<t>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.</t>

</section>
<section anchor="address-books"><name>Address books</name>
<t>The Sending Server MAY offer the Sending Party 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.</t>

</section>
<section anchor="public-link-flow"><name>Public Link Flow</name>
<t>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.</t>

</section>
<section anchor="public-invite-flow"><name>Public Invite Flow</name>
<t>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.</t>

</section>
<section anchor="invite-flow"><name>Invite Flow</name>
<t>### 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.</t>

<t>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</t>

<section anchor="steps"><name>Steps</name>

<t><list style="symbols">
  <t>the Invite Sender OCM Server generates a unique Invite Token and helps the Invite Sender to create the Invite Message</t>
  <t>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</t>
  <t>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 Gesture without manually copying the Invite Token.</t>
  <t>the Invite Receiver OCM Server discovers the OCM API of the Invite Sender OCM Server using generic OCM API Discovery (see section below)</t>
  <t>the Invite Receiver OCM Server sends the Invite Acceptance Request to the Invite Sender OCM Server</t>
</list></t>

</section>
<section anchor="invite-acceptance-request-details"><name>Invite Acceptance Request Details</name>
<t>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:</t>

<t><list style="symbols">
  <t>to the <spanx style="verb">/invite-accepted</spanx> path in the Invite Sender OCM Server's OCM API</t>
  <t>using <spanx style="verb">application/json</spanx> as the <spanx style="verb">Content-Type</spanx> HTTP request header</t>
  <t>its request body containing a JSON document representing an object with the following string fields:
  <list style="symbols">
      <t>REQUIRED: <spanx style="verb">recipientProvider</spanx> - FQDN of the Invite Receiver OCM Server</t>
      <t>REQUIRED: <spanx style="verb">token</spanx> - the Invite Token. The Invite Sender OCM Server SHOULD recall which Invite Sender OCM Address this token was linked to</t>
      <t>REQUIRED: <spanx style="verb">userID</spanx> - the Invite Receiver's identifier at their OCM Server</t>
      <t>REQUIRED: <spanx style="verb">email</spanx> - non-normative / informational; an email address for the Invite Receiver. Not necessarily at the same FQDN as their OCM Server</t>
      <t>REQUIRED: <spanx style="verb">name</spanx> - human-readable name of the Invite Receiver, as a suggestion for display in the Invite Sender's address book</t>
    </list></t>
  <t>using TLS</t>
  <t>using <eref target="https://datatracker.ietf.org/doc/html/draft-cavage-http-signatures-12">httpsig</eref></t>
</list></t>

<t>The Invite Receiver OCM Server SHOULD apply its own policies for trusting the Invite Sender OCM Server before making the Invite Acceptance Request.</t>

<t>Since the Invite Flow does not require either Party to type or remember the <spanx style="verb">userID</spanx>, 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 <spanx style="verb">userID</spanx> that forms part of their OCM Address does not need to match it.</t>

<t>Also, a different <spanx style="verb">userID</spanx> could be given out to each contact, to avoid correlation of identities.</t>

<t>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.</t>

<t>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.</t>

</section>
<section anchor="invite-acceptance-response-details"><name>Invite Acceptance Response Details</name>
<t>The Invite Acceptance Response SHOULD be a HTTP response:</t>

<t><list style="symbols">
  <t>in response to the Invite Acceptance Request</t>
  <t>using <spanx style="verb">application/json</spanx> as the <spanx style="verb">Content-Type</spanx> HTTP response header</t>
  <t>its response body containing a JSON document representing an object with the following string fields:
  <list style="symbols">
      <t>REQUIRED: <spanx style="verb">userID</spanx> - the Invite Sender's identifier at their OCM Server</t>
      <t>REQUIRED: <spanx style="verb">email</spanx> - non-normative / informational; an email address for the Invite Sender. Not necessarily at the same FQDN as their OCM Server</t>
      <t>REQUIRED: <spanx style="verb">name</spanx> - human-readable name of the Invite Sender, as a suggestion for display in the Invite Receiver's address book</t>
    </list></t>
</list></t>

<t>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.</t>

<t>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.</t>

<t>As with the <spanx style="verb">userID</spanx> 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.</t>

</section>
<section anchor="addition-into-address-books"><name>Addition into address books</name>
<t>Following these step, both servers MAY display the <spanx style="verb">name</spanx> 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.</t>

<t>Both servers MAY also allowlist each other as a server with which at least one of their users wishes to interact.</t>

<t>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.</t>

<t>Both parties may delete the other party from their address book at any time without notifying them.</t>

</section>
<section anchor="security-advantages"><name>Security Advantages</name>
<t>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.</t>

<t>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.</t>

<t>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.</t>

<t>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.</t>

</section>
</section>
</section>
<section anchor="ocm-api-discovery"><name>OCM API Discovery</name>
<t>## Introduction
After establishing contact as discussed in the previous section, the Sharing User can send the Share Creation Gesture to the Sending Server, providing the Sending Server with the following information:</t>

<t><list style="symbols">
  <t>Resource to be shared</t>
  <t>Protocol to be offered for access</t>
  <t>Sending Party's identifier</t>
  <t>Receiving Party's identifier</t>
  <t>Receiving Server FQDN</t>
  <t>OPTIONAL: Share Requirements</t>
  <t>OPTIONAL: Share Name</t>
  <t>OPTIONAL: Share Permissions</t>
</list></t>

<t>The next step is for the Sending Server to additionally discover:</t>

<t><list style="symbols">
  <t>if the Receiving Server is trusted</t>
  <t>if the Receiving Server supports OCM</t>
  <t>if so, which version and with which optional functionality</t>
  <t>at which URL</t>
  <t>the public key the Receiving Server will use for HTTP Signatures (if any)</t>
</list></t>

<t>The Sending Server MAY first perform denylist and allowlist checks on the FQDN.</t>

<t>If a finite allowlist of Receiving Servers exists on the Sending Server side, then this list may already contain all necessary information.</t>

<t>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.</t>

<t>This process MAY be influenced by a VPN connection and/or IP allowlisting.</t>

<t>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'.</t>

<section anchor="process"><name>Process</name>
<t>At the start of the process, the Discovering Server has either an OCM Address, or just an FQDN from for instance the <spanx style="verb">recipientProvider</spanx> field of an Invite Acceptance Request.</t>

<t>Step 1: In case it has an OCM Address, it should first extract <spanx style="verb">&lt;fqdn&gt;</spanx> from it (the part after the last <spanx style="verb">@</spanx> sign).
Step 2: The Discovering Server SHOULD attempt OCM API discovery a HTTP GET request to <spanx style="verb">https://&lt;fqdn&gt;/.well-known/ocm</spanx>.
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 <spanx style="verb">https://&lt;fqdn&gt;/ocm-provider</spanx> 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.
Step 7: The JSON response body is the data that was discovered.</t>

</section>
<section anchor="fields"><name>Fields</name>
<t>The JSON response body offered by the Discoverable Server SHOULD contain the following information about its OCM API:</t>

<t><list style="symbols">
  <t>REQUIRED: enabled (boolean) - Whether the OCM service is enabled at this endpoint</t>
  <t>REQUIRED: apiVersion (string) - The OCM API version this endpoint supports. Example: <spanx style="verb">"1.2.0"</spanx></t>
  <t>REQUIRED: endPoint (string) - The URI of the OCM API available at this endpoint. Example: <spanx style="verb">"https://my-cloud-storage.org/ocm"</spanx></t>
  <t>OPTIONAL: provider (string) - A friendly branding name of this endpoint. Example: <spanx style="verb">"MyCloudStorage"</spanx></t>
  <t>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 should
itself be an object containing the following fields:
  <list style="symbols">
      <t>name (string) -  A supported resource type (file, folder, calendar, contact, ...).
            Implementations MUST offer support for at least one resource type, where <spanx style="verb">file</spanx> is the commonly supported one. Each resource type is identified by its <spanx style="verb">name</spanx>:
            the list MUST NOT contain more than one resource type object per given <spanx style="verb">name</spanx>.</t>
      <t>shareTypes (array of string) -
            The supported recipient share types.
            MUST contain <spanx style="verb">"user"</spanx> at a minimum, plus optionally <spanx style="verb">"group"</spanx> and <spanx style="verb">"federation"</spanx>.
            Example: <spanx style="verb">["user"]</spanx></t>
      <t>protocols (object) - The supported protocols for accessing shared resources of this type.
            Implementations that offer <spanx style="verb">file</spanx> resources MUST support at least <spanx style="verb">webdav</spanx>,
            any other combination of resources and protocols is optional. Example:
            <spanx style="verb">json
            {
              "webdav": "/remote/dav/ocm/",
              "webapp": "/app/ocm/",
              "talk": "/apps/spreed/api/"
            }
           </spanx>
            Fields:
      <list style="symbols">
          <t>webdav (string) - The top-level WebDAV path at this endpoint. In order to access
              a remote shared resource, implementations MAY use this path
              as a prefix, or as the full path (see sharing examples).</t>
          <t>webapp (string) - The top-level path for web apps at this endpoint. This value
              is provided for documentation purposes, and it SHALL NOT
              be intended as a prefix for share requests.</t>
          <t>datatx (string) - The top-level path to be used for data transfers. This
              value is provided for documentation purposes, and it SHALL
              NOT be intended as a prefix. In addition, implementations
              are expected to execute the transfer using WebDAV as
              the wire protocol.</t>
          <t>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.</t>
        </list></t>
    </list></t>
  <t>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: <spanx style="verb">["receive-code", "webdav-uri"]</spanx>. The array MAY include for instance:
  <list style="symbols">
      <t><spanx style="verb">"enforce-mfa"</spanx> - to indicate that this OCM Server can apply a Sending Server's MFA requirements for a Share on their behalf.</t>
      <t><spanx style="verb">"webdav-uri"</spanx> - to indicate that this OCM Server can append a relative URI to the path listed for WebDAV in the appropriate <spanx style="verb">resourceTypes</spanx> entry</t>
      <t><spanx style="verb">"protocol-object"</spanx> - to indicate that this OCM Server can receive a Share Creation Notification whose <spanx style="verb">protocol</spanx> object contains one property per supported protocol instead of containing the standard <spanx style="verb">name</spanx> and <spanx style="verb">options</spanx> properties.</t>
      <t><spanx style="verb">"invites"</spanx> - 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.</t>
      <t><spanx style="verb">"receive-code"</spanx> - to indicate that this OCM Server can receive a <spanx style="verb">code</spanx> as part of a Share Creation Notification, and exchange it for a bearer token at the Sending Server's <spanx style="verb">/token</spanx> API endpoint.</t>
      <t><spanx style="verb">"invite-wayf"</spanx> - to indicate that this OCM Server exposes a WAYF Page to facilitate the Invite flow.</t>
    </list></t>
  <t>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: <spanx style="verb">["http-request-signatures", "code"]</spanx>. The array MAY include for instance:
  <list style="symbols">
      <t><spanx style="verb">"http-request-signatures"</spanx> - to indicate that API requests without http signatures will be rejected.</t>
      <t><spanx style="verb">"code"</spanx> - to indicate that API requests without code will be rejected (i.e. the <spanx style="verb">sharedSecret</spanx> in the protocol details will be ignored).</t>
      <t><spanx style="verb">"denylist"</spanx> - some servers may be blocked based on their IP address</t>
      <t><spanx style="verb">"allowlist"</spanx> - unknown servers may be blocked based on their IP address</t>
      <t><spanx style="verb">"invite"</spanx> - an invite must have been exchanged between the sender and the receiver before a Share Creation Notification can be sent</t>
    </list></t>
  <t>OPTIONAL: publicKey (object) - The signatory used to sign outgoing request to confirm its origin. The 
        signatory is optional, but if present, it MUST contain two string fields, <spanx style="verb">id</spanx> and <spanx style="verb">publicKeyPem</spanx>.
      properties:
  <list style="symbols">
      <t>REQUIRED id (string) unique id of the key in URI format. The hostname set the origin of the 
          request and MUST be identical to the current discovery endpoint.
        Example: https://my-cloud-storage.org/ocm#signature</t>
      <t>REQUIRED publicKeyPem (string) - PEM-encoded version of the public key.
        Example: "-----BEGIN PUBLIC KEY-----\nMII...QDD\n-----END PUBLIC KEY-----\n"</t>
    </list></t>
  <t>OPTIONAL: inviteAcceptDialog (string) - URL path of a web page where a user can accept an invite, when query parameters <spanx style="verb">"token"</spanx> and <spanx style="verb">"providerDomain"</spanx> are provided. Implementations that offer the <spanx style="verb">"invites"</spanx> capability SHOULD provide this URL as well in order to enhance the UX of the Invite Flow. If for example <spanx style="verb">"/index.php/apps/sciencemesh/accept"</spanx> is specified here then a WAYF Page SHOULD redirect the end-user to <spanx style="verb">/index.php/apps/sciencemesh/accept?token=zi5kooKu3ivohr9a&amp;providerDomain=example.com</spanx>.</t>
</list></t>

</section>
</section>
<section anchor="share-creation-notification"><name>Share Creation Notification</name>
<t>To create a share, the sending server SHOULD make a HTTP POST request</t>

<t><list style="symbols">
  <t>to the <spanx style="verb">/shares</spanx> path in the Receiving Server's OCM API</t>
  <t>using <spanx style="verb">application/json</spanx> as the <spanx style="verb">Content-Type</spanx> HTTP request header</t>
  <t>its request body containing a JSON document representing an object with the fields as described below</t>
  <t>using TLS</t>
  <t>using <eref target="https://datatracker.ietf.org/doc/html/draft-cavage-http-signatures-12">httpsig</eref></t>
</list></t>

<section anchor="fields-1"><name>Fields</name>

<t><list style="symbols">
  <t>REQUIRED shareWith (string)
        Consumer specific identifier of the user, group or federation the provider
        wants to share the resource with. This is known in advance.
        Please note that the consumer service endpoint is known in advance
        as well, so this is no part of the request body.
      Example: "51dc30ddc473d43a6011e9ebba6ca770@geant.org"</t>
  <t>REQUIRED name (string)
     Name of the resource (file or folder).
      Example: "resource.txt"</t>
  <t>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."</t>
  <t>REQUIRED providerId (string)
        Identifier to identify the shared resource at the provider side. This is
        unique per provider such that if the same resource is shared twice,
        this providerId will not be repeated.
      Example: 7c084226-d9a1-11e6-bf26-cec0c932ce01</t>
  <t>REQUIRED owner (string) -
        Provider specific identifier of the user who owns the resource.
      Example: "6358b71804dfa8ab069cf05ed1b0ed2a@apiwise.nl"</t>
  <t>REQUIRED sender (string) -
        Provider specific identifier of the user that wants to share the
        resource. Please note that the requesting provider is being
        identified on a higher level, so the former <spanx style="verb">remote</spanx> property
        is not part of the request body.
      Example: "527bd5b5d689e2c32ae974c6229ff785@apiwise.nl"</t>
  <t>OPTIONAL ownerDisplayName (string)
        Display name of the owner of the resource
      Example: "Dimitri"</t>
  <t>OPTIONAL senderDisplayName (string)
        Display name of the user that wants to share the resource
      Example: "John Doe"</t>
  <t>REQUIRED shareType (string)
      SHOULD have a value of "user", "group", or "federation", to indicated that the first part
      of the <spanx style="verb">shareWith</spanx> OCM Address refers to a Receiving Party who is a single user of the Receiving Server,
      a group of users at the Receiving Servers, or a group of users that is spread out over various servers,
      including at least one user at the Receiving Server.</t>
  <t>REQUIRED resourceType (string)
        Resource type (file, folder, calendar, contact, ...)</t>
  <t>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.</t>
  <t>OPTIONAL code (string)
        A nonce to be exchanged for a (potentially short-lived) bearer token at the Sending Server's /token endpoint.</t>
  <t>REQUIRED protocol (object)
        JSON object with specific options for each protocol.
        The supported protocols are:
        - <spanx style="verb">webdav</spanx>, to access the data
        - <spanx style="verb">webapp</spanx>, to access remote web applications
        - <spanx style="verb">datatx</spanx>, to transfer the data to the remote endpoint  <vspace blankLines='1'/>
    <figure><artwork><![CDATA[
    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`.
]]></artwork></figure>
  </t>
</list></t>

<t>If <spanx style="verb">multi</spanx> is given, one or more protocol
                endpoints are expected to be defined according to the optional
                properties specified below.
                Otherwise, at least <spanx style="verb">webdav</spanx> is expected to be supported, and
                its options MAY be given in the opaque <spanx style="verb">options</spanx> 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 <spanx style="verb">webdav</spanx> and <spanx style="verb">multi</spanx>, but v1.0 servers MAY
                only support <spanx style="verb">webdav</spanx>.</t>

<t><list style="symbols">
  <t>Protocol details for <spanx style="verb">webdav</spanx> MAY contain:
  <list style="symbols">
      <t>REQUIRED uri (string)
             An URI to access the remote resource. The URI SHOULD be relative,
             in which case the prefix exposed by the <spanx style="verb">/.well-known/ocm</spanx> endpoint MUST
             be used. Absolute URIs are deprecated.</t>
      <t>OPTIONAL sharedSecret (string) - required if no <spanx style="verb">code</spanx> field is given for the Share as a whole (see above).
             An optional 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.</t>
      <t>OPTIONAL permissions (array of strings) -
               The permissions granted to the sharee. A subset of:
               - <spanx style="verb">read</spanx> allows read-only access including download of a copy.
               - <spanx style="verb">write</spanx> allows create, update, and delete rights on the resource.
               - <spanx style="verb">share</spanx> allows re-share rights on the resource.</t>
      <t>OPTIONAL requirements (array of strings) -
               The requirements that the sharee MUST fulfill to access the resource. A subset of:
               - <spanx style="verb">mfa-enforced</spanx> requires the consumer to be MFA-authenticated. This
                 MAY be used if the recipient provider exposes the <spanx style="verb">enforce-mfa</spanx> capability.
               - <spanx style="verb">use-code</spanx> requires the consumer to exchange the given <spanx style="verb">code</spanx> via a
                 signed HTTPS request. This MAY be used if the recipient provider exposes
                 the <spanx style="verb">receive-code</spanx> capability.</t>
    </list></t>
  <t>Protocol details for <spanx style="verb">webapp</spanx> MAY contain:
  <list style="symbols">
      <t>REQUIRED uri (string)
             An 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 <spanx style="verb">/.well-known/ocm</spanx>
             endpoint MUST be used. Absolute URIs are deprecated.</t>
      <t>REQUIRED viewMode (string)
             The permissions granted to the sharee. A subset of:
             - <spanx style="verb">view</spanx> allows access to the web app in view-only mode.
             - <spanx style="verb">read</spanx> allows read and download access via the web app.
             - <spanx style="verb">write</spanx> allows full editing rights via the web app.</t>
      <t>OPTIONAL sharedSecret (string)
             An optional secret to be used to access the remote web app,
             for example in the form of a bearer token.</t>
    </list></t>
  <t>Protocol details for <spanx style="verb">datatx</spanx> MAY contain:
  <list style="symbols">
      <t>REQUIRED srcUri (string)
             An URI to access the remote resource. The URI SHOULD be relative,
             in which case the prefix exposed by the <spanx style="verb">/.well-known/ocm</spanx> endpoint MUST
             be used. Absolute URIs are deprecated.</t>
      <t>OPTIONAL sharedSecret (string)
             An optional secret to be used to access the resource,
             for example in the form of a bearer token.
             To prevent leaking it in logs it MUST NOT appear in any URI.</t>
      <t>OPTIONAL size (integer)
             The size of the file to be transferred from the sending server.</t>
    </list></t>
</list></t>

</section>
<section anchor="decision-to-discard"><name>Decision to Discard</name>
<t>The Receiving Server MAY discard the notification if any of the following hold true:</t>

<t><list style="symbols">
  <t>the HTTP Signature is missing but the Sending Server does expose a keypair discoverable from the FQDN part of the <spanx style="verb">sender</spanx> field in the request body</t>
  <t>the HTTP Signature is missing</t>
  <t>the HTTP Signature is not valid</t>
  <t>no keypair is trusted or discoverable from the FQDN part of the <spanx style="verb">sender</spanx> field in the request body</t>
  <t>the keypair used to generate the HTTP Signature doesn't match the one trusted or discoverable from the FQDN part of the <spanx style="verb">sender</spanx> field in the request body</t>
  <t>the Sending Server is denylisted</t>
  <t>the Sending Server is not allowlisted</t>
  <t>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)</t>
  <t>the Receiving Server is unable to act as an API client for (any of) the protocol(s) listed for accessing the resource</t>
  <t>an initial check shows that the resource cannot successfully be accessed through (any of) the protocol(s) listed</t>
</list></t>

</section>
</section>
<section anchor="receiving-party-notification"><name>Receiving Party Notification</name>
<t>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.</t>

<t>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.</t>

</section>
<section anchor="share-acceptance-notification"><name>Share Acceptance Notification</name>
<t>In response to a Share Creation Notification, the Receiving Server MAY discover the OCM API of the Sending Server,
starting from the <spanx style="verb">&lt;fqdn&gt;</spanx> part of the <spanx style="verb">sender</spanx> field in the Share Creation Notification.</t>

<t>If the OCM API of the Sending Server is successfully discovered, the Receiving Server MAY
make a HTTP POST request</t>

<t><list style="symbols">
  <t>to the <spanx style="verb">/notifications</spanx> path in the Sending Server's OCM API</t>
  <t>using <spanx style="verb">application/json</spanx> as the <spanx style="verb">Content-Type</spanx> HTTP request header</t>
  <t>its request body containing a JSON document representing an object with the fields as described below</t>
  <t>using TLS</t>
  <t>using <eref target="https://datatracker.ietf.org/doc/html/draft-cavage-http-signatures-12">httpsig</eref></t>
</list></t>

<section anchor="fields-2"><name>Fields</name>

<t><list style="symbols">
  <t>REQUIRED notificationType (string) - in a Share Acceptance Notification it SHOULD be one of:
  <list style="symbols">
      <t>'SHARE_ACCEPTED'</t>
      <t>'SHARE_DECLINED'</t>
    </list></t>
  <t>REQUIRED providerId (string) - copied from the Share Creation Notification for the Share this notification is about</t>
  <t>OPTIONAL resourceType (string) - copied from the Share Creation Notification for the Share this notification is about</t>
  <t>OPTIONAL notification (object) - optional additional parameters, depending on the notification and the resource type</t>
</list></t>

<section anchor="receiving-party-notification-1"><name>Receiving Party Notification</name>
<t>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.</t>

<t>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.</t>

</section>
</section>
</section>
<section anchor="resource-access"><name>Resource Access</name>
<t>To access the Resource, the Receiving Server MAY use multiple ways, depending on the body of the Share Creation Notification. The procedure is as follows:
1. The receiver MUST extract the OCM Server FQDN from the <spanx style="verb">sender</spanx> field of the received share, and MUST query the <xref target="ocm-api-discovery">Discovery</xref> endpoint at that address: the <spanx style="verb">resourceTypes[0].protocols.webdav</spanx> value is the <spanx style="verb">&lt;sender-ocm-path&gt;</spanx> to be used in step 3.
2. If <spanx style="verb">code</spanx> is not empty, the receiver SHOULD make a signed POST request to the <spanx style="verb">/token</spanx> path inside the Sending Server's OCM API, to exchange the code for a short-lived bearer token, and then use that bearer token to access the Resource.
3. If <spanx style="verb">protocol.name</spanx> = <spanx style="verb">webdav</spanx>, the receiver SHOULD inspect the <spanx style="verb">protocol.options</spanx> property. If it contains a <spanx style="verb">sharedSecret</spanx>, as in the <eref target="https://cs3org.github.io/OCM-API/docs.html?branch=develop&amp;repo=OCM-API&amp;user=cs3org#/paths/~1shares/post">legacy example</eref>, then the receiver SHOULD make a HTTP PROPFIND request to <spanx style="verb">https://&lt;sharedSecret&gt;:@&lt;sender-host&gt;&lt;sender-ocm-path&gt;</spanx>. Note that this access method, based on Basic Auth, is <em>deprecated</em> and may be removed in a future release of the Protocol.
4. Otherwise, if <spanx style="verb">protocol.name</spanx> = <spanx style="verb">multi</spanx>, the receiver MUST inspect the <spanx style="verb">protocol.webdav.uri</spanx> property: if it's a complete URI, the receiver MUST make a HTTP PROPFIND request against it to access the remote resource. If it only contains an identifier <spanx style="verb">&lt;key&gt;</spanx>, the receiver MUST make a HTTP PROPFIND request to <spanx style="verb">https://&lt;sender-host&gt;&lt;sender-ocm-path&gt;/&lt;key&gt;</spanx> in order to access the remote resource. Additionally, the receiver MUST pass an <spanx style="verb">Authorization: bearer</spanx> header with either the short-lived bearer token obtained in step 2, if applicable, or the <spanx style="verb">protocol.webdav.sharedSecret</spanx> value.</t>

<t>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 <spanx style="verb">https://&lt;sender-host&gt;&lt;sender-ocm-path&gt;/path/to/resource.txt</spanx>.</t>

<t>Additionally, if <spanx style="verb">protocol.&lt;protocolname&gt;.requirements</spanx> includes <spanx style="verb">mfa-enforced</spanx>, the Receiving Server MUST ensure that the Receiving Party has been authenticated with MFA, or prompt the consmer in order to elevate their session, if applicable.</t>

</section>
<section anchor="share-deletion"><name>Share Deletion</name>
<t>A <spanx style="verb">"SHARE_ACCEPTED"</spanx> notification followed by a <spanx style="verb">"SHARE_UNSHARED"</spanx> notification is
equivalent to a <spanx style="verb">"SHARE_DECLINED"</spanx> notification.</t>

<t>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.</t>

</section>
<section anchor="share-updating"><name>Share Updating</name>
<t>Some implementations have experimented with a <spanx style="verb">"RESHARE_CHANGE_PERMISSION"</spanx>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.</t>

</section>
<section anchor="resharing"><name>Resharing</name>
<t>The <spanx style="verb">"REQUEST_RESHARE"</spanx> and <spanx style="verb">"RESHARE_UNDO"</spanx> 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.</t>

</section>
<section anchor="appendix-a-multi-factor-authentication"><name>Appendix A: Multi Factor Authentication</name>
<t>If a Receiving Server exposes the capability <spanx style="verb">enforce-mfa</spanx>, 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 <spanx style="verb">mfa-enforced</spanx> 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 <spanx style="verb">mfa-enforced</spanx> requirement, if the Receiving Party has not provided a second factor to establish their identity with greater confidence.</t>

<t>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 <eref target="https://sciencemesh.io">ScienceMesh</eref> integration for the <xref target="invite-flow">Invite</xref> capability may be envisaged.</t>

</section>
<section anchor="appendix-b-request-signing"><name>Appendix B: Request Signing</name>

<t>A request is signed by adding the signature in the headers. The sender also needs to expose the public key used to generate the signature. The receiver can then validate the signature and therefore the origin of the request.
To help debugging, it is recommended to also add all properties used in the signature as headers, even if they can easily be re-generated from the payload.</t>

<t>Note: Signed requests prove the identity of the sender but do not encrypt nor affect its payload.</t>

<t>Here is an example of headers needed to sign a request.</t>

<figure><artwork><![CDATA[
  {
    "(request-target)": "post /path",
    "content-length": 380,
    "date": "Mon, 08 Jul 2024 14:16:20 GMT",
    "digest": "SHA-256=U7gNVUQiixe5BRbp4Tg0xCZMTcSWXXUZI2\\/xtHM40S0=",
    "host": "hostname.of.the.recipient",
    "Signature": "keyId=\"https://author.hostname/key\",algorithm=\"rsa-sha256\",headers=\"content-length date digest host\",signature=\"DzN12OCS1rsA[...]o0VmxjQooRo6HHabg==\""
  }
]]></artwork></figure>

<t><list style="symbols">
  <t>'(request-target)' contains the reached endpoint and the used method,</t>
  <t>'content-length' is the total length of the payload of the request,</t>
  <t>'date' is the date and time when the request has been sent,</t>
  <t>'digest' is a checksum of the payload of the request,</t>
  <t>'host' is the hostname of the recipient of the request (remote when signing outgoing request, local on incoming request),</t>
  <t>'Signature' contains the signature generated using the private key and details on its generation:
  <list style="symbols">
      <t>'keyId' is a unique id, formatted as an url. hostname is used to retrieve the public key via custom discovery</t>
      <t>'algorithm' specify the algorithm used to generate signature</t>
      <t>'headers' specify the properties used when generating the signature</t>
      <t>'signature' the signature of an array containing the properties listed in 'headers'. Some properties like content-length, date, digest, and host are mandatory to protect against authenticity override.</t>
    </list></t>
</list></t>

<section anchor="how-to-generate-the-signature-for-outgoing-request"><name>How to generate the Signature for outgoing request</name>

<t>After properties are set in the headers, the Signature is generated and added to the list.</t>

<t>This is a pseudo-code example for generating the <spanx style="verb">Signature</spanx> header for outgoing requests:</t>

<figure><artwork><![CDATA[
headers = {
    '(request-target)': 'post /path',
    'content-length': length_of(payload),
    'date': current_gmt_datetime(),  # Use a function to get the current GMT date as 'D, d M Y H:i:s T'
    'digest': 'SHA-256=' + base64_encode(hash('sha256', utf8_encode(payload))),
    'host': 'recipient-fqdn',
}

signed = ssl_sign(concatenate_with_newlines(headers), private_key, 'sha256')
signature = {
    'keyId': 'sender-fqdn',  # The sending server's FQDN; find its public key through OCM API discovery
    'algorithm': 'rsa-sha256',
    'headers': 'content-length date digest host',
    'signature': signed,
}

headers['Signature'] = format_signature(signature)
]]></artwork></figure>

</section>
<section anchor="how-to-confirm-signature-on-incoming-request"><name>How to confirm Signature on incoming request</name>

<t>The first step would be to confirm the validity of each properties:</t>

<t><list style="symbols">
  <t><spanx style="verb">(request-target)</spanx> and <spanx style="verb">host</spanx> are immutable to the type of the request and the local/current host,</t>
  <t><spanx style="verb">content-length</spanx> and <spanx style="verb">digest</spanx> can be re-generated and compared from the payload of the request,</t>
  <t>a maximum TTL must be applied to <spanx style="verb">date</spanx> and current timestamp,</t>
  <t>regarding data contained in the <spanx style="verb">Signature</spanx> header:
  <list style="symbols">
      <t>using <spanx style="verb">keyId</spanx> to get the public key from remote signatory,</t>
      <t><spanx style="verb">headers</spanx> is used to generate the clear version of the signature and must contain at least <spanx style="verb">content-length</spanx>, <spanx style="verb">date</spanx>, <spanx style="verb">digest</spanx> and <spanx style="verb">host</spanx>,</t>
      <t><spanx style="verb">signature</spanx> is the encrypted version of the signature.</t>
    </list></t>
</list></t>

<t>Here is an example of how to verify the signature using the headers, the signature and the public key:</t>

<figure><artwork><![CDATA[
clear = {
    '(request-target)': 'post /path',
    'content-length': length_of(payload),
    'date': 'Mon, 08 Jul 2024 14:16:20 GMT',  # The date used in the verification process
    'digest': 'SHA-256=' + base64_encode(hash('sha256', utf8_encode(payload))),  # Recompute the digest for verification
    'host': 'sender-fqdn',
}

signed = headers['Signature']
verification_result = ssl_verify(concatenate_with_newlines(clear), signed, public_key, 'sha256')

if not verification_result then
    raise InvalidSignatureException
]]></artwork></figure>

</section>
<section anchor="validating-the-payload"><name>Validating the payload</name>

<t>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.</t>

<t>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.</t>

</section>
</section>
<section anchor="appendix-c-directory-service"><name>Appendix C: Directory Service</name>

<t>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 HTTP GET, a JSON document with the following format:
  * REQUIRED: <spanx style="verb">federation</spanx> - a human-readable name for the list of OCM Servers exposed by the Directory Service
  * REQUIRED: <spanx style="verb">servers</spanx> - a JSON array of objects to describe the list of OCM Servers with the following string fields:
    * REQUIRED: <spanx style="verb">url</spanx> - the OCM Server's FQDN
    * REQUIRED: <spanx style="verb">displayName</spanx> - a human-readable name for the OCM Server
  Example:
  <spanx style="verb">json
  {
    "federation" : "The ScienceMesh Directory",
    "servers" : [
      {
       "url" : "https://ocm-server-1.fqdn",
       "displayName" : "OCM Server 1"
      },
      {
       "url" : "https://ocm-server-2.fqdn",
       "displayName" : "OCM Server 2"
      }
    ]
  }
 </spanx></t>

</section>
<section anchor="acknowledgements"><name>Acknowledgements</name>

<t>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, 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 Johnatan Xu.</t>

<t>We would also like to thank Ishank Arora, Gianmaria Del Monte, Jörn Friedrich Dreyer, Hugo González Labrador, Maxence Lange, Lovisa Lugnegård, Sandro Mesterheide, Antoon Prins and Björn Schissle for their direct contributions to the specification.</t>

<t>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, Iosif Peterfi, Alessandro Petraro, Rene Ranger, Angelo Romasanta, David Rousse, Carla Sauvanaud, Klaus Scheibenberger, Christian Schmitz, Marcin Sieprawski, Tilo Steiger, C.D. Tiwari, Alejandro Unger and Tom Wezepoel.</t>

</section>


  </middle>

  <back>








  </back>

<!-- ##markdown-source:
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
0f5Ov9OrQmPfs9FoRFrw4P8D2Ar4WHbFAAA=

-->

</rfc>

