JMAP                                                   N.M.

Internet Engineering Task Force (IETF)                   N. Jenkins, Ed.
Internet-Draft
Request for Comments: 9670                                      Fastmail
Updates: 8620 (if approved)                                18 April                                              November 2024
Intended status:
Category: Standards Track
Expires: 20 October 2024

                              JMAP
ISSN: 2070-1721

             JSON Meta Application Protocol (JMAP) Sharing
                       draft-ietf-jmap-sharing-09

Abstract

   This document specifies a data model for sharing data between users
   using JMAP. the JSON Meta Application Protocol (JMAP).  Future documents
   can reference this document when defining data types to support a
   consistent model of sharing.

Status of This Memo

   This Internet-Draft is submitted in full conformance with the
   provisions of BCP 78 and BCP 79.

   Internet-Drafts are working documents an Internet Standards Track document.

   This document is a product of the Internet Engineering Task Force
   (IETF).  Note that other groups may also distribute
   working documents as Internet-Drafts.  The list  It represents the consensus of current Internet-
   Drafts is at https://datatracker.ietf.org/drafts/current/.

   Internet-Drafts are draft documents valid the IETF community.  It has
   received public review and has been approved for a maximum publication by the
   Internet Engineering Steering Group (IESG).  Further information on
   Internet Standards is available in Section 2 of RFC 7841.

   Information about the current status of six months this document, any errata,
   and how to provide feedback on it may be updated, replaced, or obsoleted by other documents obtained at any
   time.  It is inappropriate to use Internet-Drafts as reference
   material or to cite them other than as "work in progress."

   This Internet-Draft will expire on 20 October 2024.
   https://www.rfc-editor.org/info/rfc9670.

