RFC 5257

Internet Message Access Protocol - ANNOTATE Extension

๐Ÿ“… published June 2008, from ietf

RFC 5257: Internet Message Access Protocol - ANNOTATE Extension ๐Ÿ’–

  • Number: RFC 5257
  • Working group: Network Working Group
  • Authors: C. Daboo (Apple Inc.) and R. Gellens (QUALCOMM Incorporated) ๐Ÿ‘ฏ
  • Category: Experimental ๐Ÿงช
  • Date: June 2008 ๐Ÿ“…
  • Obsoletes / Updates: nothing listed in the title block, so this doc doesn't obsolete or update anything ๐Ÿ™…โ€โ™€๏ธ

Status of This Memo โœจ

okay so this memo defines an Experimental Protocol for the Internet community ๐Ÿงช. it does not specify an Internet standard of any kind. they're literally asking for feedback and suggestions for improvement ๐Ÿซถ. distribution of this memo is unlimited, so share the tea ๐Ÿ“.

Abstract ๐ŸŽ€

the ANNOTATE extension to the Internet Message Access Protocol lets clients and servers keep "meta data" for messages, or for individual message parts, stored in a mailbox on the server ๐Ÿ“ฌ. think of it as sticky notes for your emails ๐Ÿ’…. you can attach comments and other useful info to a message, or hang annotations on specific parts of it, so a part can be marked as seen or important, or get a comment added ๐ŸŒธ.

the vibes here are very "we agreed, but we're not sure yet." the working group had good consensus on how to approach the problem ๐Ÿค. still, they didn't have enough info on implementation and deployment hurdles to meet all of the requirements of a Proposed Standard ๐Ÿ˜ญ. so the IETF is asking for implementations and implementation reports to keep the glow-up going โœจ.

heads up, bestie: implementers should be aware that this specification may change in an incompatible manner when it goes to Proposed Standard status ๐Ÿ’€. but any incompatible changes will get a brand new capability name, so existing experimental deployments won't get wrecked ๐Ÿ›ก๏ธ.

Table of Contents ๐Ÿ—บ๏ธ

   1. Introduction and Overview .......................................3
   2. Conventions Used in This Document ...............................4
   3. Data Model ......................................................4
      3.1. Overview ...................................................4
      3.2. Namespace of Entries and Attributes ........................4
           3.2.1. Entry Names .........................................5
           3.2.2. Attribute Names .....................................7
      3.3. Private Versus Shared ......................................7
      3.4. Access Control .............................................8
      3.5. Access to Standard IMAP Flags and Keywords ................11
   4. IMAP Protocol Changes ..........................................11
      4.1. General Considerations ....................................11
      4.2. ANNOTATE Parameter with the SELECT/EXAMINE Commands .......12
      4.3. ANNOTATION Message Data Item in FETCH Command .............12
      4.4. ANNOTATION Message Data Item in FETCH Response ............14
      4.5. ANNOTATION Message Data Item in STORE .....................16
      4.6. ANNOTATION Interaction with COPY ..........................18
      4.7. ANNOTATION Message Data Item in APPEND ....................18
      4.8. ANNOTATION Criterion in SEARCH ............................19
      4.9. ANNOTATION Key in SORT ....................................20
      4.10. New ACL Rights ...........................................21
   5. Formal Syntax ..................................................21
   6. IANA Considerations ............................................23
      6.1. Entry and Attribute Registration Template .................23
      6.2. Entry Registrations .......................................24
           6.2.1. /comment ...........................................24
           6.2.2. /flags .............................................24
           6.2.3. /altsubject ........................................25
           6.2.4. /<section-part>/comment ............................25
           6.2.5. /<section-part>/flags/seen .........................26
           6.2.6. /<section-part>/flags/answered .....................26
           6.2.7. /<section-part>/flags/flagged ......................27
           6.2.8. /<section-part>/flags/forwarded ....................27
      6.3. Attribute Registrations ...................................28
           6.3.1. value ..............................................28
           6.3.2. size ...............................................28
      6.4. Capability Registration ...................................28
   7. Internationalization Considerations ............................29
   8. Security Considerations ........................................29
   9. References .....................................................29
      9.1. Normative References ......................................29
      9.2. Informative References ....................................30
   10. Acknowledgments ...............................................30

1. Introduction and Overview ๐Ÿฆ‹

the ANNOTATE extension shows up in any IMAP [RFC3501] implementation that returns ANNOTATE-EXPERIMENT-1 as one of the supported capabilities in the CAPABILITY response ๐Ÿ‘€. if you see that string, the extension is there ๐Ÿงš.

this extension makes the following changes to the IMAP protocol:

  • a. adds a new ANNOTATION message data item for use in FETCH ๐Ÿ”.
  • b. adds a new ANNOTATION message data item for use in STORE โœ๏ธ.
  • c. adds a new ANNOTATION search criterion for use in SEARCH ๐Ÿ”Ž.
  • d. adds a new ANNOTATION sort key for use in the SORT extension ๐Ÿ“Š.
  • e. adds a new ANNOTATION data item for use in APPEND โž•.
  • f. adds a new requirement on the COPY command ๐Ÿ“‹.
  • g. adds a new ANNOTATE parameter for use with the SELECT/EXAMINE commands ๐Ÿšช.
  • h. adds two new response codes to indicate store failures of annotations ๐Ÿ™ˆ.
  • i. adds a new untagged response code for the SELECT or EXAMINE commands to indicate the maximum sized annotation that can be stored ๐Ÿ“.
  • j. adds a new Access Control List (ACL) "bit" for use with the ACL extensions [RFC2086] and [RFC4314] ๐Ÿ”.

the data model for storing annotations is based on the Application Configuration Access Protocol [RFC2244] ๐Ÿงฉ. also, lowkey important: there is no inheritance in annotations ๐Ÿšซ.

