<?xml version="1.0" encoding="utf-8"?>
<!-- name="GENERATOR" content="github.com/mmarkdown/mmark Mmark Markdown Processor - mmark.miek.nl" -->
<rfc version="3" ipr="trust200902" docName="draft-ietf-jmap-portability-extensions-01" submissionType="IETF" category="std" xml:lang="en" xmlns:xi="http://www.w3.org/2001/XInclude" indexInclude="true">

<front>
<title abbrev="JMAP Portability Extensions">JMAP Migration and Portability Extensions</title><seriesInfo value="draft-ietf-jmap-portability-extensions-01" stream="IETF" status="standard" name="Internet-Draft"></seriesInfo>
<author role="editor" initials="J.M." surname="Baum" fullname="Joris Baum"><organization>audriga</organization><address><postal><street>Alter Schlachthof 57</street>
<city>Karlsruhe </city>
<code>76137</code>
<country>Germany</country>
</postal><email>joris@audriga.com</email>
<uri>https://www.audriga.com</uri>
</address></author><author role="editor" initials="H.J." surname="Happel" fullname="Hans-Joerg"><organization>audriga</organization><address><postal><street>Alter Schlachthof 57</street>
<city>Karlsruhe </city>
<code>76137</code>
<country>Germany</country>
</postal><email>hans-joerg@audriga.com</email>
<uri>https://www.audriga.com</uri>
</address></author><date year="2024" month="March" day="20"></date>
<area>Applications</area>
<workgroup>JMAP</workgroup>
<keyword>jmap</keyword>
<keyword>debug</keyword>
<keyword>logging</keyword>
<keyword>metadata</keyword>

<abstract>
<t>JMAP (RFC8620) is a generic, efficient, mobile friendly and scalable protocol that can be used for data of any type. This makes it a good fit for migrations or data portability use cases. This extension adds additional features useful (but not limited to) those use cases.</t>
<t>It adds a feature exposing details about the product, backend and environment of a JMAP server.</t>
<t>It also adds a data model for extending the JMAP Response with log messages, particularly helpful for debugging.</t>
</abstract>

</front>

<middle>

<section anchor="introduction"><name>Introduction</name>
<t>Every server-side software has its own quirks. For example, a JMAP server
might only have partially implemented the JMAP standard or design decisions might
have been taken that let the server deviate from what is actually required by
<xref target="RFC8620"></xref>. Servers might also have unintended bugs or have certain
restrictions that are not sufficiently reflected by their list of supported
server capabilities.</t>
<t>JMAP as a protocol for data migration and portability targets a large variety of pre-existing systems. Especially legacy systems often come with a lot of constraints that may prohibit them from fully complying with the JMAP standard. Interoperable clients that aim to have a successful structured data
exchange with such &quot;unique&quot; servers need to handle these quirks with workarounds
on the client-side. Clients only want to apply special workarounds in
situations where they are truly necessary. This is typically done by identifying
which server-side software they are communicating with.</t>
<t>JMAP does not provide a standardized way to retrieve an identifier of the
product that is residing on the server side. Due to the lack of standardization
clients are left to identify misbehaving servers by error-prone means. Examples
are checking against a list of known URLs or checking known unique responses,
typically only sent by certain products. This makes identifying products
time-consuming and brittle.</t>
<t>Related functionality in other standards are the PRODID property in iCalendar <xref target="RFC5545"></xref> and vCard <xref target="RFC6350"></xref>, which allows
identifying the product that produced the files. ManageSieve <xref target="RFC5804"></xref> and JMAP Sieve <xref target="I-D.ietf-jmap-sieve"></xref> define an implementation property, which allows identifying the Sieve implementation.</t>
<t>Additionally, server-side logs are very valuable to analyze issues a client may run into. Usually, logs are either stored locally on the instances or sent to a dedicated logging server. However, data migrations often take place in constrained environments under which access to server-side logs is limited. JMAP can be leveraged to supply log messages along-side the usual data exchange. This also removes the need to operate a separate logging infrastructure or have dedicated channels for log messages.</t>

