RFC 9661
The JSON Meta Application Protocol (JMAP) for Sieve Scripts
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 Notice Β©οΈ
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 SieveScriptnameproperty contains the given string.isActive: Boolean TheisActiveproperty of the SieveScript must be identical to the value given to match the condition.
For sorting, the following SieveScript properties MUST be supported:
nameisActive
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 AninvalidSieveSetError 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
onSuccessActivateScriptargument 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
forbiddenSetError. Adescriptionproperty 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
[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. 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
- ietf: rfc9661 2024-09
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms