pizauth is a simple program for requesting, showing, and refreshing OAuth2 access tokens. pizauth is formed of two components: a persistent server which interacts with the user to request tokens, and refreshes them as necessary; and a command-line interface which can be used by programs such as fdm and msmtp to authenticate with OAuth2.
pizauth's configuration file is ~/.config/pizauth.conf
. You need to specify
at least one account
, which tells pizauth how to authenticate against a
particular OAuth2 setup. Most users will also want to receive asynchronous
notifications of authorisation requests and errors, which requires setting
auth_notify_cmd
and error_notify_cmd
.
At a minimum you need to find out from your provider:
offline_access
scope./
characters). The default value of http://localhost/
suffices in most instances.Some providers allow you to create Client IDs and Client Secrets at will (e.g. Google). Some providers sometimes allow you to create Client IDs and Client Secrets (e.g. Microsoft Azure but allow organisations to turn off this functionality.
For example, to create an account called officesmtp
which obtains OAuth2
tokens which allow you to read email via IMAP and send email via Office365's
servers:
account "officesmtp" {
auth_uri = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize";
token_uri = "https://login.microsoftonline.com/common/oauth2/v2.0/token";
client_id = "..."; // Fill in with your Client ID
client_secret = "..."; // Fill in with your Client secret
scopes = [
"https://outlook.office365.com/IMAP.AccessAsUser.All",
"https://outlook.office365.com/SMTP.Send",
"offline_access"
];
// You don't have to specify login_hint, but it does make authentication a
// little easier.
auth_uri_fields = { "login_hint": "email@example.com" };
}
As standard, pizauth displays authorisation URLs and errors on stderr. If you want to use pizauth in the background, it is easy to miss such output. Fortunately, pizauth can run arbitrary commands to alert you that you need to authorise a new token, in essence giving you the ability to asynchronously display notifications. There are two main settings:
auth_notify_cmd
notifies users that an account needs authenticating. The
command is run with two environment variables set:
PIZAUTH_ACCOUNT
is set to the account name to be authorised.PIZAUTH_URL
is set to the authorisation URL.error_notify_cmd
notifies users of errors. The command is run with two
environment variables set:
PIZAUTH_ACCOUNT
is set to the account name to be authorised.PIZAUTH_MSG
is set to the error message.For example to use pizauth with notify-send
:
auth_notify_cmd = "if [[ \"$(notify-send -A \"Open $PIZAUTH_ACCOUNT\" -t 30000 'pizauth authorisation')\" == \"0\" ]]; then open \"$PIZAUTH_URL\"; fi";
error_notify_cmd = "notify-send -t 90000 \"pizauth error for $PIZAUTH_ACCOUNT\" \"$PIZAUTH_MSG\"";
In this example, notify-send
is used to open a notification with a "Open
<account>" button; if that button is clicked, then the authorisation URL
is opened in the user's default web browser.
You need to start the pizauth server (alternatively, start pizauth.service
,
see systemd-unit below):
$ pizauth server
and configure software to request OAuth2 tokens with pizauth show officesmtp
.
The first time that pizauth show officesmtp
is executed, it will print an
error to stderr that includes an authorisation URL (and, if auth_notify_cmd
is set, it will also execute that command):
$ pizauth show officesmtp
ERROR - Token unavailable until authorised with URL https://login.microsoftonline.com/common/oauth2/v2.0/authorize?access_type=offline&code_challenge=xpVa0mDzvR1Ozw5_cWN43DsO-k5_blQNHIzynyPfD3c&code_challenge_method=S256&scope=https%3A%2F%2Foutlook.office365.com%2FIMAP.AccessAsUser.All+https%3A%2F%2Foutlook.office365.com%2FSMTP.Send+offline_access&client_id=<your Client ID>&redirect_uri=http%3A%2F%2Flocalhost%3A14204%2F&response_type=code&state=%25E6%25A0%25EF%2503h6%25BCK&client_secret=<your Client Secret>&login_hint=email@example.com
The user then needs to open that URL in the browser of their choice and
complete authentication. Once complete, pizauth will be notified, and shortly
afterwards pizauth show officesmtp
will start showing a token on stdout:
$ pizauth show officesmtp
DIASSPt7jlcBPTWUUCtXMWtj9TlPC6U3P3aV6C9NYrQyrhZ9L2LhyJKgl5MP7YV4
Note that:
pizauth show
does not block: if a token is not available it will fail;
once a token is available it will succeed.pizauth show
can print OAuth2 tokens which are no longer valid. By
default, pizauth will continually refresh your token, but it may
eventually become invalid. There will be a delay between the token
becoming invalid and pizauth realising that has happened and notifying you
to request a new token.pizauth's usage is:
pizauth dump
pizauth refresh [-u] <account>
pizauth reload
pizauth restore
pizauth server [-c <config-path>] [-d]
pizauth show [-u] <account>
pizauth shutdown
Where:
pizauth refresh
tries to obtain a new access token for an account. If an
access token already exists, a refresh is tried; if an access token doesn't
exist, a new request is made.pizauth reload
causes the server to reload its configuration (this is
a safe equivalent of the traditional SIGHUP
mechanism).pizauth server
starts a new instance of the server.pizauth show
displays an access token, if one exists, for account
. If an
access token does not exist, a new request is initiated.pizauth shutdown
asks the server to shut itself down.pizauth dump
and pizauth restore
are explained in the
Persistence section below.
Once you have set up pizauth, you will then need to set up the software which needs access tokens. This section contains example configuration snippets to help you get up and running.
In these examples, text in chevrons (like <this>
) needs to be edited to match
your individual setup. The examples assume that pizauth
is in your $PATH
:
if it is not, you will need to substitute an absolute path to pizauth
in
these snippets.
In your configuration file (typically ~/.config/msmtp/config
):
account <account-name>
auth xoauth2
host <smtp-server>
protocol smtp
from <email-address>
user <username>
passwordeval pizauth show <pizauth-account-name>
Ensure you have the xoauth2 plugin for cyrus-sasl installed, and then use
something like this for the IMAP account in ~/.mbsyncrc
:
IMAPAccount <account-name>
Host <imap-server>
User <username>
PassCmd "pizauth show <pizauth-account-name>"
AuthMechs XOAUTH2
Each provider you wish to authenticate with will have its own settings it requires of you. These can be difficult to find, so examples are provided in this section. Caveat emptor: these settings will not work in all situations, and providers have historically required users to intermittently change their settings.
You may need to create your own client ID and secret by registering with Microsoft's identity platform.
account "<your-account-name>" {
auth_uri = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize";
auth_uri_fields = { "login_hint": "<your-email-address>" };
token_uri = "https://login.microsoftonline.com/common/oauth2/v2.0/token";
client_id = "<your-client-id>";
client_secret = "<your-client-secret>";
scopes = [
"https://outlook.office365.com/IMAP.AccessAsUser.All",
"https://outlook.office365.com/POP.AccessAsUser.All",
"https://outlook.office365.com/SMTP.Send",
"offline_access"
];
}
You may need to create your own client ID and secret via the credentials tab of the Google Cloud Console.
account "<your-account-name>" {
auth_uri = "https://accounts.google.com/o/oauth2/auth";
auth_uri_fields = {"login_hint": "<your-email-address>"};
token_uri = "https://oauth2.googleapis.com/token";
client_id = "<your-client-id>";
client_secret = "<your-client-secret>";
scopes = ["https://mail.google.com/"];
}
You may need to create your own client ID and secret via the get involved tab of the Miele Developer site.
No scopes are needed.
account "<your-account-name>" {
auth_uri = "https://api.mcs3.miele.com/thirdparty/login/";
token_uri = "https://api.mcs3.miele.com/thirdparty/token/";
client_id = "<your-client-id>";
client_secret = "<your-client-secret>";
}
You can run pizauth on a remote machine and have your local machine
authenticate that remote existence with ssh -L
. pizauth contains a small HTTP
server used to receive authentication requests. By default the HTTP server
listens on a random port, but it is easiest in this scenario to fix a port with
the global http_listen
option:
http_listen = "127.0.0.1:<port-number>";
account "..." { ... }
Then on your local machine (using the same <port-number>
as above run ssh
:
ssh -L 127.0.0.1:<port-number>:127.0.0.1:<port-number> <remote>
Then on the remote machine start pizauth server
and then `pizauth show