<section anchor="conventions-used-in-this-document"><name>Conventions Used In This Document</name>
<t>The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL
NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;,
&quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as
described in BCP 14 <xref target="RFC2119"></xref> <xref target="RFC8174"></xref> when, and only when,
they appear in all capitals, as shown here.</t>
<t>The definitions of JSON keys and datatypes in the document follow
the conventions described in the core JMAP specification <xref target="RFC8620"></xref>.</t>
</section>

<section anchor="addition-to-the-capabilities-object"><name>Addition to the capabilities object</name>
<t>The capabilities object is returned as part of the JMAP Session object;
see <xref target="RFC8620"></xref>, Section 2. This document defines two additional capability URIs.</t>

<section anchor="urn-ietf-params-jmap-backendinfo"><name>urn:ietf:params:jmap:backendinfo</name>
<t>This extension defines
one additional <tt>urn:ietf:params:jmap:backendinfo</tt> server capability that provides
details about the product, backend, and environment.</t>
<t>The value of this property in the JMAP Session capabilities property is an object that MUST contain the following information on server capabilities:</t>

<ul>
<li><strong>product</strong>: <tt>SoftwareInfo</tt> Information on the overall application or product.</li>
<li><strong>backend</strong>: <tt>SoftwareInfo|null</tt> Information on the JMAP API backend component.</li>
<li><strong>environment</strong>: <tt>SoftwareInfo|null</tt> Information on the environment the software is running in.</li>
<li><t><strong>capabilityOverrides</strong>: <tt>String[PatchObject]|null</tt> An object showing which capabilities use different software components. Each key is a URI for a capability supported by the server. The value for each of these keys is a Patch Object, see <xref target="RFC8620"></xref>, Section 5.3, specifying differing information on software components.</t>
<t>The client MUST ignore any properties it does not understand.</t>
</li>
</ul>
<t>A <strong>SoftwareInfo</strong> object has the following properties:</t>

<ul spacing="compact">
<li><strong>name</strong>: <tt>String</tt> The name of the software.</li>
<li><strong>version</strong>: <tt>String</tt> The software version. The value MUST begin with a number. An example for an invalid value would be &quot;v1.0.0&quot;.</li>
</ul>
<t>This extension does not add anything to the account's accountCapabilities property.</t>
<t>Here is an example JSON snippet:</t>

<sourcecode type="json"><![CDATA["capabilities": {
  "urn:ietf:params:jmap:core:backendinfo": {
    "backend": {
      "name": "OpenXPort/Horde",
      "version": "1.0.0"
    },
    "product": {
      "name": "Horde Webmailer",
      "version": "1.0.0"
    },
    "environment": {
      "name": "PHP",
      "version": "5.5"
    },
    "capabilityOverrides": {
      "urn:ietf:params:jmap:sieve": {
        "backend": {
          "name": "Cyrus timsieved",
          "version": "3.8.2"
        },
        "product": {
          "name": "Horde Ingo",
          "version": "1.0.0"
        }
      }
    }
  }
  ...
}
]]>
</sourcecode>
</section>

<section anchor="urn-ietf-params-jmap-debug"><name>urn:ietf:params:jmap:debug</name>
<t>Represents support for the <strong>logs</strong> property in the JMAP method response
(defined in <xref target="RFC8620"></xref> Section 3.4) and the &quot;problem details&quot; types (defined in
<xref target="RFC8620"></xref> Section 3.6.1) using the <strong>LogLine</strong> data type.</t>
<t>The value of this property in the JMAP Session and account's capabilities
property is an empty object.</t>
</section>
</section>
</section>

<section anchor="structured-data-exchange-extension"><name>Structured Data Exchange Extension</name>
<t>For clients signaling support for the &quot;urn:ietf:params:jmap:core:backendinfo&quot; capability, the <strong>Response</strong> object (see <xref target="RFC8620"></xref> Section 3.4) as well as all &quot;problem details&quot; objects (see <xref target="RFC8620"></xref> Section 3.6.1) will be extended via:</t>

<ul spacing="compact">
<li><strong>logs</strong>: <tt>LogLine[]</tt> (optional)
An array of log lines that were created while processing the request.</li>
</ul>
<t>A <strong>LogLine</strong> object has the following properties:</t>