If a server supports annotations, then it MUST store all annotation data permanently, i.e., there is no concept of "session only" annotations that would correspond to the behavior of "session" flags as defined in the IMAP base specification. no session-only annotations, periodt ๐Ÿ’….

okay, so for a disconnected client (one that needs to sync annotations for when it's offline) ๐Ÿ“ด, servers SHOULD also support the Conditional STORE [RFC4551] extension ๐Ÿซถ.

the rest of this document breaks down the data model and protocol changes more rigorously ๐Ÿค“. buckle up, it's about to get detailed ๐ŸŽข.

2. Conventions Used in This Document ๐Ÿ“š

the examples in this document use C: and S: to show lines sent by the client and server, respectively ๐Ÿ’ฌ.

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119] ๐Ÿ—๏ธ. these are the official capital-letter power words, so read them carefully โœจ.

3. Data Model ๐Ÿ—ƒ๏ธ

3.1. Overview ๐ŸŒˆ

the data model for annotations in ANNOTATE uses a uniquely named entry that holds a set of standard attributes ๐Ÿง. so one coherent unit of "meta data" for a message gets stored as a single entry, made up of several attributes ๐Ÿ’œ.

for example, a comment annotation on a message has the entry name /comment ๐Ÿ’ฌ. that entry is made up of several attributes, like value, size, and so on, which hold the properties and data of the entry ๐Ÿ“ฆ.

the IMAP protocol changes described below let a client access or change the values of any attribute in any entry in a message annotation, as long as it has enough access rights to do so (see Section 3.4 for the specifics) ๐Ÿ”‘. no rights, no edits, bestie ๐Ÿ™…โ€โ™€๏ธ.

3.2. Namespace of Entries and Attributes ๐Ÿท๏ธ

a message can have zero or more annotations, and each one is a single, uniquely named entry ๐Ÿ“. every entry has a hierarchical name, with each component separated by a slash (/) ๐Ÿชœ.

An entry name MUST NOT contain two consecutive / characters and MUST NOT end with a / character. no double slashes, no trailing slash, we are not doing that ๐Ÿ™ˆ.

each entry is made up of a set of attributes ๐Ÿงธ. every attribute also has a hierarchical name, but this time the components are separated by a period (.) ๐Ÿ”ธ.

An attribute name MUST NOT contain two consecutive . characters and MUST NOT end with a . character. same energy as the slashes: no double dots, no trailing dot ๐Ÿ’….

the value of an attribute is either NIL (meaning it has no value) or a string of zero or more octets ๐Ÿซง.

Entry and attribute names MUST NOT contain asterisk (*) or percent (%) characters, and MUST NOT contain non-ASCII characters or the NULL octet ๐Ÿšซ. if an entry or attribute name breaks these rules, any IMAP command that uses it gets a BAD response ๐Ÿ’€.

Attribute names MUST NOT contain any hierarchical components named "priv" or "shared", because those have special meaning (see Section 3.3) ๐Ÿ‘‘. so those two are reserved VIP names, hands off ๐ŸŽ€.

Entry and attribute names are case-sensitive ๐Ÿ” . /Comment and /comment are NOT the same girl ๐Ÿ’โ€โ™€๏ธ.

Use of control or punctuation characters in entry and attribute names is strongly discouraged ๐Ÿ™ƒ. keep it clean, no drama in the names ๐Ÿงผ.

this specification defines an initial set of entry and attribute names that you can use in message annotations โœจ. there's also an extension mechanism for adding more names whenever they're needed ๐ŸŒŸ. we're just getting started, so stay tuned ๐Ÿงšโ€โ™€๏ธ.

3.2.1. Entry Names โœจ

okay so entry names MUST be specified in a standards track or IESG approved experimental RFC, or they fall under the vendor namespace ๐Ÿ’… see Section 6.1 for the registration template ๐Ÿ“

  • / ๐ŸŒธ is the top level of entries for an entire message. This entry doesn't hold any attributes itself. Entries that start with a number (0 through 9) are annotations on a specific body part, and everything else is an annotation on the whole message.
  • /comment ๐Ÿ’ฌ is a comment or note on the entire message.
  • /flags ๐Ÿšฉ is a hierarchy that's reserved for future use, so hands off for now ๐Ÿ™ˆ
  • /altsubject ๐ŸŽ€ holds text the recipient supplies that the client should show instead of the original message Subject.
  • /vendor/<vendor-token> ๐Ÿท๏ธ is the top level of entries for an entire message as created by one particular product from some vendor. Vendors use these sub-entries for their own client-specific annotations. The vendor-token MUST be registered with IANA, using the [RFC2244] vendor subtree registry.
  • /<section-part> ๐Ÿงฉ is the top level of entries for one specific body part. This entry doesn't hold any attributes itself. The section-part is a numeric part specifier, and its syntax is the same as the section-part ABNF element defined in [RFC3501]. The server MUST return a BAD response if the client uses an incorrect part specifier, meaning either bad syntax or a specifier that points at a part that doesn't exist. The server MUST also return a BAD response if the client uses an empty part specifier, since IMAP uses that to mean the entire message.
  • /<section-part>/comment ๐Ÿ’ญ is a comment or note on one specific body part.
  • /<section-part>/flags ๐Ÿ is the top level for the flag state of one specific body part. The client maintains every sub-entry entirely on its own, and the server never changes any flag implicitly ๐Ÿค
    • /<section-part>/flags/seen ๐Ÿ‘€ works like the IMAP \Seen flag, except it only applies to the body part this entry points at.
    • /<section-part>/flags/answered โœ… works like the IMAP \Answered flag, except it only applies to the body part this entry points at.
    • /<section-part>/flags/flagged โญ works like the IMAP \Flagged flag, except it only applies to the body part this entry points at.
    • /<section-part>/flags/forwarded ๐Ÿ“จ works like the IMAP $Forwarded keyword, except it only applies to the body part this entry points at.

