<?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.32 (Ruby 3.3.0) -->


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

]>


<rfc ipr="trust200902" docName="draft-ietf-jmap-object-history-01" category="std" consensus="true" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true">
  <front>
    <title abbrev="JMAP Object History">JMAP Object History</title>

    <author initials="B." surname="Gondwana" fullname="Bron Gondwana">
      <organization>Fastmail</organization>
      <address>
        <email>brong@fastmailteam.com</email>
      </address>
    </author>

    <date year="2026" month="October" day="15"/>

    
    
    <keyword>Internet-Draft</keyword>

    <abstract>


<?line 35?>

<t>The JMAP base protocol (RFC8620) provides methods for synchronizing
the current state of data objects between client and server.  This
extension adds the ability to retrieve historical versions of objects,
including objects that have been destroyed, by extending the standard
Foo/get method.</t>



    </abstract>



  </front>

  <middle>


<?line 43?>

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

<t>JMAP (<xref target="JMAP-CORE"/> — JSON Meta Application Protocol) provides a
standard set of methods for each data type: Foo/get, Foo/changes,
Foo/set, Foo/query, and Foo/queryChanges.  These methods operate
on the current state of objects.  The Foo/changes method tells a
client which objects have changed, but does not provide the
previous values.</t>

<t>In many applications it is useful to access historical versions
of objects.  For example, a user may want to see previous versions
of a contact record (<xref target="JMAP-CONTACTS"/>) or recover a deleted
email (<xref target="JMAP-MAIL"/>).</t>

<t>This extension adds history support to the standard Foo/get
method.  When the <spanx style="verb">urn:ietf:params:jmap:object-history</spanx> capability
is included in the request's <spanx style="verb">using</spanx> array, Foo/get gains
additional parameters that allow the client to request previous
versions of objects, including objects that have been destroyed.</t>

<section anchor="conventions-used-in-this-document"><name>Conventions Used in This Document</name>

<t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
appear in all capitals, as shown here.</t>

<?line -18?>

</section>
</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="JMAP-CORE"/>, Section 2.</t>

<t>This document defines an additional capability URI.</t>

<section anchor="urnietfparamsjmapobject-history"><name>urn:ietf:params:jmap:object-history</name>

<t>The capability <spanx style="verb">urn:ietf:params:jmap:object-history</spanx> being present
in the "accountCapabilities" property of an account represents
support for retrieving historical object versions in that account.
Servers that include the capability in one or more
"accountCapabilities" properties <bcp14>MUST</bcp14> also include the property in
the "capabilities" property.</t>

<t>The value of this property in the JMAP session "capabilities"
property <bcp14>MUST</bcp14> be an empty object.</t>

<t>The value of this property in an account's "accountCapabilities"
property is an object that <bcp14>MUST</bcp14> contain the following information
on server capabilities for that account:</t>

<t><list style="symbols">
  <t>maxHistoryDuration: "UnsignedInt|null"  <vspace blankLines='1'/>
The number of seconds after replacement for which the server
  intends to retain old versions, or null if the server does
  not have a time-based retention policy.  This is a statement
  of server policy, not a guarantee: retention is best effort,
  and the server <bcp14>MAY</bcp14> discard versions sooner (for example, due
  to storage limits).  A version whose <spanx style="verb">replaced</spanx> timestamp is
  more than this many seconds ago has probably been discarded.
  Clients that need to be certain an object remains available
  should not destroy it.</t>
  <t>supportedTypes: "String[]"  <vspace blankLines='1'/>
The names of the data types, from the "JMAP Data Types"
  registry <xref target="IANA-JMAP"/> or private types, for which the server
  supports the history extensions in this account.  A server
  <bcp14>MAY</bcp14> support history for only a subset of the types it
  supports, and <bcp14>MAY</bcp14> retain history for only some objects of
  a supported type (for example, only for some folders).
  Clients <bcp14>MUST</bcp14> ignore type names they do not recognise.</t>
</list></t>

</section>
</section>
<section anchor="extensions-to-fooget"><name>Extensions to Foo/get</name>

<t>When this capability is included in the request's <spanx style="verb">using</spanx> array,
the standard Foo/get method (<xref target="JMAP-CORE"/>, Section 5.1) accepts
the following additional request arguments:</t>

<t><list style="symbols">
  <t>includeReplaced: "Boolean" (default: false)  <vspace blankLines='1'/>
