Ambient email should use OAuth (Gmail API), not a raw SMTP/IMAP password
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 19.9k
- Forks
- 2.3k
- Avg merge
- 2d 7h
- Merged PRs (30d)
- 30
Description
Problem
Ambient mode's email integration ([safety] section) currently only supports raw SMTP/IMAP with a password:
email_enabled
email_smtp_host
email_smtp_port
email_from
email_password <- plaintext password field, confirmed via `strings` on the jcode binary
email_imap_host
email_imap_port
email_reply_enabled
This is the wrong auth model. jcode already does OAuth for every model provider it talks to (Claude, OpenAI, Gemini, Copilot, Cursor — all confirmed in the binary's credential-handling strings, e.g. ClaudeOAuth, Claude Code (macOS Keychain), OpenCodeAnthropicAuth). Email should follow the same pattern rather than falling back to a raw mailbox password, for two reasons:
- Security: SMTP/IMAP app-passwords are long-lived, broad-scope credentials with no built-in expiry/revocation UX. OAuth tokens are scoped, refreshable, and revocable from the provider's own security settings without touching jcode's config at all.
- It's redundant work: users who want ambient email almost certainly already have Gmail (or another OAuth-capable provider) wired up somewhere in their toolchain. Re-deriving a plaintext-password flow for jcode specifically, when an OAuth-based flow already exists and is already trusted, is unnecessary extra surface area — both to build and to secure.
Request
Add an OAuth-based email backend for ambient (Gmail first, since it's the most common case), reusing jcode's existing OAuth machinery rather than introducing a new plaintext-secret field:
jcode login --provider gmail-ambient(or fold into the existing/login/account picker flow) — standard OAuth device/browser flow, same UX asjcode login google/jcode login geminialready use.- Store the resulting OAuth token the same way jcode already stores Claude/OpenAI OAuth tokens (macOS Keychain via
security-framework, or jcode's existing multi-accountauth.jsonpattern — whichever the current provider-auth code path already uses, this should just be one more account type in that same system, not new infrastructure). - Ambient's email send/receive path calls the Gmail API (
gmail.send,gmail.readonly/gmail.modifyscopes) using the stored OAuth token, instead of opening a raw SMTP/IMAP socket with a password. - Keep the raw SMTP/IMAP path as a fallback for non-Gmail providers that don't support OAuth, but make OAuth the default/first-class path when the user's email is Gmail (detectable from the domain, or just prompt "Gmail (recommended, OAuth) / Other (SMTP/IMAP with app password)" during setup).
Why Gmail specifically
Most users pursuing this (including us) already have a working OAuth-based Gmail integration pattern in their broader toolchain — a token-refresh helper that hands back a valid access token on demand, used for both send and search/read. jcode's ambient email feature could call an equivalent flow directly rather than requiring IMAP/SMTP credentials at all. This also sidesteps the "where do we securely store email_password" problem entirely (see related: encrypted-storage-for-config-secrets, but that's now a secondary concern if OAuth eliminates the password requirement for the common case).
Why this matters
- Avoids introducing a new plaintext-password credential surface in jcode when a scoped, revocable, already-trusted OAuth pattern is available and jcode already has the infrastructure for it.
- Matches user expectation: everything else jcode authenticates to (model providers) uses OAuth; email being the one exception via raw password is inconsistent and a downgrade in security posture relative to the rest of the app.
- Removes the current blocker entirely for Gmail users (which is likely the majority) rather than just making the plaintext password "safer to store" (encrypted-at-rest is still worse than not needing a long-lived password at all).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Begin with the existing jcode login --provider google/gemini and /login account-picker flows, then trace ambient email's send/receive path and its [safety] SMTP/IMAP configuration. Confirm how existing provider OAuth tokens are stored and which Gmail API scopes are needed. Done means Gmail users authenticate through the existing flow and ambient send/receive uses that token, while non-Gmail SMTP/IMAP remains available.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- google-cloud, rust
- Domain
- api, authentication, backend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100