Copyright Notice

   Copyright (c) 2024 IETF Trust and the persons identified as the
   document authors.  All rights reserved.

   This document is subject to BCP 78 and the IETF Trust's Legal
   Provisions Relating to IETF Documents (https://trustee.ietf.org/
   license-info)
   (https://trustee.ietf.org/license-info) in effect on the date of
   publication of this document.  Please review these documents
   carefully, as they describe your rights and restrictions with respect
   to this document.  Code Components extracted from this document must
   include Revised BSD License text as described in Section 4.e of the
   Trust Legal Provisions and are provided without warranty as described
   in the Revised BSD License.

Table of Contents

   1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   3
     1.1.  Notational Conventions  . . . . . . . . . . . . . . . . .   3
     1.2.  Terminology . . . . . . . . . . . . . . . . . . . . . . .   3
     1.3.  Data Model Overview . . . . . . . . . . . . . . . . . . .   4
     1.4.  Subscribing to Shared Data  . . . . . . . . . . . . . . .   4
     1.5.  Addition to the Capabilities Object . . . . . . . . . . .   5
       1.5.1.  urn:ietf:params:jmap:principals . . . . . . . . . . .   5
       1.5.2.  urn:ietf:params:jmap:principals:owner . . . . . . . .   5
   2.  Principals  . . . . . . . . . . . . . . . . . . . . . . . . .   6
     2.1.  Principal/get . . . . . . . . . . . . . . . . . . . . . .   7
     2.2.  Principal/changes . . . . . . . . . . . . . . . . . . . .   7
     2.3.  Principal/set . . . . . . . . . . . . . . . . . . . . . .   7
     2.4.  Principal/query . . . . . . . . . . . . . . . . . . . . .   7
       2.4.1.  Filtering . . . . . . . . . . . . . . . . . . . . . .   7
     2.5.  Principal/queryChanges  . . . . . . . . . . . . . . . . .   8
   3.  Share Notifications . . . . . . . . . . . . . . . . . . . . .   8  ShareNotifications
     3.1.  Auto-deletion of Notifications  . . . . . . . . . . . . .   9
     3.2.  Object Properties . . . . . . . . . . . . . . . . . . . .   9
     3.3.  ShareNotification/get . . . . . . . . . . . . . . . . . .  10
     3.4.
     3.2.  ShareNotification/changes . . . . . . . . . . . . . . . .  10
     3.5.
     3.3.  ShareNotification/set . . . . . . . . . . . . . . . . . .  10
     3.6.
     3.4.  ShareNotification/query . . . . . . . . . . . . . . . . .  10
       3.6.1.
       3.4.1.  Filtering . . . . . . . . . . . . . . . . . . . . . .  10
       3.6.2.
       3.4.2.  Sorting . . . . . . . . . . . . . . . . . . . . . . .  11
     3.7.
     3.5.  ShareNotification/queryChanges  . . . . . . . . . . . . .  11
   4.  Framework for Shared Data . . . . . . . . . . . . . . . . . .  11
     4.1.  Example . . . . . . . . . . . . . . . . . . . . . . . . .  11
   5.  Internationalisation  Internationalization Considerations . . . . . . . . . . . . .  15
   6.  Security Considerations . . . . . . . . . . . . . . . . . . .  15
     6.1.  Spoofing  . . . . . . . . . . . . . . . . . . . . . . . .  15
     6.2.  Unnoticed Sharing . . . . . . . . . . . . . . . . . . . .  16
     6.3.  Denial of Service . . . . . . . . . . . . . . . . . . . .  16
     6.4.  Unauthorised  Unauthorized Principals . . . . . . . . . . . . . . . . .  16
   7.  IANA Considerations . . . . . . . . . . . . . . . . . . . . .  16
     7.1.  JMAP Capability Registration for "principals" . . . . . .  16
     7.2.  JMAP Capability Registration for "principals:owner" . . .  17
     7.3.  JMAP Data Type Registration for "Principal" . . . . . . .  17
     7.4.  JMAP Data Type Registration for "ShareNotification" . . .  17
   8.  References
     8.1.  Normative References  . . . . . . . . . . . . . . . . . . . .  17
   9.
     8.2.  Informative References  . . . . . . . . . . . . . . . . . . .  18
   Author's Address  . . . . . . . . . . . . . . . . . . . . . . . .  18

1.  Introduction

   JMAP ([RFC8620]

   The JSON Meta Application Protocol) Protocol (JMAP) [RFC8620] is a generic
   protocol for synchronizing data, such as mail, calendars calendars, or
   contacts, between a client and a server.  It is optimized for mobile
   and web
   environments, environments and provides a consistent interface to query,
   read, and modify different data types, including comprehensive error
   handling.

   This specification defines a data model to represent entities in a
   collaborative environment, environment and a framework for sharing data between
   them that can be used to provide a consistent sharing model for
   different data types.  It does not define _what_ may be shared, shared or the
   granularity of permissions, as this will depend on the data in
   question.

1.1.  Notational Conventions

   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.

   Type signatures, examples, and property descriptions in this document
   follow the conventions established in Section 1.1 of [RFC8620].  Data
   types defined in the core specification are also used in this
   document.

   Examples of API exchanges only show the methodCalls array of the
   Request object or the methodResponses array of the Response object.
   For compactness, the rest of the Request/Response object is omitted.

1.2.  Terminology

   The same terminology is used in this document as in the core JMAP
   specification, see
   specification.  See [RFC8620], Section 1.6.

   The terms Principal, "Principal" and ShareNotification "ShareNotification" (with these this specific
   capitalizations)
   capitalization) are used to refer to the data types defined in this
   document and instances of those data types.

1.3.  Data Model Overview

   A Principal (see Section 2) represents an individual, team, or
   resource (e.g., a room or projector).  The object contains
   information about the entity being represented, such as a name,
   description, and time zone.  It may also hold domain-specific
   information.  A Principal may be associated with zero or more
   Accounts (see [RFC8620], Section 1.6.2) containing data belonging to
   the Principal.  Managing the set of Principals within a system is out
   of scope for this specification, as it is highly domain specific.  It
   is likely to map directly from a directory service or other user
   management system.

   Data types may allow users to share data with others by assigning
   permissions to Principals.  When a user's permissions are changed, a
   ShareNotification object is created for them so a client can inform
   the user of the changes.

