Many IMAP/SMTP clients, like msmtp,
fdm,
isync,
aerc,
neomutt or
mutt can use OAuth2 access tokens but lack the
ability to renew and/or authorize OAuth2 credentials. The purpose of
oama
is to provide these missing capabilities by acting as a kind of
smart password manager. In particular, access token renewal happens
automatically in the background transparent to the user.
The OAuth2 credentials are kept encrypted in a backend.
In Hawaii the word oama refers to juvenile goatfish.
-
GNU PG encrypted files. These files are kept in the
$XDG_STATE_HOME/oama
directory. If theXDG_STATE_HOME
environment variable is not set then it defaults to$HOME/.local/state
. -
A keyring service provided by any password manager with a FreeDesktop.org Secret Service compatible API. Some examples of such password managers are:
Invoking oama
without any arguments print a help message listing the
available commands:
oama - OAuth credential MAnager with store/lookup, renewal, authorization.
Usage: oama [--version] [-c|--config <config>] [--debug] COMMAND
Oama is an OAuth credential manager providing store/lookup, automatic renewal
and authorization operations. The credentials are stored either in the Gnome
keyring or in files encrypted by GnuPG. Oama is useful for IMAP/SMTP or other
network clients which cannot authorize and renew OAuth tokens on their own.
Available options:
-h,--help Show this help text
--version Show version
-c,--config <config> Configuration file
(default: "~/.config/oama/config.yaml")
--debug Print HTTP traffic to stdout
Available commands:
access Get the access token for email
show Show current credentials for email
renew Renew the access token of email
authorize Authorize OAuth2 for service/email
printenv Print the current runtime environment
template Print the default config template
More detailed help for individual commands can also be generated by appending
-h
after the command. Shell completion for bash
, zsh
and fish
shells
are provided.
Before oama
is fully operational you need to create the necessary
configuration files. See details in Configuration.
oama
has a simple configuration system. When you run oama
at the first
time it will create the initial config file config.yaml
in the
$XDG_CONFIG_HOME/oama
directory. If the XDG_CONFIG_HOME environment
variable is not set then it defaults to $HOME/.config
. You need to edit the
initially created config file. This YAML file is commented explaining your
options, just follow the instructions there.
First select the method of storing the OAuth credentials. Then configure the
services you are going to use. There are two kinds of services the builtin
ones which oama
already knows and the user configured ones. The current
builtin services are google
and microsoft
.
For a builtin service the minimum information you need to provide is
client_id
. When using the device code flow authorization method
client_secret
is not needed. Other authorization methods most likely need
client_secret
.
For user configured service there are a few more required config options. See the initially created config file for more details.
You can see all the configurable options in the services:
section of
the output of the oama printenv
command.
There are also client_id_cmd
and client_secret_cmd
config parameters if you
want to keep these parameters in a password manager.
client_secret = <my-client-secret>
# or alternatively get it from a password manager like pass
client_secret_cmd = |
pass email/my-app | head -1
Presumably you use only one of the methods but if both are present then the
*_cmd
variants get the priority.
For institutional accounts your organization should provide the
client_{id,secret}
pair regardless who is the service provider.
For personal accounts you can register your own client application at your
service provider and obtain a client_{id,secret}
pair.
- Microsoft: Register an application
- Google: Credentials page
If that is too much hassle then you can try to find and use one of the open
source email clients' client_{id,secret}
pair. Most of these desktop clients
are already registered at many service providers.
Invoke oama
with no login hint:
oama authorize google <you@company.email> --nohint
The default tenant
for a Microsoft account is common
which is also
included in the auth_endpoint
and token_endpoint
URLs. If you need to
use a different tenant
value then it is enough to specify only the tenant
field the *_endpoint
URLs will be automatically changed too.
Microsoft now also accepts authorization requests with device code flow what
you can invoke with the --device
option. In this case you need to provide client_id
only.
Invoke oama
using your proper organizational email:
oama authorize microsoft <you@company.email>
Then visit the http://localhost:<portnumber>/start
page to perform the steps
below:
- Click "Sign in with another account"
- Click "Sign-in options"
- Click "Sign in to an organization"
- Put in the correct domain name which matches your organization address above
- Log in with your credentials at the organization.
After configuration, you must run the authorize
command:
Usage: oama authorize <service> <email> [--nohint] [--device]
Authorize OAuth2 for service/email
Available options:
<service> Service name
<email> Email address
--nohint Don't pass login hint
--device Use OAuth device code flow (RFC 8628)
-h,--help Show this help text
That is an interactive process involving a browser since you need to login
and authorize access to your email account. oama
will lead you through this
process.
Install and configure oama
on the remote host. Chose a back-end, it can be
either GPG or KEYRING. Make sure that the back-end installed and works as
desired on the remote machine.
Pick a free, non-privileged <port-number>
and include
redirect_uri: http://localhost:<port-number>
into your service provider configuration section.
Login into the remote host using the command below:
ssh -L <port-number>:localhost:<port-number> <remote-host>
Start the authorization on the remote host as usual:
oama authorize <service> <email>
Then just follow the instructions and open the suggested URL in a browser running on your local machine.
All transactions and exceptions are logged to syslog
. If your OS using
systemd
you can inspect the log with a command like below:
journalctl --identifier oama --identifier msmtp --identifier fdm -e
Each release comes with a few precompiled static binaries
of oama
. Select the version you want to download from
releases.
For Archlinux users there is also a package on AUR: oama-bin
To build oama
from source you need a Haskell development environment,
with ghc 9.4.x
or higher. Either your platform's package system can provide
this or you can use ghcup. Once you have
the ghc
Haskell compiler and cabal
etc. installed, follow the steps
below:
git clone https://github.com/pdobsan/oama
cd oama
cabal update
There are two alternative methods to build oama
. One results in an executable
which uses FFI to external library API-s to access keyring
or gpg
encryption
services. The other method results in an executable which spawns
external utilities.
There is a justfile
for building using the
just command runner. Invoking just
without
arguments lists the available recipes.
Dependencies:
gpgme
Linux packagelibsecret
Linux packagegobject-introspection
Linux package
Build/install steps:
just secret-libs
just build # optional install invokes it
just install
Dependencies:
gnupg
Linux packagesecret-tool
utility, part oflibsecret
but in Debian a separate package.security
utility in macOS.
Build/install steps:
just secret-tools
just build # optional install invokes it
just install
oama
will be installed into either into ~/.local/bin/
or ~/.cabal/bin/
depending on ghc
-s local setup.
To test oama
without installing use the run
recipe. For example:
just run
just run printenv
just run 'authorize google johndoe@gmail.com'
Please, report any problems, questions, suggestions regarding oama
by opening
an issue or by starting a discussion.
-
Make sure that you are using the latest version of
oama
. -
Before opening an issue search old issues (both open and closed) and check whether similar problems have been raised or solved before.
-
Attach the complete output of the
oama printenv
command. Do not remove lines, get confidential values redacted by replacing them with<some explanation>
. In particular, indicate what kind ofclient_id/secret
you are using. For example,<my own app id registered with google>
. -
Indicate what kind of account(s) you are using that is who is the service provider and whether your account is personal or institutional.
-
Send also full error messages and related syslog entries. Even when
oama
was called by another program which could have hidden its error messages you might see them in the syslog.
The programs below solve similar problems as oama
does but have different
takes on them.
oama
is released under the 3-Clause BSD License, see the file
License.