These entries set flags for one specific body part. The "value" attribute of each of the entries above must be either 1, 0, or NIL, and 1 means the flag is set. ๐ŸŽฏ

  • /<section-part>/vendor/<vendor-token> ๐ŸŒˆ is the top level of entries for one specific body part as created by one particular vendor's product. Vendors can use this for client-specific annotations. The vendor-token MUST be registered with IANA.

3.2.2. Attribute Names ๐Ÿท๏ธ

Attribute names MUST be specified in a standards track or IESG approved experimental RFC. See Section 6.1 for the registration template ๐Ÿ’–

Every attribute name implicitly comes with a .priv suffix and a .shared suffix, which map to the private and shared versions of the entry. If you search or fetch without either suffix, you get both ๐Ÿซถ The client MUST specify either a .priv or a .shared suffix when storing an annotation or sorting on annotations.

  • value ๐Ÿ’Ž is a string or binary data holding the value of the annotation. To delete an annotation, the client can store NIL into the value. If the client asks for the value attribute of an entry that doesn't exist, the server MUST return NIL for it. What the string means depends on the content-type that was used to register the entry (check Section 6.1 for the entry registration templates). When it applies, the registered content-type MUST include a charset parameter. Text values SHOULD use the utf-8 [RFC3629] character set. Binary data is allowed too (data that might contain the NULL octet, like images ๐Ÿ–ผ๏ธ), and this extension uses the "literal8" syntax element [RFC4466] so that binary data can be written to or read from the server ๐Ÿค“
  • size ๐Ÿ“ is the size of the value in octets. The server sets this automatically and clients can only read it. If the client asks for the size attribute of an entry that doesn't exist, the server MUST return "0" (zero) for the size.

3.3. Private Versus Shared ๐Ÿ”

Some IMAP mailboxes are private, so only the owning user can get to them. Other mailboxes aren't, either because the owner set up an ACL [RFC4314] that lets other users in, or because it's a shared mailbox ๐Ÿ‘ฏ

This brings up the whole shared versus private annotations question, and it's a big one ngl ๐Ÿ™ˆ

If every annotation is private, then annotations in a shared or non-private mailbox can never be seen by other users. That kills a really useful thing about annotations in a shared setup. Picture a shared IMAP folder full of bug reports ๐Ÿ› Engineers want to attach notes to existing messages, mark who's assigned, track status, and so on. That needs shared annotations ๐Ÿ“Œ

If every annotation is shared, then you can't keep private notes on messages in shared mailboxes ๐Ÿ˜ฌ And changing an ACL so other users can get into a mailbox might accidentally expose private info ๐Ÿ’€

Sometimes both kinds are useful at once. For example, an administrator might put shared annotations on messages in a shared folder, and then individual users add their own private notes on top ๐Ÿง

If shared and private annotations are going to live side by side, we need a clear way to tell them apart. It also has to be super easy for a client to reach both without missing either one ๐Ÿ‘€ And there's a real danger if a client can store an annotation without knowing whether it's shared or private ๐Ÿ˜ฑ

This document proposes two standard suffixes for every attribute: .shared and .priv ๐Ÿ’œ A SEARCH or FETCH command that doesn't specify either one uses both. STORE, APPEND, and SORT commands MUST explicitly use either the .priv or the .shared suffix ๐Ÿ™…โ€โ™€๏ธ

If the ANNOTATE extension is present, servers REQUIRED to support shared annotations, while support for private annotations is OPTIONAL on the server side. This is because private annotations can add a lot of complexity to a server, like tracking who owns each annotation or figuring out a user's quota based on their own annotations ๐Ÿงฎ Clients that support the ANNOTATE extension MUST handle both shared and private annotations ๐Ÿฆ‹

3.4. Access Control

okay so, who gets to peek at the .priv and .shared annotation values? ๐Ÿ‘€ A user needs the right rights to read or write them, and how those rights get calculated depends on whether the ACL [RFC2086] extension (or its update [RFC4314]) is around. If a client tries to store or fetch an annotation they don't have the rights for, the server MUST respond with a NO response. no vibes, just a firm no ๐Ÿ™…โ€โ™€๏ธ

When the ACL extension is NOT present, access to annotation values depends on the kind of selected state, especially whether the mailbox was SELECTED or EXAMINED in READ-ONLY or READ-WRITE mode. ๐ŸŒธ

When the ACL extension IS present, the server MUST recognize the new ACL "n" right, on top of the ones the ACL extension already has. โœจ

For .priv annotation values, the "r" right controls both read AND write access ๐Ÿ”. When it's on, .priv annotations are allowed. When it's off, they're disallowed. simple, but iconic.

For .shared annotation values, the "r" right controls read access. When it's on, .shared annotations can be read. When it's off, they can't be read. ๐Ÿฆ‹

For .shared annotation values, the "n" right controls write access. When it's on, .shared annotations can be changed or created through either a STORE or APPEND command. When it's off, they can't be changed or created. The "n" right counts as a "shared flag right" as defined in Section 6.2 of [RFC4314]. ๐Ÿ’…

