Evaluated OAuth2 (SPEC §10) and chose not to build it this phase. A self-built, unverified OAuth app suffers Google's 7-day refresh-token expiry in Testing status (or the unverified-warning + restricted-scope verification cost in Production). For a single-user personal tool, a Gmail App Password (2FA) is strictly simpler and reuses the IMAP/SMTP password auth from Phases 1–2. Validated live against a real Gmail account over app-password auth: list/get/ search, send, and a full SMTP-out → IMAP-in round-trip. No code changes were required; the speculative OAuth store fields started mid-session were reverted. OAuth2 remains a clean future addition (schema columns already present). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4.2 KiB
emcli — Phase 3 Status Report
Date: 2026-06-22
Branch: main
Phase 3 (as specified): OAuth2 — Gmail loopback consent + token refresh (SPEC §10).
Outcome: OAuth2 deferred; Gmail handled via app password on the existing auth path
After evaluating the OAuth2 design against the actual use case (a personal, self-built CLI for one Gmail account), we chose not to build the OAuth2 machinery in this phase. Gmail is instead accessed with a Google App Password over emcli's existing password auth (Phases 1–2) — and it was validated live, end-to-end. No new code was required.
Why OAuth2 was deferred (not just "skipped")
A self-built tool cannot replicate the "Log in with Google" experience of verified clients (Mailspring, Thunderbird, Aerion) without owning a verified, published OAuth app. For a personal embed the options are all poor:
- Unverified app in "Testing" publishing status → Google expires refresh tokens every 7 days, forcing weekly re-consent. Unusable for an unattended tool.
- Unverified app in "Production" status → refresh tokens are long-lived, but every login shows
the "Google hasn't verified this app" warning, and
https://mail.google.com/is a restricted scope (full verification needs a paid security assessment). Workable, but heavy setup for one user. - App Password (chosen) → requires only that 2-Step Verification is enabled. Yields a permanent 16-character credential usable with standard IMAP/SMTP password auth. No consent screen, no 7-day expiry, no client ID/secret, no Google Cloud project. Revoked only on manual revoke, main-password change, or disabling 2FA.
For a single-user personal tool, the App Password is strictly simpler and more robust, and it reuses the IMAP/SMTP password path already shipped and tested in Phases 1–2.
OAuth2 remains a clean future addition (SPEC §10, schema columns already present) if emcli ever needs multi-user/provider support or a verified app. The mechanism would be: x/oauth2 loopback consent + an XOAUTH2
sasl.Client(go-sasl ships OAUTHBEARER but not XOAUTH2) wired into the existingmail.Dial/SendSMTPauth branch. Nothing in Phases 1–2 blocks it.
Live validation (real Gmail account, app password)
A real personal Gmail account over verified TLS (imap.gmail.com:993, smtp.gmail.com:465),
authenticating with a Gmail app password via the existing password auth:
list: returned real INBOX headers (newest-first),has_attachmentscorrect.get: returned the full decoded plain-text body of a Gmail message.search:--from/--subject-containsnarrowed correctly server-side.send: delivered a message tome@stevecliff.com—{"sent":true}, exit 0.- Round-trip: a self-addressed send arrived and was found via IMAP
searchon the first poll — full SMTP-out → IMAP-in proof. - All over emcli's existing code; the app password is sealed at rest in the encrypted DB.
Gmail setup (app password)
- Enable 2-Step Verification on the Google account (required — the app-passwords page is hidden otherwise).
- Create a 16-character app password at https://myaccount.google.com/apppasswords (name it e.g. "emcli").
- Enable IMAP in Gmail: Settings → Forwarding and POP/IMAP → Enable IMAP.
- Add the account (app password is entered as the password; spaces are stripped):
emcli account add --name gmail --mode RW \ --imap-host imap.gmail.com --imap-port 993 --imap-security tls \ --smtp-host smtp.gmail.com --smtp-port 465 --smtp-security tls \ --username you@gmail.com --password '<16-char-app-password>'
App passwords are revoked by a main-password change or disabling 2FA; regenerate and re-run
account add if that happens.
Code changes
None. The speculative OAuth store fields/tests started early in the session were reverted; the working tree is byte-for-byte the Phase 2 code plus this document. Full suite remains green.
Known limitations / deferred
- OAuth2 (SPEC §10) — deferred as above; revisit for multi-user/provider or a verified app.
- Phase 4 — admin TUI +
doctor— unchanged; next up. - Carry-over Minor items from Phase 1 remain open.