If true, the server returns previous versions of the
  requested objects in addition to the current version.
  Each previous version appears as a separate entry in the
  <spanx style="verb">list</spanx> array, with the same <spanx style="verb">id</spanx> as the current version.
  Every entry includes an <spanx style="verb">objectHistory</spanx> property (see
  below).  Entries with the same <spanx style="verb">id</spanx> <bcp14>MUST</bcp14> be ordered by
  <spanx style="verb">objectHistory.version</spanx> (ascending).  Entries for
  different objects <bcp14>MAY</bcp14> be interleaved.</t>
  <t>includeDestroyed: "Boolean" (default: false)  <vspace blankLines='1'/>
If true, the server also returns objects that have been
  destroyed.  If <spanx style="verb">includeReplaced</spanx> is false, only the final
  version before destruction is returned.  If <spanx style="verb">includeReplaced</spanx>
  is true, all retained historical versions of destroyed
  objects are returned.  For destroyed objects, every entry
  has a non-null <spanx style="verb">objectHistory.replaced</spanx> value, since every
  version has been superseded (the final version was replaced
  by destruction).</t>
  <t>historyAfter: "UTCDate|null" (default: null)  <vspace blankLines='1'/>
If supplied, only versions with an <spanx style="verb">objectHistory.replaced</spanx>
  value strictly after this date are returned, plus the
  current (live) version which has a null <spanx style="verb">replaced</spanx> value.
  If null, no time-based filter is applied.</t>
  <t>historyBefore: "UTCDate|null" (default: null)  <vspace blankLines='1'/>
If supplied, only versions with an <spanx style="verb">objectHistory.replaced</spanx>
  value strictly before this date are returned.  The current
  (live) version, which has a null <spanx style="verb">replaced</spanx> value, is not
  returned.  If null, no time-based filter is applied.  <vspace blankLines='1'/>
A client can use this to page backwards through history: it
  passes the oldest <spanx style="verb">replaced</spanx> value from the previous response
  as <spanx style="verb">historyBefore</spanx> in the next request.  When several ids are
  requested, the client passes the oldest <spanx style="verb">replaced</spanx> value from
  the whole response; any id with no remaining versions is
  returned in <spanx style="verb">notFound</spanx>.  Clients <bcp14>SHOULD</bcp14> pass the <spanx style="verb">replaced</spanx>
  value exactly as received, rather than parsing and
  re-serialising it, since re-serialising at a lower precision
  could cause versions to be skipped.</t>
  <t>historyLimit: "UnsignedInt|null" (default: null)  <vspace blankLines='1'/>
If supplied, the maximum number of entries to return in the
  <spanx style="verb">list</spanx> array for each id, including the current version if
  any.  For each id, the server <bcp14>MUST</bcp14> return the most recent
  entries (those with the highest version numbers), not the
  oldest.  If more entries are available for any requested id
  than were returned, the response includes a <spanx style="verb">hasMoreHistory</spanx>
  property set to true.  Only ids for which exactly
  <spanx style="verb">historyLimit</spanx> entries were returned can have more history
  available.  If null, the server returns all retained
  versions, subject to its own limits.</t>
</list></t>

<t>If the <spanx style="verb">ids</spanx> argument is null, the server returns all objects of
the type as per <xref target="JMAP-CORE"/>, Section 5.1.  If <spanx style="verb">includeDestroyed</spanx>
is true, this includes every destroyed object for which the server
still retains any version.</t>

<t>The "maxObjectsInGet" limit and the "requestTooLarge" error
(<xref target="JMAP-CORE"/>, Section 5.1) apply to the number of distinct ids,
not to the number of entries in the <spanx style="verb">list</spanx> array.  Each id can
have up to <spanx style="verb">historyLimit</spanx> entries.</t>

<t>If, after applying <spanx style="verb">includeReplaced</spanx>, <spanx style="verb">includeDestroyed</spanx>,
<spanx style="verb">historyAfter</spanx>, and <spanx style="verb">historyBefore</spanx>, no versions of a requested id remain to be
returned, that id is included in the <spanx style="verb">notFound</spanx> array.</t>

<section anchor="the-objecthistory-property"><name>The objectHistory property</name>

<t>When <spanx style="verb">includeReplaced</spanx> or <spanx style="verb">includeDestroyed</spanx> is true, each object
in the <spanx style="verb">list</spanx> array includes an additional property:</t>

<t><list style="symbols">
  <t>objectHistory: "ObjectHistoryInfo"  <vspace blankLines='1'/>
An ObjectHistoryInfo object with the following properties:  <list style="symbols">
      <t>version: "UnsignedInt"
A per-object monotonically increasing number that
provides ordering among the versions of a single object
within a response.  Version numbers <bcp14>MAY</bcp14> have gaps (e.g.,
a server may use internal sequence numbers such as modseq
values).  The current (live) version of an object always
has the highest version number.  Servers <bcp14>SHOULD</bcp14> return
consistent version numbers across requests, but clients
<bcp14>MUST NOT</bcp14> rely on this — version numbers exist primarily
to provide ordering within a single response.</t>
      <t>replaced: "UTCDate|null"
