Gmail OAUTH2 for Gnus nnimap, reliably
Google app passwords are a faster setup but seem to be less trusted by Google. I ran into frequent trouble authenticating Gnus with them this year. OAUTH2 has been fully reliable to me since summer 2025.
Requirements
oauth2
(use-package oauth2
:demand t)
auth-source-xoauth2-pluginpackage1
(use-package auth-source-xoauth2-plugin
:demand t
:config
(auth-source-xoauth2-plugin-mode)) ;; must be active before calling "Gnus"
- GPG integrated with Emacs (see Emacs manual
epa) - GPG key available to Emacs
Setup the token store
plstore will use your GPG key to encrypt the file. Get your keyid:
gpg --list-keys --keyid-format long
And substitute <keyid> for yours:
(use-package plstore
:ensure nil
:demand t
:config
(add-to-list 'plstore-encrypt-to "<keyid>"))
Auth supports JSON files. Add one to auth-sources. Later you will add your Gmail details to this .authinfo.json.gpg file.
(setq auth-sources
(list
'default
(file-name-concat your-auth-dir ".authinfo.json.gpg")
(file-name-concat your-auth-dir ".authinfo.gpg"))
)
Add your account to Gnus’ nnimap method
(setq gnus-select-method
(nnimap "<name>"
(nnimap-address "imap.gmail.com")
(nnimap-server-port 993)
(nnimap-stream ssl)
(nnimap-user "<email>@gmail.com")
(nnimap-authenticator xoauth2)
(nnimap-expunge immediately)
(nnmail-expiry-target "nnimap+<name>:[Gmail]/Trash")))
Create an “app” in Google developer console
Generate clients in the Google developer console. You need to create one client per Gmail mailbox you want in Gnus. They can all (up to 100) go under the same Google developer account. Consult the web for up-to-date guidance on the process.2
It is important that you publish your “app” even with no intention of validating. If you do not the tokens will expire after a week or so. After publishing tokens are renewable indefinitely even without validation, there’s simply a warning and some extra clicks on the Google OAuth page.
Insert client-id and client-secret from Google Cloud into authinfo.gpg.json. One per mail account.
{
"machine": "<your_imap_address_or_email>",
"login": "<your_email>",
"port": "imaps",
"auth": "xoauth2",
"auth-url": "https://accounts.google.com/o/oauth2/auth",
"token-url": "https://accounts.google.com/o/oauth2/token",
"client-id": "<the_client_id_from_your_app>",
"client-secret": "<the_client_secret_from_your_app>",
"redirect-uri": "https://oauth2.dance/",
"scope": "https://mail.google.com"
},
First login
Finally, launch Gnus. Open the OAuth URL at the echo prompt in your browser. Login and authorize Gnus. After you’re done Google will redirect you to https://oauth2.dance which will not resolve but contain in the URL parameters the string you must insert into the prompt. Copy it and paste into Gnus. Hit return. Should everything be correct the token will be stored and encrypted automatically. You will not have to repeat this process for as long as the token is valid.
Done.