<ul spacing="compact">
<li><strong>level</strong>: <tt>String</tt>
The log level of the log message. MUST be one of the eight levels defined in
<eref target="https://datatracker.ietf.org/doc/html/rfc5424">RFC5424</eref>: debug, info, notice,
warning, error, critical, alert or emergency.</li>
<li><strong>message</strong>: <tt>String</tt>
The log message</li>
<li><strong>timestamp</strong>: <tt>UTCDate</tt>
The date the log message was logged.</li>
<li><strong>class</strong>: <tt>String|null</tt>
The name of the class that is currently logging.</li>
<li><strong>file</strong>: <tt>String|null</tt>
The file that initiated the log line.</li>
<li><strong>line</strong>: <tt>String|null</tt>
The exact line in the file where the log function is being called.</li>
</ul>
<t>An example list of logs sent alongside a response to Core/echo would look like:</t>

<sourcecode type="json"><![CDATA[NOTE: '\' line wrapping per RFC 8792

{
  "using": [
    "urn:ietf:params:jmap:core","urn:ietf:params:jmap:debug"
  ],
  "methodCalls": [
    [
      "Core/echo",
      {
        "accountId": "jorissa",
        "someOtherKey": "someOtherValue"
      },
      "0"
    ]
  ]
}

{
  "logs": [
    {
      "file": "Logger.php",
      "level": "info",
      "line": 32,
      "message": "Array Logger has been successfully initialized",
      "timestamp": "2022-01-18T10:26:56+01:00"
    },
    {
      "file": "ErrorHandler.php",
      "level": "warning",
      "line": 52,
      "message": "fopen(bridge.php): failed to open stream: \
        No such file or directory",
      "timestamp": "2022-01-18T10:26:56+01:00"
    },
    ...
  ],
  "methodResponses": [
    [
      "Core/echo",
      {
        "someOtherKey": "someOtherValue",
        "accountId": "jorissa"
      },
      "0"
    ]
  ]
}
]]>
</sourcecode>
</section>

<section anchor="security"><name>Security considerations</name>
<t>All security considerations of JMAP <xref target="RFC8620"></xref> apply to this specification.</t>
<t>Log messages might contain sensitive user data as well as detailed information
about the system on which an API server has been installed. Appropriate measures
must be taken to restrict access to JMAP Debug to trusted parties only.</t>
</section>

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

<section anchor="jmap-capability-registration-for-backendinfo"><name>JMAP Capability Registration for &quot;backendinfo&quot;</name>
<t>IANA will register the &quot;backendinfo&quot; JMAP Capability as follows:</t>
<t>Capability Name: urn:ietf:params:jmap:backendinfo</t>
<t>Specification document: this document</t>
<t>Intended use: common</t>
<t>Change Controller: IETF</t>
<t>Security and privacy considerations: this document, <xref target="security"></xref>.</t>
</section>

<section anchor="jmap-capability-registration-for-debug"><name>JMAP Capability registration for &quot;debug&quot;</name>
<t>IANA is requested to register the &quot;debug&quot; JMAP Capability as follows:</t>
<t>Capability Name: urn:ietf:params:jmap:debug</t>
<t>Specification document: this document</t>
<t>Intended use: common</t>
<t>Change Controller: IETF</t>
<t>Security and privacy considerations: this document, <xref target="security"></xref>.</t>
</section>

<section anchor="jmap-datatype-registration-for-logline"><name>JMAP Datatype Registration for &quot;LogLine&quot;</name>
<t>IANA will register the &quot;LogLine&quot; Data Type as folows:</t>
<t>Type Name: &quot;LogLine&quot;</t>
<t>Can reference blobs: No</t>
<t>Can use for state change: No</t>
<t>Capability: urn:ietf:params:jmap:debug</t>
<t>Reference: this document</t>
</section>
</section>

<section anchor="acknowledgements"><name>Acknowledgements</name>
<t>Bron Gondwana, Neil Jenkins, Alexey Melnikov, Ken Murchison, Robert Stepanek and
the JMAP working group at the IETF.</t>
</section>

</middle>

<back>
<references><name>Normative References</name>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-jmap-sieve.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5545.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5804.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6350.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8620.xml"/>
</references>

</back>

</rfc>