The date and time at which this version was superseded,
either by a subsequent update or by destruction.  If null,
this is the current live version of the object.  For
destroyed objects, every version has a non-null <spanx style="verb">replaced</spanx>
value — the final version's <spanx style="verb">replaced</spanx> is the time of
destruction.  The <spanx style="verb">replaced</spanx> values of different versions
of the same object <bcp14>MUST</bcp14> be distinct, so that <spanx style="verb">historyBefore</spanx>
and <spanx style="verb">historyAfter</spanx> partition the history without ambiguity;
a server that records two versions with the same timestamp
can collapse them into a single version.  The value <bcp14>MAY</bcp14>
include fractional seconds (<xref target="JMAP-CORE"/>, Section 1.4),
but servers <bcp14>SHOULD NOT</bcp14> use more than millisecond precision,
as many client date libraries cannot represent more.</t>
    </list></t>
</list></t>

<t>When <spanx style="verb">includeReplaced</spanx> and <spanx style="verb">includeDestroyed</spanx> are both false
(the default), the <spanx style="verb">objectHistory</spanx> property is not included in
the response, and the behaviour is identical to standard Foo/get.</t>

<t>The client <bcp14>MAY</bcp14> include "objectHistory" in the <spanx style="verb">properties</spanx> argument.
It is returned if and only if <spanx style="verb">includeReplaced</spanx> or <spanx style="verb">includeDestroyed</spanx>
is true, regardless of whether it is listed in <spanx style="verb">properties</spanx>.</t>

<t>Which changes produce a version is server dependent: a version is
a snapshot of the object that the server recorded at some point.
The server is not required to create a new version for every
individual change to an object.  For example, rapid successive
updates may be collapsed into a single version, and a server may
choose not to record a version for changes that only affect
server-computed properties.  The server <bcp14>MAY</bcp14> also prune old versions
in any order, so there can be gaps in the version history available
to the client.  Clients <bcp14>MUST NOT</bcp14> assume that the version history is
complete or contiguous.</t>

<t>The values of server-computed properties (for example, the counts
on a Mailbox) in a historical version are also server dependent.
The server <bcp14>SHOULD</bcp14> return the value the property had at the time of
that version if it has that information.</t>

<t>If a historical version contains a reference to a blob (for
example, the <spanx style="verb">blobId</spanx> of an Email), that blob <bcp14>MUST</bcp14> be downloadable
for as long as the server returns that version.  A server that has
discarded a blob referenced by a version <bcp14>MUST NOT</bcp14> return that
version.</t>

<t>If <spanx style="verb">includeReplaced</spanx> or <spanx style="verb">includeDestroyed</spanx> is true and the data type
is not listed in the <spanx style="verb">supportedTypes</spanx> capability property, the
server <bcp14>MUST</bcp14> reject the call with an "invalidArguments" error.</t>

<t>If the data type is supported but the server does not retain
history for a particular object, it <bcp14>MUST</bcp14> still return the current
version with an <spanx style="verb">objectHistory</spanx> property when requested.  In this
case, the server returns only the current version, with a <spanx style="verb">replaced</spanx>
of null.</t>

</section>
<section anchor="additional-response-properties"><name>Additional response properties</name>

<t>When <spanx style="verb">includeReplaced</spanx> or <spanx style="verb">includeDestroyed</spanx> is true, the
response includes:</t>

<t><list style="symbols">
  <t>hasMoreHistory: "Boolean"  <vspace blankLines='1'/>
If true, there are older entries available for at least one
  requested id.  The client can retrieve more versions using
  <spanx style="verb">historyBefore</spanx>, or by making a request with a larger
  <spanx style="verb">historyLimit</spanx>.  If false, the server has returned
  all retained history for the requested ids.  The server <bcp14>MAY</bcp14>
  return false even if more history exists (e.g., if it
  cannot efficiently determine whether older versions remain).
  If the server returns true, the client <bcp14>MUST NOT</bcp14> assume the
  history will still be available in a subsequent request, as
  the server may purge history at any time.</t>
</list></t>

</section>
<section anchor="examples"><name>Examples</name>

<section anchor="contact-history"><name>Contact history</name>

<t>Requesting the history of a contact, including all versions:</t>

<figure><sourcecode type="json"><![CDATA[
[["ContactCard/get", {
  "accountId": "abc",
  "ids": ["contact1"],
  "properties": ["name", "emails"],
  "includeReplaced": true,
  "historyLimit": 10
}, "0"]]
]]></sourcecode></figure>

<t>The response includes three versions: the original creation,
a name update, and the current version with an additional email
address:</t>

