Skip to content

iCloud connect and move

MAIL-239 and MAIL-250 connect an Apple mailbox with an app-specific password. On 2026-10-08 the owner required iCloud to be read-write. Archive, mark read, flag, delete, and move change mail. Move still works between folders and between connected iCloud accounts.

Send stays off. A second Apple address does not replace the first. Each row keeps its own app-specific password.

Product path

  1. Sign in, then open /accounts.
  2. On /accounts, choose +, then iCloud. Enter the Apple address and an app-specific password. The form posts /api/providers/icloud/connect. The password is not placed in the URL or ia_session. iCloud is one provider in that list, not a separate card.
  3. Duckbill logs in to imap.mail.me.com:993, lists mailboxes, and stores the password as AES-256-GCM ciphertext (token_type = imap_secret).
  4. The Accounts row shows the display address and provider icloud. A second Apple address for the same user is a second row. The provider identity is the lowercased address, so Jason.s.koch@icloud.com and jskoch67@icloud.com stay distinct.
  5. iCloud stays read-write. Archive, mark read, flag, delete, and folder move still post /api/mail/icloud/change and /api/mail/move. The same account uses IMAP UID MOVE. A different connected iCloud account fetches RFC822, appends it to the destination folder, then removes it from the source. Folder names come from /api/providers/icloud/folders. The Change iCloud mail form is not mounted on Accounts, a conversation, or the mail client.

Accepted addresses are @icloud.com, @me.com, and @mac.com.

Host environment

No new secret name. Connect and move use the existing DATABASE_URL, TOKEN_ENCRYPTION_KEY, and SESSION_SECRET. Do not put the app-specific password in env, git, Jira, or logs.

Migration 0021_icloud_imap_secret.sql allows the imap_secret token type. Migration 0022_icloud_move.sql marks move as read-write. Migration 0023_icloud_mailbox_writes.sql turns on archive, mark read, flag, and delete for existing iCloud rows without deleting a second account. Apply 0023 before the owner retries those writes.

Owner gate

Live Apple login needs the owner's app-specific password. Agents must not invent one or copy it into a ticket. A local IMAP fixture proves encryption, two-row persistence, folder move, and cross-account move. The owner completes the live login on preview from /accounts.