<?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.9) -->


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

]>


<rfc ipr="trust200902" docName="draft-lopresti-open-cloud-mesh-07" category="std" consensus="true" submissionType="IETF">
  <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.org</email>
        <uri>https://pondersource.com</uri>
      </address>
    </author>
    <author initials="M." surname="Baghbani" fullname="Mahdi Baghbani">
      <organization>Ponder Source</organization>
      <address>
        <email>mahdi@pondersource.org</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="November" day="02"/>

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

    <abstract>


<?line 38?>

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

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

<t>While this scenario is illustrative, OCM is designed to support a
broader range of interactions, including but not limited to file
transfers.</t>

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



    </abstract>



  </front>

  <middle>


<?line 60?>

<section anchor="introduction"><name>Introduction</name>

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

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

<t>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 uses those connections to establish contact between
their respective OCM servers.</t>

</section>
<section anchor="terms"><name>Terms</name>

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

<t>We define the following concepts, with some non-normative references to
related concepts from OAuth [RFC6749] and elsewhere:</t>

<t><list style="symbols">
  <t><strong>Resource</strong> - 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.</t>
  <t><strong>Remote Resource</strong> - A Resource provided by the Sending Server.</t>
  <t><strong>Shared Resource</strong> - A Resource shared by an OCM Server, becoming a
Remote Resource if accepted by the Invite Receiver OCM Server.</t>
  <t><strong>Share</strong> - 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.</t>
  <t><strong>Sending Party</strong> - A person or party who is authorized to create
Shares; similar to "Resource Owner" in OAuth [RFC6749], identified by
its OCM Address.</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, identified by its OCM Address.</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>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 [RFC6749]),</t>
      <t>takes the decision about authorizing attempts to access the Resource
(the "Resource Server" role in OAuth [RFC6749]),</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 [RFC4918]) 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>Sharing User</strong> - A user providing access to a Resource through a
Share.</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>OCM API Discovery</strong> - Process of evaluating properties of a Remote
Resource, after establishing contact with an OCM Server.</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> - 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.  <vspace blankLines='1'/>
    <figure><artwork><![CDATA[
  ocm-address = identifier "@" host [ ":" port]
]]></artwork></figure>
  <vspace blankLines='1'/>
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 
  <spanx style="verb">nomen.nescio@example.org@ocm.example.org</spanx>.  <vspace blankLines='1'/>
host is an IP literal encapsulated within square brackets, an IPv4 
  address in dotted decimal form, or a registered name as described in
  [RFC3986].  <vspace blankLines='1'/>
    <figure><artwork><![CDATA[
  host = IP-literal / IPv4address / reg-name
]]></artwork></figure>
  <vspace blankLines='1'/>
The optional port subcomponent can be used to specify a port to use
  for discovery (see Discovery Process).  <vspace blankLines='1'/>
The OCM Server MUST be discoverable at the given host and optional 
  port via the Well-Known [RFC8615] path <spanx style="verb">/.well-known/ocm</spanx>. The OCM 
  Address MUST NOT contain a path.</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, identified by its
OCM Address.</t>
  <t><strong>Invite Receiver</strong> - The party receiving an Invite, identified by its
OCM Address.</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 String</strong> - A base64 encoded string containing an Invite Token
and the FQDN of an Invite Sender OCM Server joined by an <spanx style="verb">@</spanx>-sign.</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>Trusted Server</strong> - 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.</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.  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.</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 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.</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>

<section anchor="rationale"><name>Rationale</name>

<t>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>
<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 Gsture 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 httpsig [RFC9421]</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>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.</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="invite-format"><name>Invite format</name>
<t>To accept an invite, two pieces of information are required: a <spanx style="verb">token</spanx>
and a <spanx style="verb">provider</spanx>. There are two recognized formats:</t>

<t><list style="symbols">
  <t><strong>Invite string format:</strong>
A base64-encoded string containing the token and the provider’s FQDN,
joined by an <spanx style="verb">@</spanx> sign. Example:  <vspace blankLines='1'/>
If the <spanx style="verb">token</spanx> is <spanx style="verb">a55a966e-15c1-4cb9-a39d-4e4c54399baf</spanx> and the
<spanx style="verb">provider</spanx> is <spanx style="verb">my-cloud-storage.org</spanx>, the combined string is
<spanx style="verb">a55a966e-15c1-4cb9-a39d-4e4c54399baf@my-cloud-storage.org</spanx>,
which when base64-encoded becomes
<spanx style="verb">YTU1YTk2NmUtMTVjMS00Y2I5LWEzOWQtNGU0YzU0Mzk5YmFmQG15LWNsb3VkLXN0b
3JhZ2Uub3Jn</spanx>.  <vspace blankLines='1'/>
When parsing an invite string, implementors must base64-decode it,
then split on the last <spanx style="verb">@</spanx> sign, taking care to allow multiple <spanx style="verb">@</spanx>
characters in the token part.</t>
  <t><strong>Link format:</strong>
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:  <vspace blankLines='1'/>
<spanx style="verb">https://my-cloud-storage.org/wayf?token=
a55a966e-15c1-4cb9-a39d-4e4c54399baf</spanx></t>
</list></t>