<figure><sourcecode type="json"><![CDATA[
[["ContactCard/get", {
  "accountId": "abc",
  "state": "abc123",
  "list": [
    {
      "id": "contact1",
      "name": {"full": "Robert Smith"},
      "emails": {
        "e1": {"address": "bob@example.com"}
      },
      "objectHistory": {
        "version": 1,
        "replaced": "2026-02-20T14:15:00Z"
      }
    },
    {
      "id": "contact1",
      "name": {"full": "Bob Smith"},
      "emails": {
        "e1": {"address": "bob@example.com"}
      },
      "objectHistory": {
        "version": 2,
        "replaced": "2026-03-01T09:00:00Z"
      }
    },
    {
      "id": "contact1",
      "name": {"full": "Bob Smith"},
      "emails": {
        "e1": {"address": "bob@example.com"},
        "e2": {"address": "bob@personal.example"}
      },
      "objectHistory": {
        "version": 3,
        "replaced": null
      }
    }
  ],
  "notFound": [],
  "hasMoreHistory": false
}, "0"]]
]]></sourcecode></figure>

</section>
<section anchor="recovering-destroyed-emails"><name>Recovering destroyed emails</name>

<t>A client can use Email/changes to discover which emails have been
destroyed, then use a backreference to fetch their final state.
This is useful for displaying a "recently deleted" view:</t>

<figure><sourcecode type="json"><![CDATA[
[
  ["Email/changes", {
    "accountId": "abc",
    "sinceState": "state42"
  }, "0"],
  ["Email/get", {
    "accountId": "abc",
    "#ids": {
      "resultOf": "0",
      "name": "Email/changes",
      "path": "/destroyed"
    },
    "properties": ["subject", "from", "receivedAt"],
    "includeDestroyed": true
  }, "1"]
]
]]></sourcecode></figure>

<t>The Email/get response returns the final state of each
destroyed email.  The <spanx style="verb">objectHistory.replaced</spanx> value is the
time of destruction:</t>

<figure><sourcecode type="json"><![CDATA[
[["Email/get", {
  "accountId": "abc",
  "state": "state43",
  "list": [
    {
      "id": "email42",
      "subject": "Meeting notes",
      "from": [{"name": "Alice",
        "email": "alice@example.com"}],
      "receivedAt": "2026-03-10T09:00:00Z",
      "objectHistory": {
        "version": 1,
        "replaced": "2026-03-15T16:30:00Z"
      }
    },
    {
      "id": "email57",
      "subject": "Project update",
      "from": [{"name": "Bob",
        "email": "bob@example.com"}],
      "receivedAt": "2026-03-12T14:00:00Z",
      "objectHistory": {
        "version": 1,
        "replaced": "2026-03-15T16:31:00Z"
      }
    }
  ],
  "notFound": [],
  "hasMoreHistory": false
}, "1"]]
]]></sourcecode></figure>

<t>Since <spanx style="verb">includeReplaced</spanx> was not set, only the final version of
each destroyed email is returned.  The non-null <spanx style="verb">replaced</spanx>
value indicates when each email was destroyed.</t>

</section>
</section>
</section>
<section anchor="restoring-objects"><name>Restoring Objects</name>

<t>To restore an earlier version of an existing object, the client
uses a normal Foo/set update with the values from that version.</t>

<t>To restore a destroyed object, the client uses Foo/set to create a
new object with the values from the version to be restored.  When
this capability is included in the request's <spanx style="verb">using</spanx> array, the
client <bcp14>MAY</bcp14> include the <spanx style="verb">id</spanx> of the destroyed object in the create
request.  The server <bcp14>MAY</bcp14> honour this, in which case the created
object has that id and its history continues from the destroyed
object's history, so the destroyed versions become previous
versions of the restored object.  If the server does not wish to
reuse the id, it <bcp14>MUST</bcp14> reject the creation with an
"invalidProperties" SetError listing the <spanx style="verb">id</spanx> property; the client
can then retry without an <spanx style="verb">id</spanx> to create the object with a new id.</t>

<t>The server <bcp14>MUST</bcp14> reject a create with an <spanx style="verb">id</spanx> that is not the id of
a destroyed object of the same type in the same account.  Apart
from restoring a destroyed object in this way, the server <bcp14>MUST NOT</bcp14>
reuse the id of a destroyed object for which it retains any
history.</t>

</section>
<section anchor="design-rationale"><name>Design Rationale</name>

<t>This section is not normative.</t>

<t>History is returned through the existing Foo/get method rather than
a new method.  The entries in the <spanx style="verb">list</spanx> array are ordinary objects
of the data type, so a client can feed them to the same parser it
uses for current objects, and the existing <spanx style="verb">properties</spanx> argument
works unchanged.  It also allows a client to fetch the final state
of many destroyed objects in a single call, using a backreference
to the <spanx style="verb">destroyed</spanx> list from Foo/changes, as shown in the examples
above.</t>