Here's the whole access control situation in one table, bestie ๐Ÿ“‹

   +---------------+---------------+-----------------------------------+
   |  Server Type  | Action on     | Type of mailbox                   |
   |               | annotation    |                                   |
   +===============+===============+===================================+
   |               |               |                                   |
   |               | read .priv    | Any mailbox that can be SELECTED  |
   |               | values        | or EXAMINED.                      |
   |               |               |                                   |
   |               +---------------+-----------------------------------+
   |               |               |                                   |
   |               | write .priv   | Any SELECTED [READ-WRITE] mailbox.|
   |               | values        | SELECTED [READ-ONLY] mailboxes MAY|
   | Server        |               | also permit writes.               |
   | without       |               |                                   |
   | ACL Extension +---------------+-----------------------------------+
   |               |               |                                   |
   |               | read .shared  | Any mailbox that can be SELECTED  |
   |               | values        | or EXAMINED.                      |
   |               |               |                                   |
   |               +---------------+-----------------------------------+
   |               |               |                                   |
   |               | write .shared | Any mailbox that can be SELECTED  |
   |               | values        | or EXAMINED and is [READ-WRITE].  |
   |               |               |                                   |
   +---------------+---------------+-----------------------------------+
   |               |               |                                   |
   |               | read .priv    | Any mailbox with the "r"          |
   |               | values        | ACL right.                        |
   |               |               |                                   |
   |               +---------------+-----------------------------------+
   |               |               |                                   |
   |               | write .priv   | Any mailbox with the "r"          |
   | Server        | values        | ACL right.                        |
   | with          |               |                                   |
   | ACL Extension +---------------+-----------------------------------+
   |               |               |                                   |
   |               | read .shared  | Any mailbox with the "r"          |
   |               | values        | ACL right.                        |
   |               |               |                                   |
   |               +---------------+-----------------------------------+
   |               |               |                                   |
   |               | write .shared | Any mailbox with the "n"          |
   |               | values        | ACL right.                        |
   |               |               |                                   |
   +---------------+---------------+-----------------------------------+

3.5. Access to Standard IMAP Flags and Keywords

Okay, so, the ambiguity here is real ๐Ÿ˜ญ. It isn't clear how private and shared values would line up with the base IMAP flag and keyword values, so the ANNOTATE extension does NOT expose IMAP flags or keywords as entries. BUT the /flags annotation entry is reserved for future use, and it MUST NOT be used by clients or servers that support this extension. hands off, please ๐Ÿšซ

Clients that need shared and private "flags" can make their own annotation entries for those instead, totally bypassing the base IMAP flag/keyword behavior. main character move ๐Ÿงš

4. IMAP Protocol Changes

4.1. General Considerations

Not every server is going to give you the full annotation experience ๐Ÿฅฒ, so it helps clients know what level of support they've got. That's why servers MUST return an ANNOTATIONS response code during the SELECT or EXAMINE command for a mailbox to say how much support there is. These are the possible data items you'll see with the ANNOTATIONS response code:

  • "NONE": the mailbox being selected doesn't support annotations at all. Clients MUST NOT attempt to use annotation extensions in commands for this mailbox. ๐Ÿ™ˆ
  • "READ-ONLY": the annotations supported by the mailbox can't be changed by the client. Clients MUST NOT attempt to store annotations on any messages in a mailbox with this response code. ๐Ÿ”’
  • "NOPRIVATE": the server doesn't support private annotations on the mailbox, so only shared annotations are supported. Clients SHOULD only attempt to read or store annotation attributes with the .shared suffix. If a client uses an attribute with the .priv suffix in a FETCH command, then servers should return the attribute value in the FETCH response as NIL. If a client uses an attribute with the .priv suffix in a STORE command (or an APPEND command targeted at the mailbox), then the server MUST return a NO response. ๐Ÿซฃ
  • numeric values: if servers support writable annotations, the server MUST indicate the maximum size in octets for an annotation value by providing the maximum size value in the response code. Clients MUST NOT store annotation values bigger than what the server indicated. Servers MUST accept a minimum annotation data size of at least 1024 octets if annotations can be written. ๐Ÿ“

On top of that, the server MAY limit the total number of annotations for a single message. But the server MUST provide a minimum annotation count per message of at least 10. ๐Ÿ”ข

4.2. ANNOTATE Parameter with the SELECT/EXAMINE Commands

The ANNOTATE extension defines one optional SELECT parameter [RFC4466], "ANNOTATE", which turns on unsolicited responses for annotations (more on those in Section 4.4) โœจ. This parameter is a per-mailbox state change. Basically, it has to be used in EACH SELECT/EXAMINE command to work, no matter if you used it in an earlier SELECT/EXAMINE during the same session. Don't assume it sticks around, bestie ๐Ÿ’€

Here's an example:

     C: a SELECT INBOX (ANNOTATE)
     S: * FLAGS (\Answered \Flagged \Draft \Deleted \Seen)
     S: * OK [PERMANENTFLAGS (\Answered \Flagged \Draft
                                       \Deleted \Seen \*)]
     S: * 10268 EXISTS
     S: * 1 RECENT
     S: * OK [UNSEEN 10268]
     S: * OK [UIDVALIDITY 890061587]
     S: * OK [UIDNEXT 34643]
     S: * OK [ANNOTATIONS 20480 NOPRIVATE]
     S: a OK [READ-WRITE] Completed

In this one, the client sends a SELECT command with the ANNOTATE parameter ๐ŸŽ€. The server's response includes the required ANNOTATIONS response, which says annotations go up to a maximum size of 20480 octets, and that private annotations aren't supported (only shared ones). the server really said "shared only, babe" and we respect that ๐ŸŒˆ

4.3. ANNOTATION Message Data Item in FETCH Command โœจ

okay so this extension adds an ANNOTATION message data item to the FETCH command ๐Ÿงš which means clients can grab annotations for a whole range of messages in the mailbox that's currently selected ๐Ÿ“ฌ

ANNOTATION <entry-specifier> <attribute-specifier>

when the client uses it in FETCH, it takes an entry specifier and an attribute specifier ๐Ÿ’…

Example:

C: a FETCH 1 (ANNOTATION (/comment value))
S: * 1 FETCH (ANNOTATION (/comment
                            (value.priv "My comment"
                             value.shared "Group note")))
S: a OK Fetch complete

in this one, the content of the "value" attribute for the "/comment" entry gets requested by the client and returned by the server ๐ŸŽ€ neither ".shared" nor ".priv" was specified, so both come back ๐Ÿ’–

