Skip to content

Live Gmail connect

MAIL-254 / MAIL-255 / MAIL-256 add the Duckbill™ product path for connecting multiple Gmail identities. A signed-in user starts Google OAuth from /accounts; the callback persists one connected_accounts row per stable Google identity and stores access and refresh tokens only as encrypted provider_tokens.

Product path

  1. Sign in to Duckbill and open /accounts.
  2. Select Connect Gmail. The browser requests /api/providers/gmail/start.
  3. Google receives a PKCE authorization request for openid, email, and gmail.readonly.
  4. Google returns to /connect/gmail/callback.
  5. The server exchanges the code, reads the Google profile, upserts by (user, provider, provider identity), encrypts tokens, and returns only redacted account health.
  6. The browser returns to /accounts, where each authorized Gmail identity is a separate row.

Repeating the flow with another Google identity creates another Gmail account for the same Duckbill user. Reauthorizing the same Google identity updates that account rather than duplicating it.

Host configuration

Set these names independently on preview and production. Never commit values.

VariablePurpose
GOOGLE_CLIENT_IDGoogle OAuth web client
GOOGLE_CLIENT_SECRETGoogle OAuth client secret
GMAIL_REDIRECT_URIExact callback URL, such as https://duckbill-dev.jasonkoch.io/connect/gmail/callback

The common DATABASE_URL, TOKEN_ENCRYPTION_KEY, and SESSION_SECRET requirements still apply. Gmail routes return 503 until all required names are configured.

Safety and isolation

The authorization request rejects full mail.google.com, gmail.send, and gmail.compose scopes. ENABLE_SEND and ENABLE_DELETE remain false. Provider tokens never enter ia_session, API responses, Jira, logs, or docs.

MAIL-257 keeps account loops independent through runIndependentAccountLoops. An injected Gmail provider failure is reported for that account while Graph processing continues.