<t>The history metadata is embedded in each object as the
<spanx style="verb">objectHistory</spanx> property, rather than wrapping each object in a
separate container, for the same reason: the entries remain
ordinary objects.  This follows the existing pattern of JMAP-specific
properties such as <spanx style="verb">id</spanx> being added to objects whose format is
defined elsewhere; the <spanx style="verb">objectHistory</spanx> name is reserved in the
relevant property registries (see <xref target="iana-considerations"/>).</t>

<t>Each entry is a full copy of the object rather than a patch
against the previous version.  Patches would save space, but the
client would need every intermediate version to reconstruct any
one of them, which conflicts with the server's freedom to prune
versions, and the final version of a destroyed object would need
to be returned in full anyway.</t>

<t>Every superseded version carries a <spanx style="verb">replaced</spanx> timestamp.  The
server always knows, at least approximately, when it replaced a
snapshot it was keeping, and the timestamp is what a client needs
to present history to a user and to filter it with <spanx style="verb">historyAfter</spanx>.</t>

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

<section anchor="jmap-capability-registration-for-urnietfparamsjmapobject-history"><name>JMAP Capability Registration for urn:ietf:params:jmap:object-history</name>

<t>IANA is requested to register the "Object History" Capability
as follows:</t>

<t>Capability Name: urn:ietf:params:jmap:object-history</t>

<t>Intended use: common</t>

<t>Change Controller: IETF</t>

<t>Specification document: this document</t>

<t>Security and privacy considerations: this document,
Security Considerations</t>

</section>
<section anchor="update-to-the-jmap-data-types-registry"><name>Update to the JMAP Data Types Registry</name>

<t>This document adds a "Supports History" column to the "JMAP Data
Types" registry <xref target="IANA-JMAP"/>.  The value
is "Yes" or "No", indicating whether the data type supports the
history extensions defined in this document.</t>

<t>The initial values for existing registrations are:</t>

<texttable>
      <ttcol align='left'>Type Name</ttcol>
      <ttcol align='left'>Supports History</ttcol>
      <c>Core</c>
      <c>No</c>
      <c>PushSubscription</c>
      <c>No</c>
      <c>Mailbox</c>
      <c>Yes</c>
      <c>Thread</c>
      <c>No</c>
      <c>Email</c>
      <c>Yes</c>
      <c>EmailDelivery</c>
      <c>No</c>
      <c>SearchSnippet</c>
      <c>No</c>
      <c>Identity</c>
      <c>Yes</c>
      <c>EmailSubmission</c>
      <c>No</c>
      <c>VacationResponse</c>
      <c>Yes</c>
      <c>MDN</c>
      <c>No</c>
      <c>Quota</c>
      <c>No</c>
      <c>SieveScript</c>
      <c>Yes</c>
      <c>Principal</c>
      <c>No</c>
      <c>ShareNotification</c>
      <c>No</c>
      <c>AddressBook</c>
      <c>Yes</c>
      <c>ContactCard</c>
      <c>Yes</c>
      <c>Calendar</c>
      <c>Yes</c>
      <c>CalendarEvent</c>
      <c>Yes</c>
      <c>CalendarEventNotification</c>
      <c>No</c>
      <c>ParticipantIdentity</c>
      <c>Yes</c>
</texttable>

<t>The default value for this column is "No".  New registrations
that do not explicitly include a value are assumed not to
support history.</t>

<t>This column records whether history is meaningful for a data type.
Whether a particular server supports history for a type is
advertised in the <spanx style="verb">supportedTypes</spanx> capability property.</t>

</section>
<section anchor="jscontact-property-registration"><name>JSContact Property Registration</name>

<t>IANA is requested to register the following property in the
"JSContact Properties" registry defined in <xref target="JSCONTACT"/>,
Section 3, so that the name cannot be used for a property of a
JSContact Card.</t>

<t>Property Name:  objectHistory</t>

<t>Property Type:  not applicable</t>

<t>Property Context:  Card</t>

<t>Intended Usage:  reserved</t>

<t>Since Version:  1.0</t>

<t>Change Controller:  IETF</t>

<t>Reference:  this document</t>

</section>
<section anchor="jscalendar-property-registration"><name>JSCalendar Property Registration</name>

<t>IANA is requested to register the following property in the
"JSCalendar Properties" registry defined in <xref target="JSCALENDAR"/>,
Section 8.2, so that the name cannot be used for a property of a
JSCalendar object.</t>

<t>Property Name:  objectHistory</t>

