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
- Sign in, then open
/accounts. - 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 oria_session. iCloud is one provider in that list, not a separate card. - Duckbill logs in to
imap.mail.me.com:993, lists mailboxes, and stores the password as AES-256-GCM ciphertext (token_type = imap_secret). - 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, soJason.s.koch@icloud.comandjskoch67@icloud.comstay distinct. - iCloud stays read-write. Archive, mark read, flag, delete, and folder move still post
/api/mail/icloud/changeand/api/mail/move. The same account uses IMAPUID MOVE. A different connected iCloud account fetchesRFC822, 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.
