RFC 9661

The JSON Meta Application Protocol (JMAP) for Sieve Scripts

πŸ“… published September 2024, from ietf

RFC 9661: The JSON Meta Application Protocol (JMAP) for Sieve Scripts πŸ’Œ

okay bestie, let's get into it πŸ¦‹ this one is about managing Sieve scripts on a server using JMAP, so clients can search, access, organize, and validate them. it's giving organized inbox energy πŸ’…

  • Number and title: RFC 9661, The JSON Meta Application Protocol (JMAP) for Sieve Scripts
  • Author: K. Murchison from Fastmail 🌸
  • Stream: Internet Engineering Task Force (IETF)
  • Category: Standards Track ✨
  • Date: September 2024
  • ISSN: 2070-1721
  • Obsoletes and updates: the header doesn't list anything this RFC obsoletes or updates, so it's standing on its own πŸ‘‘

Here's the table of contents, copied exactly so you can find your way around 🧚

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

Abstract ✨

this doc gives you a data model for managing Sieve scripts on a server with JMAP. clients can use it to efficiently search, access, organize, and validate those scripts. so cute, right? πŸŽ€

Status of This Memo πŸ“‹

this is an Internet Standards Track document πŸ”₯

it's a product of the Internet Engineering Task Force (IETF), and it represents the consensus of the IETF community. it got public review and was approved for publication by the Internet Engineering Steering Group (IESG). if you want more on Internet Standards, check out Section 2 of RFC 7841 🧚

for the current status, any errata, and how to give feedback, go to https://www.rfc-editor.org/info/rfc9661 πŸ’œ

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

this doc is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents, which you can read at https://trustee.ietf.org/license-info as they stood on the publication date. please actually read them, because they explain your rights and restrictions for this doc πŸ™ˆ

if you pull Code Components out of this document, they must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions. they come without warranty, as described in the Revised BSD License ⭐


1. Introduction 🌈

JMAP [RFC8620] is a generic protocol for syncing data like mail, calendars, or contacts between a client and a server. it's built for mobile and web, and it wants to give you one consistent interface across different data types. main character energy πŸ‘‘

this spec defines a data model for managing Sieve scripts [RFC5228] on a server using JMAP. the goal is that a server can give consistent access to the same scripts through ManageSieve [RFC5804] and JMAP. two doors, same room πŸšͺ✨

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 follow the conventions in Section 1.1 of [RFC8620]. this doc also uses the data types and terminology from Sections 1.2 through 1.6 of [RFC8620] πŸ¦‹

the term "SieveScript" (with this exact capitalization) refers to the data type defined in Section 2, plus instances of that type used throughout the doc. Servers MUST support all properties specified for the data type defined in this document. no skipping, bestie πŸ’…

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. every other example uses the HTTP/1.1 protocol [RFC9112] πŸ“

1.2. Addition to the Capabilities Object πŸŽ€

the "capabilities" object comes back as part of the JMAP Session object. see [RFC8620], Section 2 for the deets. this document defines one additional capability URI 🧚

1.2.1. urn:ietf:params:jmap:sieve πŸ’–

the urn:ietf:params:jmap:sieve URI means the server supports the SieveScript data type and its API methods. in the JMAP Session "capabilities" property, the value is an object that MUST contain the following server capability info:

  • implementation: String. the name and version of the Sieve implementation.

in an account's "accountCapabilities" property, the value is an object that MUST contain the following per-account server capability info:

  • maxSizeScriptName: UnsignedInt. the maximum length, in octets, allowed for the name of a SieveScript. for ManageSieve compatibility, 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. easy to mix up, so watch out πŸ‘€
  • sieveExtensions: String[]. a list of case-sensitive Sieve capability strings (as listed in the Sieve "require" action; see [RFC5228], Section 3.2) for the extensions the Sieve engine supports.
  • notificationMethods: String[]|null. a list of URI scheme parts [RFC3986] for notification methods supported by the Sieve "enotify" extension [RFC5435], or null if the Sieve engine doesn't support that extension.
  • 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 Sieve engine doesn't support that extension.

1.2.2. Example 🌸

this example JMAP Session object shows a user who can access 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 is a single Sieve script [RFC5228] that filters email messages at the time of final delivery. it's the little filter that decides your mail's whole destiny πŸ’…

2.1. Sieve Script Properties πŸŽ€

a "SieveScript" object has these properties:

  • id: Id (immutable; server-set). the id of the script.
  • name: String|null (optional; default is server dependent). the user-visible name for the SieveScript. if it's non-null, it MUST be a Net-Unicode string [RFC5198] at least 1 character long, and it's subject to the maximum size given in the "capability" object. for ManageSieve compatibility, servers MUST reject names containing any of these Unicode characters: U+0000-U+001F, U+007F-U+009F, U+2028, or U+2029. servers MAY reject names that break server policy (e.g., names containing a slash (/)). the name MUST be unique among all SieveScripts in an account. πŸ™…β€β™€οΈ
  • blobId: Id. the id of the blob holding the raw octets of the script.
  • isActive: Boolean (server-set; default: false). the 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 how you change the active script or turn off Sieve processing πŸ”₯

2.2. Sieve Script Content πŸ’œ

a script MUST be UTF-8 content [RFC3629] at least 1 character long, and it has to follow the syntax of Sieve [RFC5228]. a script MUST NOT contain any "require" statement(s) that mention Sieve capability strings missing from the "capability" object (Section 1.2.1). πŸ™ˆ

note that if the Sieve "ihave" capability string [RFC5463] is in the "capability" object, the script MAY mention unrecognized or unsupported extensions in the "ihave" test. that's a whole vibe πŸ¦‹