<t>Property Type:  not applicable</t>

<t>Property Context:  Event, Task, Group</t>

<t>Intended Usage:  reserved</t>

<t>Change Controller:  IETF</t>

<t>Reference:  this document</t>

<t>Specifications that define a JMAP data type whose object format is
also governed by a separate property registry <bcp14>SHOULD</bcp14> reserve the
<spanx style="verb">objectHistory</spanx> property name in that registry.</t>

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

<t>All security considerations from <xref target="JMAP-CORE"/> apply to this
document.</t>

<section anchor="storage-and-resource-consumption"><name>Storage and Resource Consumption</name>

<t>Retaining historical versions of objects can consume significant
server storage.  Servers <bcp14>SHOULD</bcp14> impose reasonable limits on
history retention, either by duration (advertised via
<spanx style="verb">maxHistoryDuration</spanx>) or by total storage.  Servers <bcp14>MAY</bcp14>
silently discard history entries when storage limits are
reached.</t>

</section>
<section anchor="access-control"><name>Access Control</name>

<t>Historical versions of an object <bcp14>MUST</bcp14> respect the same access
controls as the current version.  A user who does not have
permission to read an object <bcp14>MUST NOT</bcp14> be able to read its
history.</t>

<t>Access rights can change over time, for example when an object is
shared with a new user, or moved into a shared container.  The
server <bcp14>MUST NOT</bcp14> return a historical version to a user who could not
have read that version at the time it was current.  This requires
the server to track changes to access rights.  A server that does
not keep a full history of access rights can take a conservative
approach: record the point at which the access rights affecting an
object (or its containing object, such as a Mailbox or AddressBook)
last changed, for example as a modseq, and not return any version
that was replaced before that point.</t>

<t>Similarly, for destroyed objects, the server <bcp14>MUST NOT</bcp14> reveal the
existence or content of a destroyed object to a user who could not
read it at the time it was destroyed.</t>

</section>
<section anchor="information-disclosure"><name>Information Disclosure</name>

<t>Object history may reveal information that the user or an
administrator intended to remove.  For example, a contact
record that was updated to remove a phone number will still
have that phone number visible in its history.  Servers
<bcp14>SHOULD</bcp14> provide administrators with the ability to purge
history for specific objects when required for privacy or
compliance reasons.</t>

</section>
<section anchor="privacy-considerations"><name>Privacy Considerations</name>

<t>When a server supports this extension, updating or destroying an
object does not immediately remove the previous content from the
server; it remains retrievable by anyone with read access to the
object until the server discards it under its retention policy.
Users may not expect this.  This is not new in kind (servers
commonly retain deleted data in backups, and many mail systems
offer a "recently deleted" view), but this extension makes such
data retrievable through the protocol.</t>

<t>Servers <bcp14>SHOULD</bcp14> make their retention policy visible to users, for
example through the <spanx style="verb">maxHistoryDuration</spanx> capability property and
the server's user interface.  Clients that present a "destroy"
operation to users <bcp14>SHOULD NOT</bcp14> describe it as irreversible or
permanent when the server advertises this capability for that data
type.  Whether, and how, a user can request that history be purged
before the end of the retention period is a matter of server
policy and is outside the scope of this document.</t>

</section>
</section>
<section anchor="changes"><name>Changes</name>

<t>EDITOR: please remove this section before publication.</t>

<t>The source of this document exists on github at: https://github.com/brong/draft-gondwana-jmap-object-history/</t>

<t><strong>draft-ietf-jmap-object-history-01</strong></t>

<t><list style="symbols">
  <t>Removed "Updates: 8620"; the JMAP Data Types registry is not
defined by RFC 8620.  The registry is now referenced by name
rather than by its defining document.</t>
  <t>Corrected the registry table to match the current registry.</t>
  <t><spanx style="verb">historyLimit</spanx> is now per id.</t>
  <t>Defined behaviour for <spanx style="verb">ids: null</spanx> with <spanx style="verb">includeDestroyed</spanx>, and
clarified that "maxObjectsInGet" counts ids, not entries.</t>
  <t>Ids with no matching versions are returned in <spanx style="verb">notFound</spanx>.</t>
  <t>Which changes create a version, and the values of server-computed
properties, are server dependent.</t>
  <t>Blobs referenced by returned versions must be downloadable.</t>
  <t>Expanded access control considerations for changing access rights.</t>
  <t>Added <spanx style="verb">supportedTypes</spanx> to the account capability; requesting
history for an unsupported type is an error.</t>
  <t>Reserved the <spanx style="verb">objectHistory</spanx> property name in the JSContact and