1.4.  Subscribing to Shared Data

   Permissions determine whether a user _may_ access data, data but not
   whether they _want_ to.  Some shared data is of equal importance as
   the user's own, while other data is just there should the user wish
   to explicitly go find it.  Clients will often want to differentiate
   the two.  For example, a company may share mailing list archives for
   all departments with all employees, but a user may only generally be
   interested in the few they belong to.  They would have _permission_
   to access many mailboxes, mailboxes but can _subscribe_ to just the ones they
   care about.  The client would provide separate interfaces for reading
   mail in subscribed mailboxes and browsing all mailboxes they have
   permission to access in order to manage which those that they are
   subscribed to.

   The JMAP Session object (see [RFC8620], Section 2) is defined to
   include an object in the accounts "accounts" property for every account Account that
   the user has access to.  Collaborative systems may share data between
   a very large number of Principals, most of which the user does not
   care about day-to-day. day to day.  For servers implementing this specification,
   the Session object MUST only include Accounts where either the user
   is subscribed to at least one record (see [RFC8620], Section 1.6.3)
   in the account, Account or the account Account belongs to the user.  StateChange
   events ([RFC8620], Section 7.1) for changes to data SHOULD only be
   sent for data the user has subscribed to and MUST NOT be sent for any account
   Account where the user is not subscribed to any records in the account,
   Account, except where that account Account belongs to the user.

   The server MAY reject the user's attempt to subscribe to some
   resources even if they have permission to access them (e.g., a
   calendar representing a location).

   A user can query the set of Principals they have access to with
   "Principal/query" (see Section 2.4).  The Principal object will
   contain an Account object for all accounts Accounts where the user has
   permission to access data for that Principal, even if they are not
   yet subscribed.

1.5.  Addition to the Capabilities Object

   The capabilities object is returned as part of the JMAP Session
   object; see [RFC8620], Section 2.  This document defines two
   additional capability URIs.

1.5.1.  urn:ietf:params:jmap:principals

   The urn:ietf:params:jmap:principals capability represents support for
   the Principal and ShareNotification data types and associated API
   methods.

   The value of this property in the JMAP Session capabilities "capabilities"
   property is an empty object.

   The value of this property in an account’s accountCapabilities Account's "accountCapabilities"
   property is an object that MUST contain the following information on
   server capabilities and permissions for that account:

   * Account:

   *currentUserPrincipalId*: Id|null
      The id of the Principal in this account Account that corresponds to the
      user fetching this object, if any.

1.5.2.  urn:ietf:params:jmap:principals:owner

   The URI urn:ietf:params:jmap:principals:owner is solely used as a key
   in an account’s accountCapabilities Account's "accountCapabilities" property.  It does not appear
   in the JMAP Session capabilities  -- support is indicated by the
   urn:ietf:params:jmap:principals URI being present in the session
   capabilities.

   If urn:ietf:params:jmap:principals:owner is a key in an account’s
   accountCapabilities, Account's
   "accountCapabilities" property, that account Account (and the data therein)
   is owned by a Principal.  Some accounts Accounts may not be owned by a
   Principal (e.g., the
   account Account that contains the data for the
   Principals themselves), in which case this property is omitted.

   The value of this property is an object with the following
   properties:

   *

   *accountIdForPrincipal*: Id
      The id of an account Account with the urn:ietf:params:jmap:principals
      capability that contains the corresponding Principal object.
   *  *principalId*: Id

   *principalId*:Id
      The id of the Principal that owns this account. Account.