the * and % wild card characters can go in entry specifiers to match one or more characters at that position ๐Ÿฆ‹ the catch is that % won't match the / hierarchy delimiter. so /% matches entries like /comment and /altsubject, but NOT /1/comment ๐Ÿ™ˆ

Example:

C: a UID FETCH 1123 (UID ANNOTATION
                     (/* (value.priv size.priv)))
S: * 12 FETCH (UID 1123 ANNOTATION
       (/comment (value.priv "My comment"
                            size.priv "10")
        /altsubject (value.priv "Rhinoceroses!"
                            size.priv "13")
        /vendor/foobar/label.priv
                            (value.priv "label43"
                             size.priv "7")
        /vendor/foobar/personality
                            (value.priv "Tallulah Bankhead"
                             size.priv "17")))
S: a OK Fetch complete

here the client asks for the private "value" and "size" attributes of every entry in the "/" hierarchy, and the server sends them all back ๐Ÿ”ฅ

Example:

C: a FETCH 1 (ANNOTATION (/% value.shared))
S: * 1 FETCH (ANNOTATION
   (/comment (value.shared "Patch Mangler")
    /altsubject (value.shared "Patches?  We don't
    need no steenkin patches!")))
S: a OK Fetch complete

this time the client only wants the shared "value" attributes for entries at the top level of the "/" hierarchy, and that's exactly what the server returns ๐ŸŒธ

entry and attribute specifiers can be lists of atomic specifiers too, so you can get multiple items of each type in one FETCH command ๐Ÿ‘‘

Example:

C: a FETCH 1 (ANNOTATION
     ((/comment /altsubject) value.priv))
S: * 1 FETCH (ANNOTATION
     (/comment (value.priv "What a chowder-head")
      /altsubject (value.priv "How to crush beer cans")))
S: a OK Fetch complete

the private "value" attributes for the two entries "/comment" and "/altsubject" are requested and returned together, iconic โœจ

4.4. ANNOTATION Message Data Item in FETCH Response ๐Ÿฆ‹

the ANNOTATION message data item in the FETCH response shows you info about the annotations on a message ๐Ÿ’œ

ANNOTATION parenthesized list

the response is a list of entries, and each entry has its own list of attribute-value pairs ๐Ÿงš

Example:

C: a FETCH 1 (ANNOTATION (/comment value))
S: * 1 FETCH (ANNOTATION (/comment
                           (value.priv "My comment"
                            value.shared NIL)))
S: a OK Fetch complete

one entry with one attribute-value pair comes back here. the client didn't say ".shared" or ".priv", so both show up, but only the private one has a real value. the shared one is NIL ๐Ÿ™ˆ

Example:

C: a FETCH 1 (ANNOTATION
     ((/comment /altsubject) value))
S: * 1 FETCH (ANNOTATION
     (/comment (value.priv "My comment"
                          value.shared NIL)
      /altsubject (value.priv "My subject"
                          value.shared NIL)))
S: a OK Fetch complete

two entries, each with one attribute-value pair. again no suffix was given, so both get returned, and only the private attributes have values while the shared ones are NIL ๐Ÿ’…

Example:

C: a FETCH 1 (ANNOTATION
                (/comment (value size)))
S: * 1 FETCH (ANNOTATION
                (/comment
                    (value.priv "My comment"
                     value.shared NIL
                     size.priv "10"
                     size.shared "0")))
S: a OK Fetch complete

one entry with two attribute-value pairs. no suffix, so both privs and shareds come back, and only the private ones have values while the shared ones are NIL ๐ŸŽ€

here's the big one ๐Ÿ‘€ servers SHOULD send ANNOTATION message data items in unsolicited FETCH responses when an annotation entry gets changed by a third-party AND the ANNOTATE select parameter was used. that's how servers keep clients up to date with changes other clients make ๐Ÿซถ

BUT unsolicited ANNOTATION responses MUST NOT include ANNOTATION data values. they only carry the entry name of the annotation that changed ๐Ÿ˜ญ the reason is that values can be huge, so they don't get sent to a client unless that client explicitly asks for them ๐Ÿ”ฅ

the unsolicited response only has the entry name, never the value. no sneaking big data in uninvited ๐Ÿ’€

Example:

C: a STORE 1 +FLAGS (\Seen)
S: * 1 FETCH (FLAGS (\Seen))
              ANNOTATION (/comment))
S: a OK STORE complete

in this example, an unsolicited ANNOTATION response shows up during a STORE command. it contains only the entry name of the annotation that changed, not its value ๐ŸŒˆ

4.5. ANNOTATION Message Data Item in STORE ๐Ÿ’–

ANNOTATION <parenthesized entry-attribute-value list>

this sets the entries you list by adding or replacing the attributes you specify with the values you give. if a client wants to remove an attribute from an entry, it can use NIL as the value ๐Ÿงน

the ANNOTATION message data item used with STORE has an implicit ".SILENT" behavior ๐Ÿคซ which means the server doesn't send an untagged FETCH in response to the STORE command, and it assumes the client updates its own cache when the command succeeds. BUT heads up: if the Conditional STORE extension [RFC4551] is present, then the server WILL send an untagged FETCH response with a MODSEQ data item, as required by [RFC4551] ๐Ÿ™Œ

if the server can't store an annotation because its value is too big, the server MUST return a tagged NO response with a [ANNOTATE TOOBIG] response code ๐Ÿ˜ฌ

if the server can't store a NEW annotation because it has already hit the maximum number of allowed annotations, the server MUST return a tagged NO response with a [ANNOTATE TOOMANY] response code ๐Ÿ™…โ€โ™€๏ธ

Example:

C: a STORE 1 ANNOTATION (/comment
                         (value.priv "My new comment"))
S: a OK Store complete

the entry "/comment" gets created if it doesn't exist yet. its private "value" attribute gets created if it's not there, or replaced if it is. "value.priv" is now My new comment โœจ

Example:

C: a STORE 1 ANNOTATION (/comment
                         (value.shared NIL))
S: a OK Store complete

the shared "value" attribute of "/comment" gets removed by storing NIL into it ๐Ÿงผ

you can set multiple entries in one STORE command by listing entry-attribute-value pairs in the list ๐Ÿ“

Example:

C: a STORE 1 ANNOTATION (/comment
                         (value.priv "Get tix Tuesday")
                         /altsubject
                         (value.priv "Wots On"))
S: a OK Store complete

"/comment" and "/altsubject" both get created if they're missing, and the private "value" attribute gets created or replaced for each one ๐Ÿ’…

you can also set multiple attributes in one STORE command by listing several attribute-value pairs in the entry list ๐ŸŒธ

Example:

C: a STORE 1 ANNOTATION (/comment
                         (value.priv "My new comment"
                          value.shared "foo's bar"))
S: a OK Store complete

"/comment" gets created if needed, and its private and shared "value" attributes get created if missing or replaced if they're already there ๐ŸŽ€

4.6. ANNOTATION Interaction with COPY ๐Ÿงš

the COPY command moves messages from one mailbox to another on the same server ๐Ÿ“ฆ servers that support the ANNOTATION extension MUST, for each message being copied, copy all ".priv" annotation data for the current user ONLY, plus all ".shared" annotation data, along with the message into the new mailbox ๐Ÿซถ

there are some exceptions. first, if the destination mailbox permissions mean the ".priv" or ".shared" annotations aren't allowed. second, if the destination mailbox is a type that doesn't support annotations, or doesn't support storing them (a mailbox that returns a NONE or READ-ONLY response code in its ANNOTATIONS response). third, if the destination mailbox can't handle the size of an annotation because it goes over the ANNOTATIONS value ๐Ÿ˜ค

and servers MUST NOT copy ".priv" annotation data for users OTHER than the current user ๐Ÿ”’

4.7. ANNOTATION Message Data Item in APPEND ๐Ÿ‘

ANNOTATION <parenthesized entry-attribute-value list>

this sets the entries and attributes you list on the resulting message ๐Ÿ’œ

the APPEND command can include annotations for the message being appended, by adding a new append data item [RFC4466] ๐Ÿง the new data item also works with the multi-append [RFC3502] extension, which lets you append multiple messages with a single APPEND command ๐ŸŒˆ

Example:

C: a APPEND drafts ANNOTATION (/comment
     (value.priv "Don't send until I say so")) {310}
S: + Ready for literal data
C: MIME-Version: 1.0
...
C:
S: a OK APPEND completed

in this one, a comment with a private value gets added to a new message that's appended to the mailbox. the ellipsis stands in for the bulk of the message ๐Ÿ“

ANNOTATION <entry-name> <attribute-name> <value>

okay so the ANNOTATION criterion for SEARCH lets a client go detective ๐Ÿ•ต๏ธโ€โ™€๏ธ and hunt for a specific string inside the value of an annotation entry on a message. it's giving investigation energy, bestie.

Messages that have annotations with entries matching <entry-name>, attributes matching <attribute-name>, and the specified string <value> in their values come back in the SEARCH results โœจ. The * character can be used in the entry name field to match any content in those items ๐ŸŒˆ, and the % character can be used in the entry name field to match a single level of hierarchy only ๐ŸŽ€.

Only the value, value.priv, and value.shared attributes can be searched ๐Ÿ’…. Clients MUST NOT specify an attribute other than either value, value.priv, or value.shared. Servers MUST return a BAD response if the client tries to search any other attribute ๐Ÿ™ˆ.

Example:

C: a SEARCH ANNOTATION /comment value "IMAP4"
S: * SEARCH 2 3 5 7 11 13 17 19 23
S: a OK Search complete

In the above example, the message numbers of any messages containing the string "IMAP4" in the shared or private value attribute of the /comment entry are returned in the search results ๐Ÿฆ‹.

Example:

C: a SEARCH ANNOTATION * value.priv "IMAP4"
S: * SEARCH 1 2 3 5 8 13 21 34
S: a OK Search complete

In the above example, the message numbers of any messages containing the string "IMAP4" in the private value attribute of any entry are returned in the search results ๐Ÿ’œ.


4.9. ANNOTATION Key in SORT ๐Ÿง

ANNOTATION <entry-name> <attribute-name>

the ANNOTATION criterion for the SORT command [RFC5256] tells the server to return the sequence numbers or Unique Identifiers (UIDs) of messages in a mailbox, sorted by the values of the annotations you pick ๐Ÿ—‚๏ธ. this one is available if the server returns both ANNOTATE-EXPERIMENT-1 and SORT as supported capabilities in the CAPABILITY command response, so check those first, bestie โœ….

Messages are sorted using the values of the <attribute-name> attributes in the <entry-name> entries.

Clients MUST provide either the .priv or .shared suffix to the attribute name so the server knows exactly which value to sort on ๐ŸŽฏ.

Only the value.priv and value.shared attributes can be used for sorting ๐Ÿ’…. Clients MUST NOT specify an attribute other than either value.priv or value.shared. Servers MUST return a BAD response if the client tries to sort on any other attribute ๐Ÿ™ˆ.

When either value.priv or value.shared is being sorted, the server MUST use the character set value specified in the SORT command to determine the appropriate sort order ๐Ÿ”ค.

Example:

C: a SORT (ANNOTATION /altsubject value.shared) UTF-8 ALL
S: * SORT 2 3 4 5 1 11 10 6 7 9 8
S: a OK Sort complete

In the above example, the message numbers of all messages are returned, sorted according to the shared value attribute of the /altsubject entry ๐ŸŒธ.

Note that the ANNOTATION sort key must include a fully specified entry -- wild cards are not allowed. no stars here, bestie ๐ŸŒŸ

4.10. New ACL Rights ๐Ÿ”

As discussed in Section 3.4, this extension adds a new "n" right to the list of rights provided by the ACL extensions [RFC2086] and [RFC4314]. โœจ


5. Formal Syntax ๐Ÿ“œ

The following syntax specification uses the Augmented Backus-Naur Form (ABNF) notation as specified in [RFC5234] ๐Ÿ’–.

Non-terminals referenced but not defined below are as defined by [RFC3501] with the new definitions in [RFC4466] superseding those in [RFC3501] ๐Ÿงฉ.

Except as noted otherwise, all alphabetic characters are case-insensitive. The use of upper or lower case characters to define token strings is for editorial clarity only. Implementations MUST accept these strings in a case-insensitive fashion ๐Ÿซถ.

ann-size          = "NONE" /
                     (("READ-ONLY" / nz-number)
                      [SP "NOPRIVATE"])
                     ; response codes indicating the level of
                     ; support for annotations in a mailbox

append-ext        =/ att-annotate
                    ; modifies [RFC3501] extension behaviour

att-annotate      = "ANNOTATION" SP
                         "(" entry-att *(SP entry-att) ")"

att-search        = "value" / "value.priv" / "value.shared"
                    ; the only attributes that can be searched

att-sort          = "value.priv" / "value.shared"
                    ; the only attributes that can be sorted

att-value         = attrib SP value

attrib            = astring
                    ; dot-separated attribute name
                    ; MUST NOT contain "*" or "%"

attribs           = attrib / "(" attrib *(SP attrib) ")"
                    ; one or more attribute specifiers

capability        =/ "ANNOTATE-EXPERIMENT-1"
                    ; defines the capability for this extension

entries           = entry-match /
                    "(" entry-match *(SP entry-match) ")"

entry             = astring
                    ; slash-separated path to entry
                    ; MUST NOT contain "*" or "%"

entry-att         = entry SP "(" att-value *(SP att-value) ")"

entry-match       = list-mailbox
                    ; slash-separated path to entry
                    ; MAY contain "*" or "%" for use as wild cards

fetch-att         =/ "ANNOTATION" SP "(" entries SP attribs ")"
                    ; modifies original IMAP fetch-att

msg-att-dynamic   =/ "ANNOTATION" SP
                       ( "(" entry-att *(SP entry-att) ")" /
                         "(" entry *(SP entry) ")" )
                    ; extends FETCH response with annotation data

resp-text-code    =/ "ANNOTATE" SP "TOOBIG" /
                     "ANNOTATE" SP "TOOMANY" /
                     "ANNOTATIONS" SP ann-size
                    ; new response codes

search-key        =/ "ANNOTATION" SP entry-match SP att-search
                     SP value
                    ; modifies original IMAP search-key

select-param      =/ "ANNOTATE"
                    ; defines the select parameter used with
                    ; ANNOTATE extension

sort-key          =/ "ANNOTATION" SP entry SP att-sort
                    ; modifies original sort-key

store-att-flags   =/ att-annotate
                    ; modifies original IMAP STORE command

value             = nstring / literal8

6. IANA Considerations ๐Ÿฆ„

Entry names MUST be specified in a standards track or IESG approved experimental RFC, or fall under the vendor namespace. Vendor names MUST be registered ๐Ÿท๏ธ.

Attribute names MUST be specified in a standards track or IESG approved experimental RFC ๐ŸŽ€.

Each entry registration MUST include a content-type that is used to indicate the nature of the annotation value. Where applicable, a charset parameter MUST be included with the content-type ๐Ÿ’….

6.1. Entry and Attribute Registration Template ๐Ÿ“

To: iana@iana.org
Subject: IMAP Annotate Registration

Please register the following IMAP Annotate item:

[] Entry        [] Attribute

Name: ______________________________

Description: _______________________

____________________________________

____________________________________

Content-Type:_______________________

Contact person: ____________________

        email:  ____________________

6.2. Entry Registrations ๐Ÿ’–

The following templates specify the IANA registrations of annotation entries specified in this document ๐ŸŒท.

6.2.1. /comment

To: iana@iana.org
Subject: IMAP Annotate Registration

Please register the following IMAP Annotate item:

[X] Entry        [] Attribute

Name: /comment

Description: Defined in IMAP ANNOTATE extension document.

Content-Type: text/plain; charset=utf-8

Contact person: Cyrus Daboo

        email:  cyrus@daboo.name

6.2.2. /flags

To: iana@iana.org
Subject: IMAP Annotate Registration

Please register the following IMAP Annotate item:

[X] Entry        [] Attribute

Name: /flags

Description: Reserved entry hierarchy.

Content-Type: -

Contact person: Cyrus Daboo

        email:  cyrus@daboo.name

6.2.3. /altsubject

To: iana@iana.org
Subject: IMAP Annotate Registration

Please register the following IMAP Annotate item:

[X] Entry        [] Attribute

Name: /altsubject

Description: Defined in IMAP ANNOTATE extension document.

Content-Type: text/plain; charset=utf-8

Contact person: Cyrus Daboo

        email:  cyrus@daboo.name

6.2.4. /<section-part>/comment

To: iana@iana.org
Subject: IMAP Annotate Registration

Please register the following IMAP Annotate item:

[X] Entry        [] Attribute

Name: /<section-part>/comment

Description: Defined in IMAP ANNOTATE extension document.

Content-Type: text/plain; charset=utf-8

Contact person: Cyrus Daboo

        email:  cyrus@daboo.name

6.2.5. /<section-part>/flags/seen

To: iana@iana.org
Subject: IMAP Annotate Registration

Please register the following IMAP Annotate item:

[X] Entry        [] Attribute

Name: /<section-part>/flags/seen

Description: Defined in IMAP ANNOTATE extension document.

Content-Type: text/plain; charset=utf-8

Contact person: Cyrus Daboo

        email:  cyrus@daboo.name

6.2.6. /<section-part>/flags/answered

To: iana@iana.org
Subject: IMAP Annotate Registration

Please register the following IMAP Annotate item:

[X] Entry        [] Attribute

Name: /<section-part>/flags/answered

Description: Defined in IMAP ANNOTATE extension document.

Content-Type: text/plain; charset=utf-8

Contact person: Cyrus Daboo

        email:  cyrus@daboo.name

6.2.7. /<section-part>/flags/flagged

To: iana@iana.org
Subject: IMAP Annotate Registration

Please register the following IMAP Annotate item:

[X] Entry        [] Attribute

Name: /<section-part>/flags/flagged

Description: Defined in IMAP ANNOTATE extension document.

Content-Type: text/plain; charset=utf-8

Contact person: Cyrus Daboo

        email:  cyrus@daboo.name

6.2.8. /<section-part>/flags/forwarded

To: iana@iana.org
Subject: IMAP Annotate Registration

Please register the following IMAP Annotate item:

[X] Entry        [] Attribute

Name: /<section-part>/flags/forwarded

Description: Defined in IMAP ANNOTATE extension document.

Content-Type: text/plain; charset=utf-8

Contact person: Cyrus Daboo

        email:  cyrus@daboo.name

6.3. Attribute Registrations ๐ŸŒˆ

The following templates specify the IANA registrations of annotation attributes specified in this document ๐Ÿงš.

6.3.1. value

To: iana@iana.org
Subject: IMAP Annotate Registration

Please register the following IMAP Annotate item:

[] Entry        [X] Attribute

Name: value

Description: Defined in IMAP ANNOTATE extension document.

Contact person: Cyrus Daboo

        email:  cyrus@daboo.name

6.3.2. size

To: iana@iana.org
Subject: IMAP Annotate Registration

Please register the following IMAP Annotate item:

[] Entry        [X] Attribute

Name: size

Description: Defined in IMAP ANNOTATE extension document.

Contact person: Cyrus Daboo

        email:  cyrus@daboo.name

6.4. Capability Registration ๐Ÿ‘‘

This document registers "ANNOTATE-EXPERIMENT-1" as an IMAPEXT capability โญ.

7. Internationalization Considerations ๐ŸŒ

Okay bestie, annotations can hold text values, and you can search and sort them too ๐Ÿ”. So servers MUST follow standard IMAP text normalization, character set conversion, and collation rules whenever they do that, the same way they would for any other text field being searched or sorted on ๐Ÿ’…โœจ

8. Security Considerations ๐Ÿ”

Okay this part is serious, no cap ๐Ÿ˜ญ Annotations whose values are meant to stay private MUST be stored in .priv values instead of .shared values, because .shared values may be accessible to other users. Do not skip this one, bestie ๐Ÿซถ

Apart from that, the ANNOTATE extension doesn't raise any security issues that the base IMAP protocol doesn't already have. Those are covered in [RFC3501] ๐Ÿ›ก๏ธ

9. References ๐Ÿ“š

9.1. Normative References ๐Ÿ”—

  • [RFC2086] Myers, J., "IMAP4 ACL extension", RFC 2086, January 1997.
  • [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
  • [RFC2244] Newman, C. and J. Myers, "ACAP -- Application Configuration Access Protocol", RFC 2244, November 1997.
  • [RFC3501] Crispin, M., "INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1", RFC 3501, March 2003.
  • [RFC3502] Crispin, M., "Internet Message Access Protocol (IMAP) - MULTIAPPEND Extension", RFC 3502, March 2003.
  • [RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO 10646", STD 63, RFC 3629, November 2003.
  • [RFC4314] Melnikov, A., "IMAP4 Access Control List (ACL) Extension", RFC 4314, December 2005.
  • [RFC4466] Melnikov, A. and C. Daboo, "Collected Extensions to IMAP4 ABNF", RFC 4466, April 2006.
  • [RFC5234] Crocker, D., Ed., and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", STD 68, RFC 5234, January 2008.
  • [RFC5256] Crispin, M. and K. Murchison, "Internet Message Access Protocol - SORT and THREAD Extensions", RFC 5256, June 2008.

9.2. Informative References ๐Ÿ’ก

  • [RFC4551] Melnikov, A. and S. Hole, "IMAP Extension for Conditional STORE Operation or Quick Flag Changes Resynchronization", RFC 4551, June 2006.

10. Acknowledgments ๐Ÿ™

Huge thanks to Chris Newman for his super detailed comments on the first draft, and to everyone at the ACAP working dinner in Pittsburgh ๐Ÿฝ๏ธ The IMAPext working group participants also made major contributions to this work, so they get all the flowers ๐ŸŒธ

Authors' Addresses ๐Ÿ’Œ

   Cyrus Daboo
   Apple Inc.
   1 Infinite Loop
   Cupertino, CA  95014
   USA

   EMail: cyrus@daboo.name
   URI:   http://www.apple.com/


   Randall Gellens
   QUALCOMM Incorporated
   5775 Morehouse Dr.
   San Diego, CA  92121-2779
   USA

   EMail: randy@qualcomm.com

Copyright (C) The IETF Trust (2008).

This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth therein, the authors retain all their rights.

This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

Intellectual Property ๐Ÿฆ‹

The IETF takes no position regarding the validity or scope of any Intellectual Property Rights or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; nor does it represent that it has made any independent effort to identify any such rights. Information on the procedures with respect to rights in RFC documents can be found in BCP 78 and BCP 79.

Copies of IPR disclosures made to the IETF Secretariat and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this specification can be obtained from the IETF on-line IPR repository at http://www.ietf.org/ipr.

The IETF invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights that may cover technology that may be required to implement this standard. Please address the information to the IETF at ietf-ipr@ietf.org.

๐Ÿ“ฆ where this page comes from