JSCalendar property registries.</t>
  <t>Added acknowledgements.</t>
  <t>Added a Design Rationale section (Foo/get rather than a new method,
embedded metadata, full objects rather than patches, timestamps).</t>
  <t>Added a Restoring Objects section: a client may ask to recreate a
destroyed object with its old id, and the server may accept or
reject; ids of destroyed objects are otherwise not reused.</t>
  <t><spanx style="verb">maxHistoryDuration</spanx> is now a best-effort statement of server policy.</t>
  <t>Clarified that "objectHistory" may appear in <spanx style="verb">properties</spanx>.</t>
  <t>Added Privacy Considerations.</t>
  <t>Added <spanx style="verb">historyBefore</spanx> for paging backwards through history;
versions of the same object have distinct <spanx style="verb">replaced</spanx> values, with
at most millisecond precision.</t>
  <t>Removed the audit use case from the introduction.</t>
</list></t>

<t><strong>draft-ietf-jmap-object-history-00</strong></t>

<t><list style="symbols">
  <t>Uploaded with working-group adopted name.</t>
</list></t>

<t><strong>draft-gondwana-jmap-object-history-00</strong></t>

<t><list style="symbols">
  <t>initial proposal</t>
</list></t>

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

<t>The author would like to thank Ben Bucksch, Mauro De Gennaro,
Arnt Gulbrandsen, Neil Jenkins, and Robert Stepanek for their
feedback on this document.</t>

<t>{backmatter}</t>

</section>


  </middle>

  <back>


<references title='References' anchor="sec-combined-references">

    <references title='Normative References' anchor="sec-normative-references">



<reference anchor="JMAP-CORE">
  <front>
    <title>The JSON Meta Application Protocol (JMAP)</title>
    <author fullname="N. Jenkins" initials="N." surname="Jenkins"/>
    <author fullname="C. Newman" initials="C." surname="Newman"/>
    <date month="July" year="2019"/>
    <abstract>
      <t>This document specifies a protocol for clients to efficiently query, fetch, and modify JSON-based data objects, with support for push notification of changes and fast resynchronisation and for out-of- band binary data upload/download.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="8620"/>
  <seriesInfo name="DOI" value="10.17487/RFC8620"/>
</reference>

<reference anchor="RFC2119">
  <front>
    <title>Key words for use in RFCs to Indicate Requirement Levels</title>
    <author fullname="S. Bradner" initials="S." surname="Bradner"/>
    <date month="March" year="1997"/>
    <abstract>
      <t>In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
    </abstract>
  </front>
  <seriesInfo name="BCP" value="14"/>
  <seriesInfo name="RFC" value="2119"/>
  <seriesInfo name="DOI" value="10.17487/RFC2119"/>
</reference>

<reference anchor="RFC8174">
  <front>
    <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
    <author fullname="B. Leiba" initials="B." surname="Leiba"/>
    <date month="May" year="2017"/>
    <abstract>
      <t>RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t>
    </abstract>
  </front>
  <seriesInfo name="BCP" value="14"/>
  <seriesInfo name="RFC" value="8174"/>
  <seriesInfo name="DOI" value="10.17487/RFC8174"/>
</reference>




    </references>

    <references title='Informative References' anchor="sec-informative-references">



<reference anchor="JMAP-MAIL">
  <front>
    <title>The JSON Meta Application Protocol (JMAP) for Mail</title>
    <author fullname="N. Jenkins" initials="N." surname="Jenkins"/>
    <author fullname="C. Newman" initials="C." surname="Newman"/>
    <date month="August" year="2019"/>
    <abstract>
      <t>This document specifies a data model for synchronising email data with a server using the JSON Meta Application Protocol (JMAP). Clients can use this to efficiently search, access, organise, and send messages, and to get push notifications for fast resynchronisation when new messages are delivered or a change is made in another client.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="8621"/>
  <seriesInfo name="DOI" value="10.17487/RFC8621"/>
</reference>

<reference anchor="JMAP-CONTACTS">
  <front>
    <title>JSON Meta Application Protocol (JMAP) for Contacts</title>
    <author fullname="N. Jenkins" initials="N." role="editor" surname="Jenkins"/>
    <date month="December" year="2024"/>
    <abstract>
      <t>This document specifies a data model for synchronising contact data with a server using the JSON Meta Application Protocol (JMAP).</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="9610"/>
  <seriesInfo name="DOI" value="10.17487/RFC9610"/>
</reference>