2.  Principals

   A Principal represents an individual, a group, a location (e.g., a
   room), a resource (e.g., a projector) projector), or other another entity in a
   collaborative environment.  Sharing in JMAP is generally configured
   by assigning rights to certain data within an account Account to other
   Principals.  For example, a user may assign permission to read their
   calendar to a Principal representing another user or their team.

   In a shared environment environment, such as a workplace, a user may have access
   to a large number of Principals.

   In most systems, the user will have access to a single Account
   containing Principal objects.  In some situations, for example example, when
   aggregating data from different places, there may be multiple
   Accounts containing Principal objects.

   A *Principal* object has the following properties:

   *

   *id*: Id (immutable; server-set)
      The id of the Principal.
   *

   *type*: String
      This MUST be one of the following values:
      -  individual:

      *  "individual": This represents a single person.
      -  group:
      *  "group": This represents a group of other Principals.
      -  resource:
      *  "resource": This represents some resource, e.g., a projector.
      -  location:
      *  "location": This represents a location.
      -  other:
      *  "other": This represents some other undefined Principal.
   *

   *name*: String
      The name of the Principal, e.g., "Jane Doe", Doe" or "Room 4B".
   *

   *description*: String|null
      A longer description of the Principal, for example example, details about
      the facilities of a resource, or null if no description is
      available.
   *

   *email*: String|null
      An email address for the Principal, or null if no email is
      available.  If given, the value MUST conform to the "addr-spec"
      syntax, as defined in [RFC5322], Section 3.4.1.
   *

   *timeZone*: String|null
      The time zone for this Principal, if known.  If not null, the
      value MUST be a time zone name from the IANA Time Zone Database
      TZDB (https://www.iana.org/time-zones).
   *
      [IANA-TZDB].

   *capabilities*: String[Object] (server-set)
      A map of JMAP capability URIs to domain specific domain-specific information about
      the Principal in relation to that capability, as defined in the
      document that registered the capability.
   *

   *accounts*: Id[Account]|null (server-set)
      A map of account Account id to Account object for each JMAP Account
      containing data for this Principal that the user has access to, or
      null if none.

2.1.  Principal/get

   This is a standard "/get" method as described in [RFC8620],
   Section 5.1.

2.2.  Principal/changes

   This is a standard "/changes" method as described in [RFC8620],
   Section 5.2.

      |  Note: implementations Implementations backed by an external directory may be
      |  unable to calculate changes.  In this case, they will always
      |  return a "cannotCalculateChanges" error as described in the
      |  core JMAP specification.

2.3.  Principal/set

   This is a standard "/set" method as described in [RFC8620],
   Section 5.3.

   Managing Principals is likely tied to a directory service or some
   other vendor-specific solution.  This management may occur out-of-
   band, out of
   band or via an additional capability defined elsewhere.  Allowing
   direct user modification of properties has security considerations,
   as noted in Section 6.  Servers  A server MUST reject any change it doesn’t doesn't
   allow with a forbidden "forbidden" SetError.

   Where a server does support changes via this API, it SHOULD allow an
   update to the "name", "description" "description", and "timeZone" properties of the
   Principal with the same id as the "currentUserPrincipalId" in the
   Account capabilities.  This allows the user to update their own
   details.

2.4.  Principal/query

   This is a standard "/query" method as described in [RFC8620],
   Section 5.5 5.5.

2.4.1.  Filtering

   A *FilterCondition* object has the following properties, all of which
   are optional:

   *

   *accountIds*: String[]
      A list of account Account ids.  The Principal matches if any of the ids in
      this list are keys in the Principal's "accounts" property (i.e.,
      if any of the account Account ids belong to the Principal).
   *

   *email*: String
      The email property of the Principal contains the given string.
   *

   *name*: String
      The name property of the Principal contains the given string.
   *  *text*

   *text*: String
      The name, email, or description property of the Principal contains
      the given string.
   *

   *type*: String
      The type must be exactly as given to match the condition.
   *

   *timeZone*: String
      The timeZone must be exactly as given to match the condition.

   All given conditions in the FilterCondition object must match for the
   Principal to match.

   Text matches for "contains" SHOULD be simple substring matches.

2.5.  Principal/queryChanges

   This is a standard "/queryChanges" method as described in [RFC8620],
   Section 5.6.

      |  Note: implementations Implementations backed by an external directory may be
      |  unable to calculate changes.  In this case, they will always
      |  return a "cannotCalculateChanges" error as described in the
      |  core JMAP specification.

3.  Share Notifications  ShareNotifications

   The ShareNotification data type records when the user's permissions
   to access a shared object changes.  ShareNotification  ShareNotifications are only
   created by the server; users cannot create them explicitly.
   Notifications  They are
   stored in the same Account as the Principals.

   Clients may present the list of notifications to the user and allow
   them
   the user to dismiss them.  To dismiss a notification you notification, use a standard
   "/set" call to destroy it.

   The server SHOULD create a ShareNotification whenever the user's
   permissions change on an object.  It MAY choose not to create a
   notification for permission changes to a group Principal, even if the
   user is in the group, if this is more likely to be overwhelming than
   helpful, or if it would create excessive notifications within the
   system.