script content is treated as a binary blob, and you upload and download it through the mechanisms in Sections 6.1 and 6.2 of [RFC8620], respectively. you can also use the JMAP Blob management methods in Sections 4.1 and 4.2 of [RFC9404], respectively πŸ“¦

downloading script content through the JMAP downloadUrl or the Blob/get method gives you functionality equivalent to the GETSCRIPT command in [RFC5804]. iconic πŸ’–

2.3. SieveScript/get 🌈

this is a standard "/get" method, as described in [RFC8620], Section 5.1. the "ids" argument may be null, which fetches all scripts at once 🫢

this method gives you functionality equivalent to the LISTSCRIPTS command in [RFC5804]. so the same job, just with JMAP energy ✨


okay that's part 1 wrapped up πŸŽ€ part 2 is coming next, bestie 🧚

2.3.1. Examples 🧚

okay bestie, time for the fun part! list all the scripts for ken πŸ’–

[
  ["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"
  ]
]

now download the script content through the JMAP downloadUrl we saw advertised in the example in Section 1.2.2. the way this just works is 🫢

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";

and if you want the script properties AND the content in one single JMAP API request, you can use the JMAP Blob management extension [RFC9404]. iconic multitasking πŸ‘‘

[
  ["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, just like the one described in [RFC8620], Section 5.3, but it comes with some extra optional request arguments. ✨ the rules here are super important, so read them closely, bestie πŸ™ˆ

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) gets deactivated before the specified SieveScript gets activated.

if it's omitted, or if the id is either invalid or nonexistent, it MUST be ignored, and the currently active SieveScript (if any) will stay exactly as it is.

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) gets 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) stays as it is.

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) stays as it is.

this method gives you the same functionality as the PUTSCRIPT, DELETESCRIPT, RENAMESCRIPT, and SETACTIVE commands defined in [RFC5804]. so much overlap, I'm obsessed

script content must first be uploaded as per Section 2.2 before you reference it in a SieveScript/set call. no skipping this step, bestie!

if the SieveScript can't 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 can't be created or updated because its size exceeds the "maxSizeScript" limit, the server MUST reject the request with a "tooLarge" SetError.

if the SieveScript can't 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. 🚫 no cap, don't even try it

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 that requires the Imap4Flags Extension [RFC5232] using the JMAP uploadUrl we saw advertised in the example in Section 1.2.2. this one's giving main character energy πŸ¦‹

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
}

now create and activate a script using that uploaded blob. heads up: the response shows that an existing active script gets deactivated so the newly created one can take over 🌸

[
  ["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"
  ]
]

rename the script and deactivate it in the same go πŸ“

[
  ["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"
  ]
]

last but not least, deactivate and destroy the active script πŸ’€ bye bye 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 ✨

bestie, this one is just the standard "/query" method from [RFC8620], Section 5.5, so you already know the vibe πŸ’… A FilterCondition object has two properties, and you can leave either one out:

  • 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.

For sorting, the following SieveScript properties MUST be supported:

  • name
  • isActive

2.6. SieveScript/validate 🧐

This method lets the client check whether a Sieve script is valid without saving it on the server. Very useful for a "is this even going to work?" moment πŸ™ˆ

The method takes these 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 these 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 gives you the same functionality as the CHECKSCRIPT command defined in [RFC5804]. Iconic 🌸

Script content has to be uploaded as per Section 2.2 before you reference it in a SieveScript/validate call, so upload first, then validate. Order matters, bestie πŸ’–

3. Quotas πŸ’Έ

Servers SHOULD put quotas on Sieve scripts so that malicious users can't blow past the available storage πŸ™…β€β™€οΈ How quotas are administered is outside the scope of this specification, but [RFC9425] defines a data model that lets users check their quota details over JMAP. Very organized of them πŸ“Š

The way SieveScript requests get handled when they would push a user over a quota setting is covered in Section 2.4. Go read that if you're curious!

4. Compatibility with JMAP Vacation Response πŸ–οΈ

Section 8 of [RFC8621] defines a VacationResponse object, which is basically an autoresponder for incoming email messages. πŸ›ŽοΈ If a server implements the VacationResponse as a Sieve script that sits alongside the user's other scripts, then these requirements apply:

  • The server MUST allow the VacationResponse Sieve script to be fetched by the SieveScript/get method (Section 2.3).
  • The server MUST allow the VacationResponse Sieve script to be activated or deactivated through the onSuccessActivateScript argument to the SieveScript/set method (Section 2.4).
  • The server 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, explaining that the script can only be modified by a VacationResponse/set method. 🚫

5. Security Considerations πŸ”

Okay, this part is serious, so listen up πŸ‘‘ All security considerations discussed in JMAP [RFC8620] and Sieve [RFC5228] apply to this specification too. No skipping them!!

On top of that, implementations MUST treat Sieve script content as untrusted data. 🚨 So script parsers MUST fail gracefully when they hit syntactically invalid or malicious content, and they MUST be ready to handle resource exhaustion (for example, allocation of enormous strings, lists, or command blocks). Bestie, parsers have to be built like they're being attacked every single day, because they might be 😭

6. IANA Considerations πŸ“‹

6.1. JMAP Capability Registration for "sieve" πŸŽ€

IANA has registered "sieve" in the "JMAP Capabilities" registry like this:

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 like this:

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

7.2. Informative References

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. Absolute legends πŸ‘‘

Author's Address πŸ–ŠοΈ

Kenneth Murchison
Fastmail US LLC
1429 Walnut Street, Suite 1201
Philadelphia, PA 19102
United States of America
Email: murch@fastmailteam.com
πŸ“¦ where this page comes from