<reference anchor="JSCONTACT">
  <front>
    <title>JSContact: A JSON Representation of Contact Data</title>
    <author fullname="R. Stepanek" initials="R." surname="Stepanek"/>
    <author fullname="M. Loffredo" initials="M." surname="Loffredo"/>
    <date month="May" year="2024"/>
    <abstract>
      <t>This specification defines a data model and JavaScript Object Notation (JSON) representation of contact card information that can be used for data storage and exchange in address book or directory applications. It aims to be an alternative to the vCard data format and to be unambiguous, extendable, and simple to process. In contrast to the JSON-based jCard format, it is not a direct mapping from the vCard data model and expands semantics where appropriate. Two additional specifications define new vCard elements and how to convert between JSContact and vCard.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="9553"/>
  <seriesInfo name="DOI" value="10.17487/RFC9553"/>
</reference>

<reference anchor="JSCALENDAR">
  <front>
    <title>JSCalendar: A JSON Representation of Calendar Data</title>
    <author fullname="N. Jenkins" initials="N." surname="Jenkins"/>
    <author fullname="R. Stepanek" initials="R." surname="Stepanek"/>
    <date month="July" year="2021"/>
    <abstract>
      <t>This specification defines a data model and JSON representation of calendar data that can be used for storage and data exchange in a calendaring and scheduling environment. It aims to be an alternative and, over time, successor to the widely deployed iCalendar data format. It also aims to be unambiguous, extendable, and simple to process. In contrast to the jCal format, which is also based on JSON, JSCalendar is not a direct mapping from iCalendar but defines the data model independently and expands semantics where appropriate.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="8984"/>
  <seriesInfo name="DOI" value="10.17487/RFC8984"/>
</reference>


<reference anchor="IANA-JMAP" target="https://www.iana.org/assignments/jmap/">
  <front>
    <title>JSON Meta Application Protocol (JMAP)</title>
    <author >
      <organization>IANA</organization>
    </author>
    <date year="n.d."/>
  </front>
</reference>


    </references>

</references>



  </back>

<!-- ##markdown-source:
H4sIAAAAAAAAA81d23LjyHm+76focC88mqI0kvbgXY7Ltua0K9ecLGmccjZb
URNokliBAIMGpGFmx5WHyAPkWfIoeZL8pz4AhDTatV3OXNgiiW50/8fvP3Tv
/v6+aou2tDP9h1cnb/Wb+Y82a/V3hWvrZqvMfN7Y6/Hf8jqrzBoG5o1ZtPuF
bRf7P67NZr+m5/ZX/Nz+4ZFy3XxdOFfU1cV2AyNOn1+8UJlp7RIemGnX5qqe
u7q0rXUzVWyamW6bzrXHh4ffHB6rK7u9qZscxlWtbSrb7j/DVyrXmir/N1PW
Fcy5tU5tipn+vq2zqXZ10zZ24eCv7Rr/+EEp07Wrupkpva80/CsqN9NPDvS3
dZXfmMrQl7yjJ01d9b+vm+VMvzCuXZuipG8s/jXTc3h0+fuF/NJasz7I6rVS
Vd2sTVtc2xk9jQTcf/rm7PlMn714+vVXx4dKFdVi5KFXJ6cv/UNH6djXFydP
L87pp2++Ojrkn87le/76yy8/91+fvHz++tnJGc/0zddf0PenJ69P9nE6fh/+
a02ztO1Mr9p242aPHt3c3BwUsOsD2PEjAzxbVmtbte4RsvZRHCYyc/7mtX5l
W6NPNpuyAJYCj/XbpgYm1KV+gO/aC4MCA/y//finpzEuUan9/X1t5q5tTNYq
dbGyLIFz46zehNmFknv41XWRW6fXFt6QOw2EBcZX2Qq4U/xHUS1VC3NkXdPA
XkDeQPR0vdC5gZWzuDo9t+2NtZXOygIfAtHSzjbXtjnQ+gKEWdn3ra1QiLXJ
4R04o5kXZdFudVvrxrZNYa+tZrkHWpQaBuPzDt8lr5kC27Oyy2FN4c3tyrR6
ZWDsHBcAG2mbemvzqZ5vNb2VHscXksibJlcv6voRME52fMAkWxd5XlqlPkNN
aeq8y5AfShHxHnz4EKTw40f9v//5X59gX0JXo/yLgSYtbieltDXZimnZknrL
2qb0R7Yy1dLCvvGD89/+e2eb7ZSIHD4+5SeJ3BYY7V9Rb2wDDFOwtFEuChl5
XPpOmUG3tixxD8LZm1UB6/XEJ7rzACR41+q8hqFV3frt41vVBuxgUXdOX5uy
g0UqdVrptam22kTSOV20unC6c3bRlSgVJsusc2MyoXorf4FkfG/Wm9ICVXCC
BmbfajBALc7jLAq+X0IyhdFZXbWgJiCAGRjJhM1sMD5+3APNol9hHDyfW7Sz
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
AXmM8PpHZgAA

-->

</rfc>