3.1.  Auto-deletion of Notifications

   The server MAY limit the maximum number of notifications it will
   store for a user.  When the limit is reached, any new notification
   will cause the previously oldest notification to be automatically
   deleted.

   The server MAY coalesce notifications if appropriate, appropriate or remove
   notifications after a certain period of time or that it deems are no
   longer relevant or after a certain
   period of time.

3.2.  Object Properties

   The relevant.

   A *ShareNotification* object has the following properties:

   *

   *id*: String (immutable; server-set)
      The id of the ShareNotification.
   *

   *created*: UTCDate (immutable; server-set)
      The time this notification was created.
   *

   *changedBy*: Entity (immutable; server-set)
      Who made the change.
      -  An *Entity* object has the following
      properties:

      *name*: String
         The name of the entity who made the change.
      -
      *email*: String|null
         The email of the entity who made the change, or null if no
         email is available.
      -
      *principalId*: Id|null
         The id of the Principal corresponding to the entity who made
         the change, or null if no associated Principal.
   *

   *objectType*: String (immutable; server-set)
      The name of the data type for the object whose permissions have
      changed, as registered in the IANA JMAP "JMAP Data Types Types" registry
      (https://www.iana.org/assignments/jmap/jmap.xhtml#jmap-data-
      types).
      [IANA-JMAP], e.g., "Calendar" or "Mailbox".
   *

   *objectAccountId*: Id (immutable; server-set)
      The id of the account Account where this object exists.
   *

   *objectId*: Id (immutable; server-set)
      The id of the object that this notification is about.
   *

   *oldRights*: String[Boolean]|null (immutable; server-set)
      The "myRights" property of the object for the user before the
      change.
   *

   *newRights*: String[Boolean]|null (immutable; server-set)
      The "myRights" property of the object for the user after the
      change.
   *

   *name*: String (immutable; server-set)
      The name of the object at the time the notification was made.
      Determining the name will depend on the data type in question.
      For example, it might be the "title" property of a CalendarEvent
      or the "name" of a Mailbox.  The name is to show to users who have
      had their access rights to the object removed, so that these users
      know removed what it is that they
      can no longer access.

3.3.

3.1.  ShareNotification/get

   This is a standard "/get" method as described in [RFC8620],
   Section 5.1.

3.4.

3.2.  ShareNotification/changes

   This is a standard "/changes" method as described in [RFC8620],
   Section 5.2.

3.5.

3.3.  ShareNotification/set

   This is a standard "/set" method as described in [RFC8620],
   Section 5.3.

   Only destroy is supported; any attempt to create/update MUST be
   rejected with a forbidden "forbidden" SetError.

3.6.

3.4.  ShareNotification/query

   This is a standard "/query" method as described in [RFC8620],
   Section 5.5.

3.6.1.

3.4.1.  Filtering

   A *FilterCondition* object has the following properties, all of which
   are optional:

   *

   *after*: UTCDate|null
      The creation date must be on or after this date to match the
      condition.
   *

   *before*: UTCDate|null
      The creation date must be before this date to match the condition.
   *

   *objectType*: String
      The objectType value must be identical to the given value to match
      the condition.
   *

   *objectAccountId*: Id
      The objectAccountId value must be identical to the given value to
      match the condition.

   All given conditions in the FilterCondition object must match for the
   ShareNotification to match.

3.6.2.

3.4.2.  Sorting

   The "created" property MUST be supported for sorting.

3.7.

3.5.  ShareNotification/queryChanges

   This is a standard "/queryChanges" method as described in [RFC8620],
   Section 5.6.

4.  Framework for Shared Data

   Shareable data types MUST define the following three properties:

   *

   *isSubscribed*: Boolean
      >
      The value true indicates that the user wishes to subscribe to see
      this data.  The value false indicates that the user does not wish
      to subscribe to see this data.  The initial value for this
      property when data is shared by another user is implementation
      dependent, although data types may give advice on appropriate
      defaults.
   *

   *myRights*: String[Boolean]
      The set of permissions the user currently has.  Appropriate
      permissions are domain specific and must be defined per data type.
      Each key is the name of a permission defined for that data type.
      The value for the key is true if the user has the permission, permission or
      false if they do not.
   *

   *shareWith*: Id[String[Boolean]]|null
      The value of this property is null if the data is not shared with
      anyone.  Otherwise, it is a map where each key is the id of a
      Principal with which this data is shared, and the value associated
      with that key is the rights to give that Principal, in the same
      format as the myRights "myRights" property.  The account Account id for the
      Principal id can be found in the capabilities of the Account this
      object is in (see Section 1.5.2).

      Users with appropriate permission may set this property to modify
      who the data is shared with.  The Principal that owns the account Account
      that this data is in MUST NOT be in the set of sharees map, since the owner's
      rights are implicit.

4.1.  Example

   Suppose we are designing a data model for a very simple todo to-do list.
   There is a Todo data type representing a single item to do, each of
   which belongs to a single TodoList.  The specification makes the
   lists
   TodoLists shareable by referencing this document and defining the
   common properties.

   First

   First, it would define a set of domain-specific rights.  For example,
   a TodoListRights object may have the following properties:

   *

   *mayRead*: Boolean
      The user may fetch this TodoList, TodoList and any Todos that belong to this
      TodoList.
   *

   *mayWrite*: Boolean
      The user may create, update, or destroy Todos that belong to this
      TodoList,
      TodoList and may change the "name" property of this TodoList.
   *

   *mayAdmin*: Boolean
      The user may see and modify the "myRights" property of this
      TodoList,
      TodoList and may destroy this TodoList.

   Then in the TodoList data type, we would include the three common
   properties,
   properties described in Section 4, in addition to any type-specific
   properties (like "name" in this case):

   *

   *id*: Id (immutable; server-set)
      The id of the object.
   *

   *name*: String
      A name for this list of todos.
   * Todos.

   *isSubscribed*: Boolean
      True if the user has indicated they wish to see this list.  If
      false, clients should not display this todo list TodoList with the user's
      other lists, TodoLists but should provide a means for users to see and
      subscribe to all lists TodoLists that have been shared with them.
   *

   *myRights*: TodoListRights
      The set of permissions the user currently has for this todo list.
   * TodoList.

   *shareWith*: Id[TodoListRights]|null
      A map of Principal id to rights to give that Principal, or null if
      If not shared with anyone or anyone, the user does not have value is null.  Otherwise, it's a
      map where the "mayAdmin"
      right for this list. keys are Principal ids and the values are the rights
      given to those Principals.  Users with the "mayAdmin" right may
      set this property to modify who the data is shared with.  The
      Principal that owns the account Account that this data is in MUST NOT be
      in the set of
      sharees; map; their rights are implicit.

   We would also define a new Principal capability with two properties:

   *

   *accountId*: Id|null
      The accountId containing the todo Todo data for this Principal, if it
      has been shared with the requesting user.
   *

   *mayShareWith*: Boolean
      May the
      The user add may give this Principal as a sharee of permission to access a todo list? TodoList.

   A client wishing to let the user configure sharing would look at the
   account capabilities
   "capabilities" for the Account containing the user's Todo data, data and
   find the "urn:ietf:params:jmap:principals:owner" property, as per
   Section 1.5.2.  For example, the JMAP Session object might contain:

   {
     "accounts": {
       "u12345678": {
         "name": "jane.doe@example.com",
         "isPersonal": true,
         "isReadOnly": false,
         "accountCapabilities": {
           "urn:com.example:jmap:todo": {},
           "urn:ietf:params:jmap:principals:owner": {
             "accountIdForPrincipal": "u33084183",
             "principalId": "P105aga511jaa"
           }
         }
       },
       ...
     },
     ...
   }

                  Figure 1 1: Part of a JMAP Session Object

   From this it this, the client now knows which account Account has the Principal data,
   and it can fetch the list of Principals to and offer the user to share it with
   the list
   with, user by making an API request like this:

   [[ "Principal/get", {
     "accountId": "u33084183",
     "ids": null
   }, "0" ]]

             Figure 2 2: "methodCalls" Property of a JMAP Request

   Here's an example response (where Joe Bloggs "Joe Bloggs" is another user that
   this user could share their todo list with, but who TodoList with; Joe has not shared any data in of
   their own account data with this user): user, so the "accounts" property is null):

   [[ "Principal/get", {
     "accountId": "u33084183",
     "state": "7b8eff5zz",
     "list": [{
       "id": "P2342fnddd20",
       "type": "individual",
       "name": "Joe Bloggs",
       "description": null,
       "email": "joe.bloggs@example.com",
       "timeZone": "Australia/Melbourne",
       "capabilities": {
           "urn:com.example:jmap:todo": {
               "accountId": null,
               "mayShareWith": true
           }
       },
       "accounts": null
     }, {
       "id": "P674pp24095qo49pr",
       "name": "Board room",
       "type": "location",
       ...
     }, ... ],
     "notFound": []
   }, "0" ]]

          Figure 3 3: "methodResponses" Property of a JMAP Response

   A todo list TodoList can be shared with Joe Bloggs "Joe Bloggs" by updating its shareWith
   property, as in this example request:

   [[ "TodoList/set", {
     "accountId": "u12345678",
     "update": {
       "tl01n231": {
           "shareWith": {
               "P2342fnddd20": {
                   "mayRead": true,
                   "mayWrite": true,
                   "mayAdmin": false
               }
           }
       }
     }
   }, "0" ]]

             Figure 4 4: "methodCalls" Property of a JMAP Request

