Configuring aerc
I finally migrated from mutt
to aerc
for my TUI-based email needs. This is how I set up authentication.
Gmail
There are two ways to authenticate to Gmail: using an application password and using OAuth. The former is not ideal because the access is scoped to the entire Google account rather than just reading and writing email. The latter is not ideal because it’s difficult to set up, but I did it that way so wanted to write it down somewhere.
Generate an OAuth Token
Visit console.cloud.google.com
and create a new project with a sensible name (e.g. “aerc”) and unique project ID.
Then under “APIs and services”, we need to create a credential and OAuth consent screen, in reverse order. The consent screen is cosmetic, no need to add any scopes, just fill in the mandatory fields and include your own account as a test user. Once done, create an OAuth credential of type “Desktop”.
Generate a Refresh Token
Now we have an OAuth client ID and client secret.
This authenticates the application, not an end user; we have to now authenticate an end user (ourself) to the application with the correct scope.
One way to do this is to run auth-source-xoauth2
’s google-oauth
tool.
make ... ./oauth -client-id "{client_id}" -client-secret "{client_secret}" Visit the URL for the auth dialog: https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&... YYYY/MM/DD HH:MM:SS Got "/?state=state&code=...&scope=https://mail.google.com/" AccessToken: ... TokenType: Bearer RefreshToken: ... Expiry: ...
Build Account Configuration
We now have enough to construct aerc
’s source
URL. From aerc-imap(5)
,
source = <scheme>://<username>[:<password>]@<hostname>[:<port>]?[<oauth2_params>]
and since we’ll use imaps+oauthbearer
as the scheme which has token_endpoint
, client_id
, client_secret
and scope
as optional parameters, the URL will look like
imaps+oauthbearer://{username}:{refresh_token}@imap.gmail.com?token_endpoint=https%3A%2F%2Foauth2.googleapis.com%2Ftoken&client_id={client_id}&client_secret={client_secret}
where each variable above is URL-encoded, e.g. username%40gmail.com
for the username
.
This means the refresh_token
almost certainly has to be URL-encoded too. No need to set the port, we use the default of 993.
The outgoing
URL is almost the same (from aerc-smtp(5)
),
smtps+oauthbearer://{username}:{refresh_token}@smtp.gmail.com:465?token_endpoint=https%3A%2F%2Foauth2.googleapis.com%2Ftoken&client_id={client_id}&client_secret={client_secret}
where only the scheme, hostname and port changed. Again, no need to set the port, we use the default of 465 (for SMTPS, not 587 for STARTTLS).
One drawback of this is that secrets end up in the configuration file. This can be partially mitigated by using source-cred-cmd
and outgoing-cred-cmd
which will replace the password component of the URL (for us, the refresh_token
) with the standard out of the program we specify. For example,
source = imaps+oauthbearer://{username}@imap.gmail.com?token_endpoint=https%3A%2F%2Foauth2.googleapis.com%2Ftoken&client_id={client_id}&client_secret={client_secret} outgoing = smtps+oauthbearer://{username}@smtp.gmail.com?token_endpoint=https%3A%2F%2Foauth2.googleapis.com%2Ftoken&client_id={client_id}&client_secret={client_secret} source-cred-cmd = pass mail/oauth/mail.google.com | head -n 1 outgoing-cred-cmd = pass mail/oauth/mail.google.com | head -n 1 default = INBOX folders-sort = INBOX postpone = [Gmail]/Drafts from = {name} <{username}> cache-headers = true
where the refresh token is not URL-encoded, aerc
will do that for us now. This still leaves the client secret, which there’s nothing we can do about.
maths.tcd.ie
This is much simpler. Use
source = imaps://{username}@imap.maths.tcd.ie outgoing = smtp://{username}@smtp.maths.tcd.ie source-cred-cmd = pass mail/maths.tcd.ie | head -n 1 outgoing-cred-cmd = pass mail/maths.tcd.ie | head -n 1 from = {name} <{username}@maths.tcd.ie> default = INBOX copy-to = Sent cache-headers = true
where {username}
doesn’t include the domain (i.e. not like the Gmail configuration above).
References
There are a few other resources for this, such as Setting up Gmail on aerc, How to setup aerc with Gmail and OAuth2 and the aerc wiki. I found them helpful but I ended up deviating from them in different ways.