The JSON Meta Application Protocol (JMAP) for Sieve Scripts
Extracted elements (23)
Script content is treated as a binary blob and uploaded/downloaded via JMAP blob mechanisms (RFC 8620 Sections 6.1/6.2 or RFC 9404 Blob/get and Blob/upload). This decouples content transfer from metadata management and aligns with JMAP's general blob handling model.
Script content must be uploaded before being referenced in SieveScript/set or SieveScript/validate calls. This two-phase upload-then-reference pattern follows the JMAP blob model and avoids embedding large binary content inside JSON API calls.
Servers implementing VacationResponse (RFC 8621 Section 8) as a Sieve script MUST allow it to be fetched and activated/deactivated via SieveScript/get and /set, but MUST NOT allow it to be destroyed or have its content updated — such requests MUST be rejected with a 'forbidden' SetError.
The data model is designed so that a server can provide consistent access to the same Sieve scripts via both ManageSieve (RFC 5804) and JMAP. SieveScript/get, /set, and /validate provide functionality equivalent to LISTSCRIPTS/PUTSCRIPT/DELETESCRIPT/RENAMESCRIPT/SETACTIVE/CHECKSCRIPT respectively.
If SieveScript/set would result in duplicate names, the server MUST reject with an 'alreadyExists' SetError including an 'existingId' property. Exceeding maxSizeScript MUST return 'tooLarge'; exceeding maxNumberScripts or storage MUST return 'overQuota'.
Script content MUST be UTF-8 of at least 1 character and conform to Sieve syntax. A script MUST NOT contain 'require' statements mentioning Sieve capability strings absent from the server's capability object.
Servers MUST support all properties specified for the SieveScript data type. The 'maxSizeScriptName' capability MUST be at least 512 octets for ManageSieve compatibility.
Servers SHOULD impose quotas on Sieve scripts to prevent malicious users from exceeding available storage. RFC 9425 defines a JMAP data model for quota details.
SieveScript names MUST be Net-Unicode strings of at least 1 character. Servers MUST reject names containing Unicode characters U+0000-U+001F, U+007F-U+009F, U+2028, or U+2029. Names MUST be unique within an account.
The active SieveScript MUST NOT be destroyed unless it is first deactivated in a separate SieveScript/set call. Attempting to destroy an active script MUST return a 'sieveIsActive' SetError.
The id of any activated SieveScript MUST be reported in 'created' or 'updated' with isActive=true; the id of any deactivated SieveScript MUST be reported in 'updated' with isActive=false.
SieveScript/get is a standard JMAP /get method. The 'ids' argument may be null to fetch all scripts. It provides functionality equivalent to ManageSieve's LISTSCRIPTS command.
SieveScript/query is a standard JMAP /query method supporting FilterCondition properties 'name' (substring match) and 'isActive' (Boolean equality). Sorting MUST be supported on 'name' and 'isActive'.
SieveScript/set extends the standard JMAP /set method with two optional arguments: 'onSuccessActivateScript' (Id of script to activate after all mutations succeed) and 'onSuccessDeactivateScript' (Boolean to deactivate the currently active script). When both are present, deactivation is processed first.
SieveScript/validate allows clients to verify Sieve script validity without storing it. It takes 'accountId' and 'blobId' arguments, and returns 'accountId' and 'error' (an 'invalidSieve' SetError or null). It is equivalent to ManageSieve's CHECKSCRIPT command.
The 'invalidSieve' SetError is returned for create/update when the Sieve script content violates Sieve grammar or references unsupported extensions. The 'description' property SHOULD contain a specific error message with at least the line number of the first error.
The SieveScript object has four properties: 'id' (immutable, server-set Id), 'name' (optional String|null, Net-Unicode, unique per account), 'blobId' (Id referencing the raw script octets), and 'isActive' (Boolean, server-set, default false). At most one script may be active per user.
The urn:ietf:params:jmap:sieve capability object at the session level MUST include 'implementation' (String). At the account level it MUST include 'maxSizeScriptName', 'maxSizeScript', 'maxNumberScripts', 'maxNumberRedirects', 'sieveExtensions', 'notificationMethods', and 'externalLists'.
IANA registered 'SieveScript' in the JMAP Data Types registry: can reference blobs (yes), can use for state change (yes), capability 'urn:ietf:params:jmap:sieve'.
IANA registered two new error codes in the JMAP Error Codes registry: 'invalidSieve' (script violates Sieve grammar or uses unsupported extensions) and 'sieveIsActive' (client attempted to destroy the active script).
IANA registered 'urn:ietf:params:jmap:sieve' in the JMAP Capabilities registry with intended use 'common', change controller IETF, referencing RFC 9661.
All security considerations from JMAP (RFC 8620) and Sieve (RFC 5228) apply to this specification, covering authentication, authorization, transport security, and script execution risks.
Implementations MUST treat Sieve script content as untrusted data. Script parsers MUST fail gracefully on syntactically invalid or malicious content and MUST be prepared to handle resource exhaustion (e.g., allocation of enormous strings, lists, or command blocks).