5.  Internationalisation  Internationalization Considerations

   Experience has shown that unrestricted use of Unicode can lead to
   problems such as inconsistent rendering, users reading text and
   interpreting it differently than intended, and unexpected results
   when copying text from one location to another.  Servers MAY choose
   to mitigate this by restricting the set of characters allowed in
   otherwise unconstrained String fields.  The FreeformClass, as
   documented in [RFC8264], Section 4.3 4.3, might be a good starting point
   for this.

   Attempts to set a value containing code points outside of the
   permissible set can be handled in a few ways by the server.  The
   first option is to simply strip the forbidden characters and store
   the resulting string.  This is likely to be appropriate for control
   characters
   characters, for example, where they can end up in data accidentally
   due to copy-and-paste issues, issues and are probably invisible to the end
   user.  JMAP allows the server to transform data on create/update, as
   long as any changed properties are returned to the client in the /set
   response,
   "/set" response so it knows what has changed, as per [RFC8620],
   Section 5.3.  Alternatively, the server MAY just reject the create/
   update with an invalidProperties "invalidProperties" SetError.

6.  Security Considerations

   All security considerations of JMAP [RFC8620] apply to this
   specification.  Additional considerations are detailed below.

6.1.  Spoofing

   Allowing users to edit their own Principal's name (and, to a lesser
   extent, email, description, or type) could allow a user to change
   their Principal to look like another user in the system, potentially
   tricking others into sharing private data with them.  Servers may
   choose to forbid this, this and SHOULD keep logs of such changes to provide
   an audit trail.

   Note that simply forbidding the use of a name already in the system
   is insufficient protection, as a malicious user could still change
   their name to something easily confused with the existing name by
   using trivial misspellings or visually similar Unicode characters.

6.2.  Unnoticed Sharing

   Sharing data with another user allows someone to turn a transitory
   account compromise (e.g., brief access to an unlocked or logged-in
   client) into a persistent compromise (by setting up sharing with a
   user that is controlled by the attacker).  This can be mitigated by
   requiring further authorisation authorization for configuring sharing, sharing or sending
   notifications to the sharer via another channel whenever a new sharee
   permission is added.

