Gmail
Send through your Gmail or Google Workspace account with a one-time browser sign-in and send-only access.
Mailfire can send through the Gmail API of a personal Gmail or Google Workspace account. You do not need SMTP settings, an app password, or your own Google Cloud project.
Availability
Mailfire’s Google app is awaiting Google’s verification. Until it is verified, only accounts registered as testers
can sign in, and released versions up to 0.3.0 do not include the Gmail provider. Developers can use their own
Desktop OAuth client by setting MAILFIRE_GMAIL_CLIENT_ID and MAILFIRE_GMAIL_CLIENT_SECRET.
Set up
Select the provider in your configuration file and authorize Mailfire once:
[sending]
provider = "gmail"
from = "My Name <me@gmail.com>"
mailfire auth login --provider gmail
mailfire validate
On Google’s consent page, tick the checkbox to let Mailfire send email on your behalf: Google lists each permission separately, and without this one the login fails with an explanation and nothing is saved.
auth login opens Google’s consent page in your browser and waits for the redirect to a temporary local address
(http://127.0.0.1:<port>/oauth2/callback). The flow uses PKCE and a random state value; requests to the local
address that do not carry this state are refused.
Mailfire requests two scopes:
gmail.send— send email as you. Mailfire cannot read, list, or delete your mail.openid— only an opaque, stable account ID. Mailfire uses it to make sure a deferred message is never resent from a different Google account after you sign in again. It includes no name, email address, or other profile data.
The access token, its expiry, the refresh token, and the account ID are stored in an owner-only (0600) file:
~/.config/mailfire/gmail-credentials.json, or %APPDATA%\mailfire\gmail-credentials.json on Windows. Change it with
credentials in [gmail] or MAILFIRE_GMAIL_CREDENTIALS. Do not commit or copy this file: the refresh token is a
credential. Writes are atomic and locked, so concurrent sends and refreshes cannot corrupt it.
mailfire auth status --provider gmail shows whether credentials exist; mailfire auth logout --provider gmail
removes the local file. Logging out does not revoke Mailfire’s access at Google; do that at
https://myaccount.google.com/permissions.
The privacy policy describes how Mailfire handles your Google user data.
Token lifetime
Access tokens usually last about one hour. Mailfire refreshes them automatically before a send when they expire within five minutes. Sends, resends, and refreshes never open a browser or prompt; if the authorization is gone, they fail with exit code 3 and name the login command.
Refresh tokens are long-lived, not permanent. Google can expire a refresh token that has not been used for six months, and revocation, password or security changes, Workspace policy, or a time-limited grant can require another browser login at any time.
SSH and headless servers
Run login on the server with --no-browser and a fixed port. Mailfire prints the consent URL and an SSH command:
mailfire auth login --provider gmail --no-browser --port 8765
On the computer with your browser, forward the port, then open the printed URL there:
ssh -L 8765:127.0.0.1:8765 user@server
Google redirects your browser to 127.0.0.1:8765, and the tunnel delivers the callback to Mailfire on the server.
Google’s device-code flow does not support Gmail scopes, and Mailfire does not use the deprecated copy-and-paste
out-of-band flow.
If the server forbids port forwarding, use --manual --port 8765. After consent, the browser fails to load the
callback page; copy the complete URL from its address bar and paste it into Mailfire. This is still the loopback flow
with PKCE and state validation. Never copy refresh tokens through chat or shell history.
Keep authorization alive
For infrequent senders, schedule a real token refresh monthly. It exchanges the refresh token even when the cached access token is still valid, and it does not send mail, read mail, alter the queue, or consume notification cooldowns:
# Refresh Gmail authorization on the first day of each month at 09:15.
# Replace the path with the output of: command -v mailfire
15 9 1 * * /usr/local/bin/mailfire auth refresh --provider gmail
- On Apple Silicon with Homebrew the path is usually
/opt/homebrew/bin/mailfire. - Run the job as the same OS user, with the same configuration, as your sends. Cron has a minimal environment and
PATH; pass-c /path/to/mailfire.confif your configuration is not in a default location. - On Windows, create a Task Scheduler task that runs
mailfire auth refresh --provider gmailmonthly under the same user account. - Mailfire’s credential file needs no unlocked desktop keychain, so it works on headless systems.
- Monitor the job’s exit status through an independent channel (not by Gmail mail alone): 0 refreshed, 3 not authorized (log in again), 4 temporary failure (retry later), 2 configuration problem.
Refreshing prevents inactivity expiry only while it succeeds. It cannot prevent revocation, password-related invalidation, account-policy changes, time-limited grants, or other Google authorization failures. External OAuth apps left in Google’s “Testing” status issue refresh tokens for Gmail scopes that expire after seven days; refreshing does not extend that limit.
Sending behavior and limits
- Sender: Gmail sends only as the authenticated account or one of its configured “Send mail as” aliases. If
fromis neither, Gmail replaces it with the account’s address; Mailfire cannot check aliases without access to your Gmail settings, which it does not request. - Bcc: Gmail takes the recipients, Bcc included, from the message and removes the Bcc header before delivery, so recipients do not see Bcc addresses.
- Limits: messages may be at most 25 MB. Gmail enforces daily sending limits per account (lower for new and
free accounts); exceeding them, and other temporary errors (HTTP 429 and 5xx), defer the message for
mailfire resend. - Test mode: Gmail has no Mailgun-style validation-only mode.
--testis rejected (exit 1) rather than delivering real email; usemailfire validateto check the authorization and--previewto check rendering. - Deferred messages keep the Google account ID. They are resent only from the same account; after a login with a
different account they are kept but not sent (
blocked (account mismatch)) until the original account is authorized again.