summaryrefslogtreecommitdiff
path: root/doc/rfc/rfc9661.txt
diff options
context:
space:
mode:
authorThomas Voss <mail@thomasvoss.com> 2024-11-27 20:54:24 +0100
committerThomas Voss <mail@thomasvoss.com> 2024-11-27 20:54:24 +0100
commit4bfd864f10b68b71482b35c818559068ef8d5797 (patch)
treee3989f47a7994642eb325063d46e8f08ffa681dc /doc/rfc/rfc9661.txt
parentea76e11061bda059ae9f9ad130a9895cc85607db (diff)
doc: Add RFC documents
Diffstat (limited to 'doc/rfc/rfc9661.txt')
-rw-r--r--doc/rfc/rfc9661.txt1015
1 files changed, 1015 insertions, 0 deletions
diff --git a/doc/rfc/rfc9661.txt b/doc/rfc/rfc9661.txt
new file mode 100644
index 0000000..52d30f6
--- /dev/null
+++ b/doc/rfc/rfc9661.txt
@@ -0,0 +1,1015 @@
+
+
+
+
+Internet Engineering Task Force (IETF) K. Murchison
+Request for Comments: 9661 Fastmail
+Category: Standards Track September 2024
+ISSN: 2070-1721
+
+
+ The JSON Meta Application Protocol (JMAP) for Sieve Scripts
+
+Abstract
+
+ This document specifies a data model for managing Sieve scripts on a
+ server using the JSON Meta Application Protocol (JMAP). Clients can
+ use this protocol to efficiently search, access, organize, and
+ validate Sieve scripts.
+
+Status of This Memo
+
+ This is an Internet Standards Track document.
+
+ This document is a product of the Internet Engineering Task Force
+ (IETF). It represents the consensus of the IETF community. It has
+ received public review and has been approved for 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 this document, any errata,
+ and how to provide feedback on it may be obtained at
+ https://www.rfc-editor.org/info/rfc9661.
+
+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) 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
+ 1.1. Notational Conventions
+ 1.2. Addition to the Capabilities Object
+ 1.2.1. urn:ietf:params:jmap:sieve
+ 1.2.2. Example
+ 2. Sieve Scripts
+ 2.1. Sieve Script Properties
+ 2.2. Sieve Script Content
+ 2.3. SieveScript/get
+ 2.3.1. Examples
+ 2.4. SieveScript/set
+ 2.4.1. Examples
+ 2.5. SieveScript/query
+ 2.6. SieveScript/validate
+ 3. Quotas
+ 4. Compatibility with JMAP Vacation Response
+ 5. Security Considerations
+ 6. IANA Considerations
+ 6.1. JMAP Capability Registration for "sieve"
+ 6.2. JMAP Data Type Registration for "SieveScript"
+ 6.3. JMAP Error Codes Registry
+ 6.3.1. invalidSieve
+ 6.3.2. sieveIsActive
+ 7. References
+ 7.1. Normative References
+ 7.2. Informative References
+ Acknowledgments
+ Author's Address
+
+1. Introduction
+
+ The JSON Meta Application Protocol (JMAP) [RFC8620] is a generic
+ protocol for synchronizing data, such as mail, calendars, or
+ contacts, between a client and a server. It is optimized for mobile
+ and web environments, and it aims to provide a consistent interface
+ to different data types.
+
+ This specification defines a data model for managing Sieve scripts
+ [RFC5228] on a server using JMAP. The data model is designed to
+ allow a server to provide consistent access to the same scripts via
+ ManageSieve [RFC5804] as well as JMAP.
+
+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]. This
+ document also uses data types and terminology established in
+ Sections 1.2 through 1.6 of [RFC8620].
+
+ The term "SieveScript" (with this specific capitalization) is used to
+ refer to the data type defined in Section 2 and instances of this
+ data type used throughout this document. Servers MUST support all
+ properties specified for the data type defined in this document.
+
+ For brevity, JMAP API examples (see Section 3 of [RFC8620]) only show
+ the "methodCalls" property of the "Request" object and the
+ "methodResponses" property of the "Response" object. All other
+ examples are shown using the HTTP/1.1 protocol [RFC9112].
+
+1.2. Addition to the Capabilities Object
+
+ The "capabilities" object is returned as part of the JMAP Session
+ object; see [RFC8620], Section 2. This document defines one
+ additional capability URI.
+
+1.2.1. urn:ietf:params:jmap:sieve
+
+ The urn:ietf:params:jmap:sieve URI represents support for the
+ SieveScript data type and associated API methods. The value of this
+ property in the JMAP Session "capabilities" property is an object
+ that MUST contain the following information on server capabilities:
+
+ *implementation*: String
+
+ The name and version of the Sieve implementation.
+
+ The value of this property in an account's "accountCapabilities"
+ property is an object that MUST contain the following information on
+ per-account server capabilities:
+
+ *maxSizeScriptName*: UnsignedInt
+
+ The maximum length, in octets, allowed for the name of a
+ SieveScript. For compatibility with ManageSieve, this MUST be at
+ least 512 (up to 128 Unicode characters).
+
+ *maxSizeScript*: UnsignedInt|null
+
+ The maximum size (in octets) of a Sieve script the server is
+ willing to store for the user, or null for no limit.
+
+ *maxNumberScripts*: UnsignedInt|null
+
+ The maximum number of Sieve scripts the server is willing to store
+ for the user, or null for no limit.
+
+ *maxNumberRedirects*: UnsignedInt|null
+
+ The maximum number of Sieve "redirect" actions a script can
+ perform during a single evaluation, or null for no limit. Note
+ that this is different from the total number of "redirect" actions
+ a script can contain.
+
+ *sieveExtensions*: String[]
+
+ A list of case-sensitive Sieve capability strings (as listed in
+ the Sieve "require" action; see [RFC5228], Section 3.2) indicating
+ the extensions supported by the Sieve engine.
+
+ *notificationMethods*: String[]|null
+
+ A list of URI scheme parts [RFC3986] for notification methods
+ supported by the Sieve "enotify" extension [RFC5435], or null if
+ the extension is not supported by the Sieve engine.
+
+ *externalLists*: String[]|null
+
+ A list of URI scheme parts [RFC3986] for externally stored list
+ types supported by the Sieve "extlists" extension [RFC6134], or
+ null if the extension is not supported by the Sieve engine.
+
+1.2.2. Example
+
+ This example JMAP Session object shows a user that has access to
+ their own Sieve scripts with support for a few Sieve extensions:
+
+ {
+ "capabilities": {
+ "urn:ietf:params:jmap:core": {
+ ...
+ },
+ "urn:ietf:params:jmap:mail": {},
+ "urn:ietf:params:jmap:quota": {},
+ "urn:ietf:params:jmap:blob": {},
+ "urn:ietf:params:jmap:sieve": {
+ "implementation": "ACME Email Filtering"
+ },
+ "urn:ietf:params:jmap:vacationresponse": {},
+ ...
+ },
+ "accounts": {
+ "ken": {
+ "name": "ken@example.com",
+ "isPersonal": true,
+ "isReadOnly": false,
+ "accountCapabilities": {
+ "urn:ietf:params:jmap:core": {},
+ "urn:ietf:params:jmap:quota": {},
+ "urn:ietf:params:jmap:mail": {
+ ...
+ },
+ "urn:ietf:params:jmap:blob": {
+ "supportedTypeNames": [
+ "Email"
+ "SieveScript",
+ ...
+ ],
+ ...
+ },
+ "urn:ietf:params:jmap:sieve": {
+ "maxSizeScriptName": 512,
+ "maxSizeScript": 65536,
+ "maxNumberScripts": 5,
+ "maxNumberRedirects": null,
+ "sieveExtensions": [
+ "fileinto",
+ "imap4flags",
+ "enotify",
+ ...
+ ],
+ "notificationMethods": [
+ "mailto"
+ ],
+ "externalLists": null,
+ },
+ "urn:ietf:params:jmap:vacationresponse": {},
+ ...
+ },
+ ...
+ }
+ },
+ "primaryAccounts": {
+ "urn:ietf:params:jmap:mail": "ken",
+ "urn:ietf:params:jmap:sieve": "ken",
+ "urn:ietf:params:jmap:vacationresponse": "ken",
+ ...
+ },
+ "username": "ken@example.com",
+ "apiUrl": "/jmap/",
+ "downloadUrl":
+ "/jmap/download/{accountId}/{blobId}/{name}?accept={type}",
+ "uploadUrl": "/jmap/upload/{accountId}/",
+ ...
+ }
+
+2. Sieve Scripts
+
+ A "SieveScript" object represents a single Sieve script [RFC5228] for
+ filtering email messages at the time of final delivery.
+
+2.1. Sieve Script Properties
+
+ A "SieveScript" object has the following properties:
+
+ *id*: Id (immutable; server-set)
+
+ The id of the script.
+
+ *name*: String|null (optional; default is server dependent)
+
+ User-visible name for the SieveScript. If non-null, this MUST be
+ a Net-Unicode string [RFC5198] of at least 1 character in length,
+ subject to the maximum size given in the "capability" object.
+
+ For compatibility with ManageSieve, servers MUST reject names that
+ contain any of the following Unicode characters: U+0000-U+001F,
+ U+007F-U+009F, U+2028, or U+2029.
+
+ Servers MAY reject names that violate server policy (e.g., names
+ containing a slash (/)).
+
+ The name MUST be unique among all SieveScripts within an account.
+
+ *blobId*: Id
+
+ The id of the blob containing the raw octets of the script.
+
+ *isActive*: Boolean (server-set; default: false)
+
+ Indicator that the SieveScript is actively filtering incoming
+ messages.
+
+ A user may have at most one active script. The SieveScript/set
+ method (Section 2.4) is used for changing the active script or
+ disabling Sieve processing.
+
+2.2. Sieve Script Content
+
+ A script MUST be UTF-8 content [RFC3629] of at least 1 character in
+ length, subject to the syntax of Sieve [RFC5228]. A script MUST NOT
+ contain any "require" statement(s) mentioning Sieve capability
+ strings not present in the "capability" object (Section 1.2.1). Note
+ that if the Sieve "ihave" capability string [RFC5463] is present in
+ the "capability" object, the script MAY mention unrecognized/
+ unsupported extensions in the "ihave" test.
+
+ Script content is treated as a binary blob and uploaded/downloaded
+ via the mechanisms provided in Sections 6.1 and 6.2 of [RFC8620],
+ respectively, and/or via the JMAP Blob management methods provided in
+ Sections 4.1 and 4.2 of [RFC9404], respectively.
+
+ Downloading script content via the JMAP downloadUrl or the Blob/get
+ method provides functionality equivalent to that of the GETSCRIPT
+ command defined in [RFC5804].
+
+2.3. SieveScript/get
+
+ This is a standard "/get" method as described in [RFC8620],
+ Section 5.1. The "ids" argument may be null to fetch all scripts at
+ once.
+
+ This method provides functionality equivalent to that of the
+ LISTSCRIPTS command defined in [RFC5804].
+
+2.3.1. Examples
+
+ List all scripts:
+
+ [
+ ["SieveScript/get", {
+ "accountId": "ken"
+ }, "0"]
+ ]
+
+ [
+ [
+ "SieveScript/get",
+ {
+ "state": "1634915373.240633104-120",
+ "list": [
+ {
+ "id": "2d647053-dded-418d-917a-63eda3ac8f7b",
+ "name": "test1",
+ "isActive": true,
+ "blobId": "S7"
+ }
+ ],
+ "notFound": [],
+ "accountId": "ken"
+ },
+ "0"
+ ]
+ ]
+
+ Download the script content via the JMAP downloadUrl as advertised in
+ the example in Section 1.2.2:
+
+ GET /jmap/download/ken/S7/test1.siv?accept=application/sieve HTTP/1.1
+ Host: jmap.example.com
+ Authorization: Basic a2VuOnBhc3N3b3Jk
+
+ HTTP/1.1 200 OK
+ Date: Fri, 22 Oct 2021 15:27:38 GMT
+ Content-Type: application/sieve; charset=utf-8
+ Content-Disposition: attachment; filename="test1.siv"
+ Content-Length: 49
+
+ require ["fileinto"];
+ fileinto "INBOX.target";
+
+ Fetch script properties and content in a single JMAP API request
+ using the JMAP Blob management extension [RFC9404]:
+
+ [
+ ["SieveScript/get", {
+ "accountId": "ken",
+ "ids": [ "2d647053-dded-418d-917a-63eda3ac8f7b" ]
+ }, "0"],
+ ["Blob/get", {
+ "accountId": "ken",
+ "#ids": {
+ "resultOf": "0",
+ "name": "SieveScript/get",
+ "path": "/list/*/blobId"
+ }
+ }, "1"]
+ ]
+
+ [
+ [
+ "SieveScript/get",
+ {
+ "state": "1634915373.240633104-120",
+ "list": [
+ {
+ "id": "2d647053-dded-418d-917a-63eda3ac8f7b",
+ "name": "test1",
+ "isActive": true,
+ "blobId": "S7"
+ }
+ ],
+ "notFound": [],
+ "accountId": "ken"
+ },
+ "0"
+ ],
+ [
+ "Blob/get",
+ {
+ "list": [
+ {
+ "id": "S7",
+ "data:asText":
+ "require [\"fileinto\"];\\r\\nfileinto \"INBOX.target\";\\r\\n",
+ "size": 49
+ }
+ ],
+ "notFound": [],
+ "accountId": "ken"
+ },
+ "1"
+ ]
+ ]
+
+2.4. SieveScript/set
+
+ This is a standard "/set" method as described in [RFC8620],
+ Section 5.3, but with the following additional optional request
+ arguments:
+
+ *onSuccessActivateScript*: Id
+
+ The id of the SieveScript to activate if and only if all of the
+ creations, modifications, and destructions (if any) succeed. (For
+ references to SieveScript creations, this is equivalent to a
+ creation-reference, so the id will be the creation id prefixed
+ with a "#".) The currently active SieveScript (if any) will be
+ deactivated before activating the specified SieveScript.
+
+ If omitted, or if the id is either invalid or nonexistent, it MUST
+ be ignored, and the currently active SieveScript (if any) will
+ remain as such.
+
+ The id of any activated SieveScript MUST be reported in either the
+ "created" or "updated" argument in the response as appropriate,
+ including a value of "true" for the "isActive" property. The id
+ of any deactivated SieveScript MUST be reported in the "updated"
+ argument in the response, including a value of "false" for the
+ "isActive" property.
+
+ *onSuccessDeactivateScript*: Boolean
+
+ If "true", the currently active SieveScript (if any) will be
+ deactivated if and only if all of the creations, modifications,
+ and destructions (if any) succeed. If "false" or omitted, the
+ currently active SieveScript (if any) will remain as such.
+
+ The id of any deactivated SieveScript MUST be reported in the
+ "updated" argument in the response, including a value of "false"
+ for the "isActive" property.
+
+ If both the "onSuccessActivateScript" and "onSuccessDeactivateScript"
+ arguments are present in the request, then
+ "onSuccessDeactivateScript" MUST be processed first. If neither
+ argument is present in the request, the currently active SieveScript
+ (if any) will remain as such.
+
+ This method provides functionality equivalent to that of the
+ PUTSCRIPT, DELETESCRIPT, RENAMESCRIPT, and SETACTIVE commands defined
+ in [RFC5804].
+
+ Script content must first be uploaded as per Section 2.2 prior to
+ referencing it in a SieveScript/set call.
+
+ If the SieveScript cannot be created or updated because it would
+ result in two SieveScripts with the same name, the server MUST reject
+ the request with an "alreadyExists" SetError. An "existingId"
+ property of type "Id" MUST be included on the SetError object with
+ the id of the existing SieveScript.
+
+ If the SieveScript cannot be created or updated because its size
+ exceeds the "maxSizeScript" limit, the server MUST reject the request
+ with a "tooLarge" SetError.
+
+ If the SieveScript cannot be created because it would exceed the
+ "maxNumberScripts" limit or would exceed a server-imposed storage
+ limit, the server MUST reject the request with an "overQuota"
+ SetError.
+
+ The active SieveScript MUST NOT be destroyed unless it is first
+ deactivated in a separate SieveScript/set method call.
+
+ The following extra SetError types are defined:
+
+ For "create" and "update":
+
+ *invalidSieve*: The SieveScript content violates the Sieve grammar
+ [RFC5228], and/or one or more extensions mentioned in the script's
+ "require" statement(s) are not supported by the Sieve interpreter.
+ The "description" property on the SetError object SHOULD contain a
+ specific error message giving at least the line number of the
+ first error.
+
+ For "destroy":
+
+ *sieveIsActive*: The SieveScript is active.
+
+2.4.1. Examples
+
+ Upload a script requiring the Imap4Flags Extension [RFC5232] using
+ the JMAP uploadUrl as advertised in the example in Section 1.2.2:
+
+ POST /jmap/upload/ken/ HTTP/1.1
+ Host: jmap.example.com
+ Authorization: Basic a2VuOnBhc3N3b3Jk
+ Content-Type: application/sieve
+ Content-Length: 98
+
+ require "imapflags";
+
+ if address :is ["To", "Cc"] "jmap@ietf.org" {
+ setflag "\\Flagged";
+ }
+
+
+ HTTP/1.1 201 Created
+ Date: Thu, 10 Dec 2020 17:14:31 GMT
+ Content-Type: application/json; charset=utf-8
+ Content-Length: 171
+
+ {
+ "accountId": "ken",
+ "blobId": "Gabcc83e44a6e19991c4568d0b94e1767c83dd123",
+ "type": "application/sieve"
+ "size": 98
+ }
+
+ Create and activate a script using the uploaded blob. Note that the
+ response shows that an existing active script has been deactivated in
+ lieu of the newly created script being activated.
+
+ [
+ ["SieveScript/set", {
+ "accountId": "ken",
+ "create": {
+ "A": {
+ "name": null,
+ "blobId": "Gabcc83e44a6e19991c4568d0b94e1767c83dd123"
+ }
+ },
+ "onSuccessActivateScript": "#A"
+ }, "0"]
+ ]
+
+ [
+ [
+ "SieveScript/set",
+ {
+ "oldState": "1603741717.50737918-4096",
+ "newState": "1603741751.227268529-4096",
+ "created": {
+ "A": {
+ "id": "dd1b164f-8cdc-448c-9f54",
+ "name": "ken-20201210T171432-0",
+ "blobId": "Sdd1b164f-8cdc-448c-9f54",
+ "isActive": true
+ }
+ },
+ "updated": {
+ "8abd6f4a-bcb4d-87650-3fcd": {
+ "isActive": false
+ }
+ },
+ "destroyed": null,
+ "notCreated": null,
+ "notUpdated": null,
+ "notDestroyed": null,
+ "accountId": "ken"
+ },
+ "0"
+ ]
+ ]
+
+ Update the script content using the JMAP Blob management extension
+ [RFC9404]:
+
+ {
+ [
+ ["Blob/upload", {
+ "accountId": "ken",
+ "create": {
+ "B": {
+ "data": [ {
+ "data:asText":
+ "redirect \"ken@example.com\"\r\n;"
+ } ],
+ "type": "application/sieve"
+ }
+ }
+ }, "1"],
+ ["SieveScript/set", {
+ "accountId": "ken",
+ "update": { "dd1b164f-8cdc-448c-9f54": {
+ "blobId": "#B"
+ }
+ }
+ }, "2"]
+ ]
+
+ [
+ [
+ "Blob/upload",
+ {
+ "oldState": null,
+ "newState": "1603741700.309607123-0128",
+ "created": {
+ "B": {
+ "id": "G969c83e44a6e10871c4568d0b94e1767c83ddeae",
+ "blobId": "G969c83e44a6e10871c4568d0b94e1767c83ddeae",
+ "type": "application/sieve",
+ "size": 29
+ }
+ },
+ "notCreated": null,
+ "accountId": "ken"
+ },
+ "1"
+ ],
+ [
+ "SieveScript/set",
+ {
+ "oldState": "1603741751.227268529-4096",
+ "newState": "1603742603.309607868-4096",
+ "created": null,
+ "updated": {
+ "dd1b164f-8cdc-448c-9f54": null
+ },
+ "destroyed": null,
+ "notCreated": null,
+ "notUpdated": null,
+ "notDestroyed": null,
+ "accountId": "ken"
+ },
+ "2"
+ ]
+ ]
+
+ Update the script name, and deactivate it:
+
+ [
+ ["SieveScript/set", {
+ "accountId": "ken",
+ "update": { "dd1b164f-8cdc-448c-9f54": {
+ "name": "myscript"
+ }
+ },
+ "onSuccessDeactivateScript": true
+ }, "3"]
+ ]
+
+ [
+ [
+ "SieveScript/set",
+ {
+ "oldState": "1603742603.309607868-4096",
+ "newState": "1603742967.852315428-4096",
+ "created": null,
+ "updated": {
+ "dd1b164f-8cdc-448c-9f54": {
+ "isActive": false
+ }
+ },
+ "destroyed": null,
+ "notCreated": null,
+ "notUpdated": null,
+ "notDestroyed": null,
+ "accountId": "ken"
+ },
+ "3"
+ ]
+ ]
+
+ Reactivate the script:
+
+ [
+ ["SieveScript/set", {
+ "accountId": "ken",
+ "onSuccessActivateScript": "dd1b164f-8cdc-448c-9f54"
+ }, "4"]
+ ]
+
+ [
+ [
+ "SieveScript/set",
+ {
+ "oldState": "1603742967.852315428-4096",
+ "newState": "1603744460.316617118-4096",
+ "created": null,
+ "updated": {
+ "dd1b164f-8cdc-448c-9f54": {
+ "isActive": true
+ }
+ },
+ "destroyed": null,
+ "notCreated": null,
+ "notUpdated": null,
+ "notDestroyed": null,
+ "accountId": "ken"
+ },
+ "4"
+ ]
+ ]
+
+ Deactivate and destroy the active script:
+
+ [
+ ["SieveScript/set", {
+ "accountId": "ken",
+ "onSuccessDeactivateScript": true
+ }, "5"],
+ ["SieveScript/set", {
+ "accountId": "ken",
+ "destroy": [ "dd1b164f-8cdc-448c-9f54" ]
+ }, "6"]
+ ]
+
+ [
+ [
+ "SieveScript/set",
+ {
+ "oldState": "1603744460.316617118-4096",
+ "newState": "1603744637.575375572-4096",
+ "created": null,
+ "updated": {
+ "dd1b164f-8cdc-448c-9f54": {
+ "isActive": false
+ }
+ },
+ "destroyed": null,
+ "notCreated": null,
+ "notUpdated": null,
+ "notDestroyed": null,
+ "accountId": "ken"
+ },
+ "5"
+ ],
+ [
+ "SieveScript/set",
+ {
+ "oldState": "1603744637.575375572-4096",
+ "newState": "1603744637.854390875-4096",
+ "created": null,
+ "updated": null,
+ "destroyed": [
+ "dd1b164f-8cdc-448c-9f54"
+ ],
+ "notCreated": null,
+ "notUpdated": null,
+ "notDestroyed": null,
+ "accountId": "ken"
+ },
+ "6"
+ ]
+ ]
+
+2.5. SieveScript/query
+
+ This is a standard "/query" method as described in [RFC8620],
+ Section 5.5. A "FilterCondition" object has the following
+ properties, either of which may be omitted:
+
+ *name*: String
+
+ The SieveScript "name" property contains the given string.
+
+ *isActive*: Boolean
+
+ The "isActive" property of the SieveScript must be identical to
+ the value given to match the condition.
+
+ The following SieveScript properties MUST be supported for sorting:
+
+ * *name*
+
+ * *isActive*
+
+2.6. SieveScript/validate
+
+ This method is used by the client to verify Sieve script validity
+ without storing the script on the server.
+
+ The method takes the following arguments:
+
+ *accountId*: Id
+
+ The id of the account to use.
+
+ *blobId*: Id
+
+ The id of the blob containing the raw octets of the script to
+ validate, subject to the same requirements in Section 2.2.
+
+ The response has the following arguments:
+
+ *accountId*: Id
+
+ The id of the account used for this call.
+
+ *error*: SetError|null
+
+ An "invalidSieve" SetError object if the script content is invalid
+ (see Section 2.4), or null if the script content is valid.
+
+ This method provides functionality equivalent to that of the
+ CHECKSCRIPT command defined in [RFC5804].
+
+ Script content must first be uploaded as per Section 2.2 prior to
+ referencing it in a SieveScript/validate call.
+
+3. Quotas
+
+ Servers SHOULD impose quotas on Sieve scripts to prevent malicious
+ users from exceeding available storage. Administration of such
+ quotas is outside of the scope of this specification; however,
+ [RFC9425] defines a data model for users to obtain quota details over
+ JMAP.
+
+ The mechanism for handling SieveScript requests that would place a
+ user over a quota setting is discussed in Section 2.4.
+
+4. Compatibility with JMAP Vacation Response
+
+ Section 8 of [RFC8621] defines a "VacationResponse" object to
+ represent an autoresponder to incoming email messages. Servers that
+ implement the VacationResponse as a Sieve script that resides among
+ other user scripts are subject to the following requirements:
+
+ * MUST allow the VacationResponse Sieve script to be fetched by the
+ SieveScript/get method (Section 2.3).
+
+ * MUST allow the VacationResponse Sieve script to be activated or
+ deactivated via the "onSuccessActivateScript" argument to the
+ SieveScript/set method (Section 2.4).
+
+ * MUST NOT allow the VacationResponse Sieve script to be destroyed
+ or have its content updated by the SieveScript/set method
+ (Section 2.4). Any such request MUST be rejected with a
+ "forbidden" SetError. A "description" property MAY be present
+ with an explanation that the script can only be modified by a
+ VacationResponse/set method.
+
+5. Security Considerations
+
+ All security considerations discussed in JMAP [RFC8620] and Sieve
+ [RFC5228] apply to this specification.
+
+ Additionally, implementations MUST treat Sieve script content as
+ untrusted data. As such, script parsers MUST fail gracefully in the
+ face of syntactically invalid or malicious content and MUST be
+ prepared to deal with resource exhaustion (e.g., allocation of
+ enormous strings, lists, or command blocks).
+
+6. IANA Considerations
+
+6.1. JMAP Capability Registration for "sieve"
+
+ IANA has registered "sieve" in the "JMAP Capabilities" registry as
+ follows:
+
+ Capability Name: urn:ietf:params:jmap:sieve
+
+ Reference: RFC 9661
+
+ Intended Use: common
+
+ Change Controller: IETF
+
+ Security and Privacy Considerations: RFC 9661, Section 5
+
+6.2. JMAP Data Type Registration for "SieveScript"
+
+ IANA has registered "SieveScript" in the "JMAP Data Types" registry
+ as follows:
+
+ Type Name: SieveScript
+
+ Can Reference Blobs: Yes
+
+ Can Use for State Change: Yes
+
+ Capability: urn:ietf:params:jmap:sieve
+
+ Reference: RFC 9661
+
+6.3. JMAP Error Codes Registry
+
+ IANA has registered the following two new error codes in the "JMAP
+ Error Codes" registry, as defined in [RFC8620].
+
+6.3.1. invalidSieve
+
+ JMAP Error Code: invalidSieve
+
+ Intended Use: common
+
+ Change Controller: IETF
+
+ Reference: RFC 9661, Section 2.4
+
+ Description: The SieveScript violates the Sieve grammar [RFC5228],
+ and/or one or more extensions mentioned in the script's "require"
+ statement(s) are not supported by the Sieve interpreter.
+
+6.3.2. sieveIsActive
+
+ JMAP Error Code: sieveIsActive
+
+ Intended Use: common
+
+ Change Controller: IETF
+
+ Reference: RFC 9661, Section 2.4
+
+ Description: The client tried to destroy the active SieveScript.
+
+7. References
+
+7.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>.
+
+ [RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO
+ 10646", STD 63, RFC 3629, DOI 10.17487/RFC3629, November
+ 2003, <https://www.rfc-editor.org/info/rfc3629>.
+
+ [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
+ Resource Identifier (URI): Generic Syntax", STD 66,
+ RFC 3986, DOI 10.17487/RFC3986, January 2005,
+ <https://www.rfc-editor.org/info/rfc3986>.
+
+ [RFC5198] Klensin, J. and M. Padlipsky, "Unicode Format for Network
+ Interchange", RFC 5198, DOI 10.17487/RFC5198, March 2008,
+ <https://www.rfc-editor.org/info/rfc5198>.
+
+ [RFC5228] Guenther, P., Ed. and T. Showalter, Ed., "Sieve: An Email
+ Filtering Language", RFC 5228, DOI 10.17487/RFC5228,
+ January 2008, <https://www.rfc-editor.org/info/rfc5228>.
+
+ [RFC5435] Melnikov, A., Ed., Leiba, B., Ed., Segmuller, W., and T.
+ Martin, "Sieve Email Filtering: Extension for
+ Notifications", RFC 5435, DOI 10.17487/RFC5435, January
+ 2009, <https://www.rfc-editor.org/info/rfc5435>.
+
+ [RFC6134] Melnikov, A. and B. Leiba, "Sieve Extension: Externally
+ Stored Lists", RFC 6134, DOI 10.17487/RFC6134, July 2011,
+ <https://www.rfc-editor.org/info/rfc6134>.
+
+ [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>.
+
+ [RFC8621] Jenkins, N. and C. Newman, "The JSON Meta Application
+ Protocol (JMAP) for Mail", RFC 8621, DOI 10.17487/RFC8621,
+ August 2019, <https://www.rfc-editor.org/info/rfc8621>.
+
+7.2. Informative References
+
+ [RFC5232] Melnikov, A., "Sieve Email Filtering: Imap4flags
+ Extension", RFC 5232, DOI 10.17487/RFC5232, January 2008,
+ <https://www.rfc-editor.org/info/rfc5232>.
+
+ [RFC5463] Freed, N., "Sieve Email Filtering: Ihave Extension",
+ RFC 5463, DOI 10.17487/RFC5463, March 2009,
+ <https://www.rfc-editor.org/info/rfc5463>.
+
+ [RFC5804] Melnikov, A., Ed. and T. Martin, "A Protocol for Remotely
+ Managing Sieve Scripts", RFC 5804, DOI 10.17487/RFC5804,
+ July 2010, <https://www.rfc-editor.org/info/rfc5804>.
+
+ [RFC9112] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke,
+ Ed., "HTTP/1.1", STD 99, RFC 9112, DOI 10.17487/RFC9112,
+ June 2022, <https://www.rfc-editor.org/info/rfc9112>.
+
+ [RFC9404] Gondwana, B., Ed., "JSON Meta Application Protocol (JMAP)
+ Blob Management Extension", RFC 9404,
+ DOI 10.17487/RFC9404, August 2023,
+ <https://www.rfc-editor.org/info/rfc9404>.
+
+ [RFC9425] Cordier, R., Ed., "JSON Meta Application Protocol (JMAP)
+ for Quotas", RFC 9425, DOI 10.17487/RFC9425, June 2023,
+ <https://www.rfc-editor.org/info/rfc9425>.
+
+Acknowledgments
+
+ The concepts in this document are based largely on those in
+ [RFC5804]. The author would like to thank the authors of that
+ document for providing both inspiration and some borrowed text for
+ this document.
+
+ The author would also like to thank the following individuals for
+ contributing their ideas and support for writing this specification:
+ Joris Baum, Mauro De Gennaro, Bron Gondwana, Neil Jenkins, Alexey
+ Melnikov, and Ricardo Signes.
+
+Author's Address
+
+ Kenneth Murchison
+ Fastmail US LLC
+ 1429 Walnut Street, Suite 1201
+ Philadelphia, PA 19102
+ United States of America
+ Email: murch@fastmailteam.com