As I mentioned before, I am a heavy terminal user, including viewing and replying emails with it. Mutt is my email client. Once you have setup your 2 factor authentication with Google, you won’t be able to access your Gmail using IMAP with your password, you’ll have to generate a specific password for the so called “Less Secure Apps”. There is a problem with that, if you use IMAP with less-secure-app password on your company account where “less secure app” is not allowed, you are probably stuck.
In this tutorial, I am going to show you how to setup the Google recommended OAuth 2.0 way with Mutt.
Remember, the OAuth client setup should be an one-time step, it should be usable for your different email addresses on Gmail, that includes your work email if your employer choose Gmail as their email service provider, as long as you authorize permission during the OAuth App.
- Login to your google account, navigate to https://console.cloud.google.com/apis/credentials and if this page says anything API not enabled, enable it.
- In the credentials page, create a project.
- After creating the project, you should be able to go to the OAuth consent screen tab, put something recognizable in the application name, click save.
- Go back to “Credentials” page and click on “Create credentials” button and select OAuth client ID.
- Select other and click create. You’ll be given an OAuth client ID and secret. You can view the id and secret anytime.
Now you’ve setup an OAuth client, it is time for mutt configuration.
Download oauth2.py from GitLab: https://gitlab.com/muttmua/mutt/-/blob/master/contrib/mutt_oauth2.py and make it executable. You’ll need to run the command to generate an OAuth token.
Fill your Google App client id and secret here: https://gitlab.com/muttmua/mutt/-/blob/5347d1c5c0f529ad7e1464ce9f1716d54ed9c31a/contrib/mutt_oauth2.py#L61 and Line 62.
Execute the following command to authorize yourself.
mutt_oauth2.py [email protected] --verbose --authorize
Open the web browser with the link given and authenticate yourself, login and grant permission.
The way I manage my files under
. |-- accounts | |-- gmail.asc | |-- account2.asc | |-- account3.asc |-- mailcap |-- muttrc |-- oauth2.py ...
The muttrc master config file only manage generic stuff such as header and format stuff, it also has some macro to map function keys to switch accounts. The actual accounts are under
~/.mutt/accounts folder with GPG encryption in ASCII.
The original gmail file should only contain account related stuff, such as IMAP and SMTP configuration. At the core the login lines should be:
set imap_user = "[email protected]" set imap_authenticators="oauthbearer" set imap_oauth_refresh_command="~/.mutt/mutt_oauth2.py ~/.mutt/tokens/gmail" set smtp_authenticators="oauthbearer" set smtp_oauth_refresh_command="~/.mutt/mutt_oauth2.py ~/.mutt/tokens/gmail" set smtp_url = "smtp://[email protected]@smtp.gmail.com:587/" set from = "[email protected]" set realname = "Your Name" set signature = "~/.mutt/signatures/mysig" # Basic config, you can leave this as is set folder = "imaps://imap.gmail.com" set spoolfile = "+INBOX" set imap_check_subscribed set postponed = "+[Gmail]/Draft" set record = "" set header_cache=~/.mutt/cache/headers
You should be able to use mutt to view/send emails via Gmail using OAuth 2.0!
Thanks for the article but what about those GPG “asc” files? Can you elaborate a little bit on that or provide some resource? thanks.
The asc files are generated by the following command:
gpg2 -e -r "[email protected]" --armor
The purpose of GPG is to not store plaintext info on my local disk
You will need to setup your GPG profile in order to use gpg.
Hi, thanks for this neat guide you wrote. The access token I received is only valid for 3599 seconds; how do I get a permanent access token, so I could write it in the mutt config file without having to manually change the access token every time it expires?
Sorry, I just noticed that you put the refresh token in the config file, not the access token itself. I take it, this is all that’s needed? If the access token expires, the same command will retrieve a new access token automatically?
Hi. Great writeup. There is a mutt_oauth2.py script you can use now, which works with python3 (finally I can get rid of python2). I’m using it, and seems to work fine. https://gitlab.com/muttmua/mutt/-/blob/master/contrib/mutt_oauth2.py.README
Thanks for the Python3 update!
Thanks for a great guide.
Are there any security issues with storing the client_secret and/or refresh token in a .dotfiles repo on GitHub.
Hi Google is now saying the “out of band” Oauth will be deprecated in late 2022. Any ideas on how to keep Mutt working with Gmail?
It is 2023 and I am still using it fine.
Leave a comment