Skip to content

MailFerry v2.1.0 — IMAP Migration & Sync

Latest

Choose a tag to compare

@ajsap ajsap released this 03 Aug 21:47

MailFerry v2.1.0 — Feature Release

High-Performance Native IMAP Migration Engine.

OAuth 2.0 / modern authentication with a first-class mailferry auth
lifecycle, IMAP MULTIAPPEND batching, evidence-based server
identification, and a substantially polished operator experience.

Migration correctness, the statistics identity, terminal sanitisation
and SIGHUP handling are unchanged and still test-enforced. Existing
password migrations and existing mailferry.db / mailferry.toml
files continue to work untouched.

Added

  • OAuth 2.0 / modern authentication (SASL XOAUTH2, and
    OAUTHBEARER for standards-compliant servers). First-class
    Microsoft 365 / Exchange Online and Google Workspace / Gmail,
    plus a generic provider. Source and destination authenticate
    independently — password↔OAuth, or two different providers, in one
    run. The canonical 10-column CSV is unchanged: an endpoint opts in
    with an oauth:<profile> password cell.
  • Three authentication models, kept deliberately distinct:
    delegated (one user's own mailbox), application (Microsoft 365
    app-only, IMAP.AccessAsApp — one tenant app → many mailboxes) and
    service_account (Google domain-wide delegation → many mailboxes).
    An administrative profile mints its tenant token once and shares
    it across every mailbox and worker in the run.
  • mailferry auth command familyadd / list / show /
    test / refresh / remove. Browser loopback + PKCE (RFC 8252),
    headless device code (RFC 8628) for Microsoft, and manual redirect
    capture for Google. --user names the mailbox you mean: it is sent
    as the OIDC login_hint and the account that actually signed in is
    verified afterwards — on a mismatch nothing is saved.
    auth test is a staged diagnostic: token → TLS → SASL → LIST,
    then the server's full capability list and a plain-language verdict.
  • Secrets are never stored in configuration. Client secrets,
    refresh tokens and service-account keys are held as external
    references (env: / file: / keychain: / dpapi: / cmd:) and
    resolved at run time — never written to mailferry.toml, the State
    Database, logs, reports or traces. Storage uses the OS-native secure
    store: macOS login keychain, Linux Secret Service, Windows DPAPI
    (current-user scope), with a documented 0600 fallback.
  • IMAP MULTIAPPEND (RFC 3502) — several messages uploaded in one
    APPEND command when the destination advertises it. On by default
    with automatic batch sizing (--multiappend auto|off,
    --multiappend-batch-size auto|N). On the built-in benchmark, 400
    messages went from 400 append commands to 50. It is an
    optimisation and nothing more
    : bodies still stream (memory stays
    proportional to a chunk, not a batch), an unsupported destination
    transparently uses one append per message, and every message keeps
    its own durable state, destination UID, flags and INTERNALDATE.
    Batch size is not concurrency.
  • Evidence-based server identification. MailFerry reports what the
    server positively says about itself — OAuth provider, RFC 2971 IMAP
    ID, vendor-private CAPABILITY, greeting banner, TLS certificate —
    and displays Unknown when the evidence is insufficient. There is
    no hostname table, provider list or fingerprint database
    , and the
    identifier is never given the hostname, so guessing from a domain is
    structurally impossible.
  • Adaptive Dashboard. A Source / Destination panel reporting host,
    server, auth, negotiated TLS and that connection's current speed;
    for heterogeneous (MSP) runs it aggregates by identified platform
    rather than showing one mailbox as if it spoke for the run. Plus a
    live F3 mailbox inspector, one unified quit confirmation (Esc
    never exits), a Runtime that freezes on completion, and a single
    authoritative completion timestamp.
  • Interactive F9 Settings and an expanded typed configuration
    surface, saved atomically to mailferry.toml with comments
    preserved.
  • Documentation: docs/OAUTH.md (the authentication model),
    docs/OAUTH-SETUP.md (step-by-step Microsoft Entra and Google Cloud
    configuration, verified against the official provider documentation
    on 01/08/2026) and docs/MULTIAPPEND.md.

Fixed

  • Cancelling a run no longer abandons appends already on the wire.
    A stopped transfer settles the commands it has already sent, so each
    message's outcome is recorded rather than left ambiguous — removing
    a path where a resume could copy a message twice.
  • A starting migration could fail if something was watching it.
    SQLite does not apply busy_timeout to PRAGMA journal_mode, so a
    read-only observer (mailferry attach) opening the file during the
    initial WAL switch could abort the run with database is locked.
    Schema initialisation now retries on lock contention.
  • keychain: secret references are now resolvable on Linux (Secret
    Service via secret-tool); previously a reference could be stored
    that only macOS could read back.

Verification

gofmt, go vet (darwin/linux/windows), the full unit and end-to-end
suites and the race detector all pass. Two clean builds of this commit
are byte-identical.

Known limitations

  • macOS binaries are not yet Apple-notarised — Gatekeeper may block
    the first launch and a one-time Open Anyway is expected. See
    docs/INSTALLATION-MACOS.md;
    never disable Gatekeeper. The signing pipeline is documented in
    docs/RELEASING-MACOS.md and planned for a future release.
  • Terminal/PTY regression tests are Linux-only and were not executed on
    the macOS build host.
  • Real-provider verification to date covers the Microsoft 365
    delegated browser flow. The device-code, app-only, Google
    delegated and Google domain-wide-delegation paths, Windows DPAPI
    storage and Linux Secret Service are implemented and unit-tested
    against mocked providers, but have not yet been exercised against
    live tenants.

Verifying your download

shasum -a 256 -c SHA256SUMS      # macOS
sha256sum -c SHA256SUMS          # Linux

Full changelog:
https://github.com/ajsap/mailferry/blob/main/CHANGELOG.md