6.3.  Denial of Service

   By creating many changes to the sharing status of objects, a user can
   cause many ShareNotifications to be generated, which could lead to
   resource exhaustion.  Servers can mitigate this by coalescing
   multiple changes to the same object into a single notification,
   limiting the maximum number of notifications it stores per user, user and/
   or rate limiting rate-limiting the changes to sharing permissions in the first
   place.  Automatically deleting older notifications after reaching a
   limit can mean the user is not made aware of a sharing change, which
   can itself be a security issue.  For this reason, it is better to
   coalesce changes and use other mitigation strategies.

6.4.  Unauthorised  Unauthorized Principals

   The set of Principals within a shared environment MUST be strictly
   controlled.  If adding a new Principal is open to the public, risks
   include:

   *  An increased risk of a user accidentally sharing data with an
      unintended person.
   *  An attacker may share sharing unwanted or offensive information with the
      user.
   *  An attacker may share sharing items with spam content in the names in order
      to generate ShareNotification objects, which are likely to be
      prominently displayed to the sharee. user receiving them.

7.  IANA Considerations

7.1.  JMAP Capability Registration for "principals"

   IANA will register the has registered "principals" JMAP Capability in the "JMAP Capabilities" registry
   as follows:

   Capability Name:  urn:ietf:params:jmap:principals

   Specification document: this document
   Intended use: Use:  common
   Change Controller:  IETF
   Security and privacy considerations: this document, Privacy Considerations:  RFC 9670, Section 6
   Reference:  RFC 9670

7.2.  JMAP Capability Registration for "principals:owner"

   IANA will register the has registered "principals:owner" JMAP Capability in the "JMAP Capabilities"
   registry as follows:

   Capability Name:  urn:ietf:params:jmap:principals:owner

   Specification document: this document
   Intended use: Use:  common
   Change Controller:  IETF
   Security and privacy considerations: this document, Privacy Considerations:  RFC 9670, Section 6
   Reference:  RFC 9670

7.3.  JMAP Data Type Registration for "Principal"

   IANA will register the has registered "Principal" JMAP in the "JMAP Data Type Types" registry as
   follows:

   Type Name:  Principal
   Can reference blobs: no Reference Blobs:  No
   Can Use for State Change: yes  Yes
   Capability:  urn:ietf:params:jmap:principals

   Specification document: this document
   Reference:  RFC 9670

7.4.  JMAP Data Type Registration for "ShareNotification"

   IANA will register the has registered "ShareNotification" JMAP in the "JMAP Data Type Types"
   registry as follows:

   Type Name:  ShareNotification
   Can reference blobs: no Reference Blobs:  No
   Can Use for State Change: yes  Yes
   Capability:  urn:ietf:params:jmap:principals

   Specification document: this document
   Reference:  RFC 9670

8.  References

8.1.  Normative References

   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
              Requirement Levels", BCP 14, RFC 2119,
              DOI 10.17487/RFC2119, March 1997,
              <https://www.rfc-editor.org/info/rfc2119>.

   [RFC5322]  Resnick, P., Ed., "Internet Message Format", RFC 5322,
              DOI 10.17487/RFC5322, October 2008,
              <https://www.rfc-editor.org/info/rfc5322>.

   [RFC8174]  Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
              2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
              May 2017, <https://www.rfc-editor.org/info/rfc8174>.

   [RFC8620]  Jenkins, N. and C. Newman, "The JSON Meta Application
              Protocol (JMAP)", RFC 8620, DOI 10.17487/RFC8620, July
              2019, <https://www.rfc-editor.org/info/rfc8620>.

9.

8.2.  Informative References

   [IANA-JMAP]
              IANA, "JMAP Data Types",
              <https://www.iana.org/assignments/jmap>.

   [IANA-TZDB]
              IANA, "Time Zone Database",
              <https://www.iana.org/time-zones>.

   [RFC8264]  Saint-Andre, P. and M. Blanchet, "PRECIS Framework:
              Preparation, Enforcement, and Comparison of
              Internationalized Strings in Application Protocols",
              RFC 8264, DOI 10.17487/RFC8264, October 2017,
              <https://www.rfc-editor.org/info/rfc8264>.

Author's Address

   Neil Jenkins (editor)
   Fastmail
   PO Box 234, Collins St West
   Melbourne VIC 8007
   Australia
   Email: neilj@fastmailteam.com
   URI:   https://www.fastmail.com