<t>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 <spanx style="verb">inviteAcceptDialog</spanx>
in its Discovery endpoint.  Implmentations SHOULD support the link
format when they implement a WAYF Page that leverages those
<spanx style="verb">inviteAcceptDialog</spanx> targets.</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>

<section anchor="introduction-1"><name>Introduction</name>

<t>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:</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>
<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 via 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. Implementations MAY fallback to HTTP instead
of HTTPS in testing setups and retry steps 2-5, in particular when
an optional port is given in the address.
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.2"</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
MUST itself be an object containing the following fields:
  <list style="symbols">
      <t>name (string) - A supported resource type (file, 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 [RFC4918] path at this
endpoint.  In order to access a Remote 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 SHOULD NOT be intended as a prefix
for share requests.</t>
          <t>datatx (string) - The top-level path used for data transfers.
This value is provided for documentation purposes,
and it SHOULD NOT be intended as a prefix.  In
addition, implementations are expected to execute
the transfer using WebDAV [RFC4918] 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:
_ <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.
_ <spanx style="verb">"webdav-uri"</spanx> - to indicate that this OCM Server can append a
relative URI to the path listed for WebDAV [RFC4918] in the
appropriate <spanx style="verb">resourceTypes</spanx> entry <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.
_ <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.
_ <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.
_ <spanx style="verb">"invite-wayf"</spanx> - to indicate that this OCM Server exposes a WAYF
Page to facilitate the Invite flow.</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:
_ <spanx style="verb">"http-request-signatures"</spanx> - to indicate that API requests
without http signatures will be rejected.
_ <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).
_ <spanx style="verb">"denylist"</spanx> - some servers MAY be blocked based on their IP
address
_ <spanx style="verb">"allowlist"</spanx> - unknown servers MAY be blocked based on their IP
address * <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>
  <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 keyId (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----\n...\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 httpsig [RFC9421]</t>
</list></t>

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

<t><list style="symbols">
  <t>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@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)
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</t>
  <t>REQUIRED owner (string) -
OCM Address of the user who owns the
Resource.
Example: "6358b71804dfa8ab069cf05ed1b0ed2a@apiwise.nl"</t>
  <t>REQUIRED sender (string) -
OCM Address of the user that wants to share
the Resource.
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
indicate 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 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.</t>
  <t>REQUIRED resourceType (string)
Resource type (file, folder, calendar, contact, ...).  If the
Resource is a folder, implementations SHOULD advertise it as
<spanx style="verb">folder</spanx> rather than <spanx style="verb">file</spanx>, in order to streamline the processing
by the Receiving Server.</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)
A 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)
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 <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)
A 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 httpsig [RFC9421]</t>
</list></t>

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

<t><list style="symbols">
  <t>REQUIRED notificationType (string) - in a Share Acceptance
Notification it MUST 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>

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

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

<t><list style="numbers" type="1">
  <t>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.</t>
  <t>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.</t>
  <t>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.</t>
  <t>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>
</list></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 consumer 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.  In all cases, the Receiving Server MUST NOT reshare
a Resource without an explicit grant from the Sending Server.</t>

</section>
<section anchor="iana-considerations"><name>IANA Considerations</name>

<section anchor="well-known-uri-for-the-discovery"><name>Well-Known URI for the Discovery</name>

<t>The following value is to be registered in the "Well-Known URIs"
registry (using the template from [RFC5785]):
   URI suffix: ocm
   Change controller: IETF
   Specification document(s): the present Draft, once in RFC form
   Related information: N/A</t>

</section>
</section>
<section anchor="security-considerations"><name>Security Considerations</name>

<section anchor="trust"><name>Trust</name>

<t>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 <spanx style="verb">mfa-enforced</spanx> requirement.</t>

<t>Trust needs to be established out of band, but there are some features
of the protocol that <em>can</em> 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.</t>

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

<section anchor="httpsig"><name>httpsig</name>

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

</section>
</section>
<section anchor="legacy-shared-secrets"><name>Legacy shared secrets</name>

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

</section>
</section>
<section anchor="references"><name>References</name>

<section anchor="normative-references"><name>Normative References</name>

<t>[RFC2119] Bradner, S. "<eref target="https://datatracker.ietf.org/doc/html/rfc2119">Key words for use in RFCs to Indicate
Requirement Levels</eref>",
March 1997.</t>

<t>[RFC4918] Dusseault, L. M. "<eref target="https://datatracker.ietf.org/html/rfc4918/">HTTP Extensions for Web Distributed
Authoring and Versioning</eref>",
June 2007.</t>

<t>[RFC8174] Leiba, B. "<eref target="https://datatracker.ietf.org/html/rfc8174">Ambiguity of Uppercase vs Lowercase in RFC 2119
Key Words</eref>", May 2017.</t>

<t>[RFC9421] Backman, A., Richer, J. and Sporny, M. "<eref target="https://tools.ietf.org/html/rfc9421">HTTP Message
Signatures</eref>", February 2024.</t>

<t>[RFC3986] Berners-Lee, T., Fielding, R. and Masinter, L. 
"<eref target="https://datatracker.ietf.org/doc/html/rfc3986">Uniform Resource Identifier (URI): Generic Syntax
</eref>", January 2005</t>

<t>[RFC8615] Nottingham, M. "<eref target="https://datatracker.ietf.org/doc/html/rfc8615">Well-Known Uniform Resource Identifiers 
(URIs)</eref>", May 2019</t>

</section>
<section anchor="informative-references"><name>Informative References</name>

<t>[RFC6749] Hardt, D. (ed), "<eref target="https://datatracker.ietf.org/html/rfc6749">The OAuth 2.0 Authorization Framework</eref>", October 2012.</t>

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

<t><spanx style="verb">
  {
    "@request-target": "post /path",
    "content-length": 380,
    "date": "Mon, 08 Jul 2024 14:16:20 GMT",
    "content-digest": "SHA-256=U7gNVUQiixe5BRbp4...",
    "host": "hostname.of.the.recipient",
    "Signature": "keyId=\"https://author.hostname/key\",algorithm=
      \"rsa-sha256\",headers=\"content-length date digest host\",
      signature=\"DzN12OCS1rsA[...]o0VmxjQooRo6HHabg==\""
  }
</spanx></t>

<t><list style="symbols">
  <t>'@request-target' (optional) 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>'content-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,
content-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>

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

<t>signed = ssl_sign(concatenate_with_newlines(headers),
    private_key, 'sha256')
signature = {
    'keyId': 'sender.fqdn',  # The sending server's FQDN
    'algorithm': 'rsa-sha256',
    'headers': 'content-length date content-digest host',
    'signature': signed,
}</t>

<t>headers['Signature'] = format_signature(signature)
```</t>

</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">content-length</spanx> and <spanx style="verb">content-digest</spanx> can be regenerated 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">content-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>

<t>```
clear = {
    'content-length': length_of(payload),
    'date': 'Mon, 08 Jul 2024 14:16:20 GMT',
    'content-digest': 'SHA-256=' + base64_encode(hash('sha256',
          utf8_encode(payload))),  # Recompute digest for verification
    'host': 'sender-fqdn',
}</t>

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

<t>if not verification_result then
    raise InvalidSignatureException
```</t>

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

<t><list style="symbols">
  <t>REQUIRED: <spanx style="verb">federation</spanx> - a human-readable name for the list of OCM
Servers exposed by the Directory Service</t>
  <t>REQUIRED: <spanx style="verb">servers</spanx> - a JSON array of objects to describe the list
of OCM Servers with the following string fields:
  <list style="symbols">
      <t>REQUIRED: <spanx style="verb">url</spanx> - an absolute URL identifying the
OCM Server.  It MUST:
      <list style="symbols">
          <t>include scheme: either <spanx style="verb">https://</spanx> or
(for testing purposes) <spanx style="verb">http://</spanx></t>
          <t>include host (either a FQDN or an IP address)</t>
          <t>MAY include a non-default port</t>
          <t>MUST NOT include a base path (e.g., <spanx style="verb">/ocm</spanx>)</t>
          <t>MUST NOT include userinfo, query, or fragment</t>
        </list></t>
      <t>REQUIRED: <spanx style="verb">displayName</spanx> - a human-readable name
for the OCM Server
Example:</t>
    </list></t>
</list></t>

<t><spanx style="verb">json
{
  "federation": "The ScienceMesh Directory",
  "servers": [
    {
      "url": "https://ocm-server-1.example.org",
      "displayName": "OCM Server 1"
    },
    {
      "url": "https://ocm-server-2.example.org:4443",
      "displayName": "OCM Server 2"
    },
    {
      "url": "http://192.168.1.1:8080",
      "displayName": "OCM Server 3"
    }
  ]
}
</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,
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.</t>

<t>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.</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, Marcin Sieprawski,
Tilo Steiger, C.D. Tiwari, Alejandro Unger and Tom Wezepoel.</t>

</section>


  </middle>

  <back>








  </back>

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

-->

</rfc>

