{"id":32210085,"url":"https://github.com/pdobsan/oama","last_synced_at":"2026-03-07T23:31:44.573Z","repository":{"id":37762979,"uuid":"501036528","full_name":"pdobsan/oama","owner":"pdobsan","description":"OAuth credential Manager","archived":false,"fork":false,"pushed_at":"2025-08-29T10:50:56.000Z","size":349,"stargazers_count":237,"open_issues_count":6,"forks_count":19,"subscribers_count":11,"default_branch":"main","last_synced_at":"2026-02-23T21:29:11.526Z","etag":null,"topics":["email","imap","oauth2","smtp","utility"],"latest_commit_sha":null,"homepage":"","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pdobsan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-06-07T23:38:47.000Z","updated_at":"2026-02-16T23:50:11.000Z","dependencies_parsed_at":"2024-06-04T21:35:26.718Z","dependency_job_id":"dd0c1e04-5533-401c-abf0-e3ee3e27e631","html_url":"https://github.com/pdobsan/oama","commit_stats":null,"previous_names":["pdobsan/oama","pdobsan/mailctl"],"tags_count":50,"template":false,"template_full_name":null,"purl":"pkg:github/pdobsan/oama","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pdobsan%2Foama","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pdobsan%2Foama/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pdobsan%2Foama/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pdobsan%2Foama/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pdobsan","download_url":"https://codeload.github.com/pdobsan/oama/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pdobsan%2Foama/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30237329,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-07T23:24:20.706Z","status":"ssl_error","status_checked_at":"2026-03-07T23:21:10.486Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["email","imap","oauth2","smtp","utility"],"created_at":"2025-10-22T06:25:03.667Z","updated_at":"2026-03-07T23:31:44.545Z","avatar_url":"https://github.com/pdobsan.png","language":"Haskell","funding_links":[],"categories":["\u003ca name=\"networking\"\u003e\u003c/a\u003eNetworking"],"sub_categories":[],"readme":"# **oama** - OAuth credential MAnager\n\n\u003cp align=\"center\" width=\"100%\"\u003e\n  \u003cimg width=\"22%\" src=\"oama-fish.jpg\" alt=\"🐟\"\u003e\n\u003c/p\u003e\n\n## Synopsis\n\nMany IMAP/SMTP clients, like [msmtp](https://marlam.de/msmtp/),\n[fdm](https://github.com/nicm/fdm),\n[isync](http://isync.sourceforge.net/),\n[aerc](https://aerc-mail.org/),\n[neomutt](https://github.com/neomutt/neomutt) or\n[mutt](http://www.mutt.org/) can use OAuth2 access tokens but lack the\nability to renew and/or authorize OAuth2 credentials. The purpose of\n`oama` is to provide these missing capabilities by acting as a kind of\nsmart password manager. In particular, access token renewal happens\nautomatically in the background transparent to the user.\n\n`oama` runs on Linux, macOS and BSD Unix type systems. Both `x86_64` and `arm64/aarch64`\nplatforms are supported.\n\nThe word *oama* refers to *juvenile goatfish* in Hawaii, see the logo.\n\n### Backends and Security\n\nThe managed OAuth credentials are kept in various **encrypted backends**.\n`oama` can use any of the backends below:\n\n- [GNU PG](https://www.gnupg.org/) **encrypted files**. These files are kept\n  in the `$XDG_STATE_HOME/oama` directory. If the `XDG_STATE_HOME`\n  environment variable is not set then it defaults to `$HOME/.local/state`.\n\n- **Keyrings** provided by any password manager with a\n  FreeDesktop.org Secret Service compatible API. *Some examples* of such\n  password managers are:\n\n    - [Gnome keyring](https://wiki.gnome.org/Projects/GnomeKeyring/)\n    - [KDE Wallet Manager](https://apps.kde.org/kwalletmanager5/)\n    - [KeePaasXC](https://keepassxc.org/)\n\nAdditionally, `oama` can be configured to obtain the *client ID and secret*\nassociated with an OAuth account from a password manager so these pieces of\nsensitive information don't need to be in the config file.\n\n#### Operational security\n\n[Proof Key for Code Exchange (PKCE)](https://datatracker.ietf.org/doc/html/rfc7636)\nis used during authorization. Use of PKCE is recommended both\n[by Google](https://developers.google.com/identity/protocols/oauth2/native-app?hl=en)\nand\n[by Microsoft](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow).\nPKCE is required in the\n[new OAuth 2.1 draft](https://www.ietf.org/archive/id/draft-ietf-oauth-v2-1-13.html#name-authorization-code-security).\n\nTo avoid CSRF attacks `oama` uses a random `state value` to be maintained during\nthe authorization session. Also, as a default, a dynamically generated random\n`redirect_uri` is used so that cannot be leaked through the config file.\n\n## Usage\n\nInvoking `oama` without any arguments print a help message listing the\navailable commands:\n\n    oama - OAuth credential MAnager with store/lookup, renewal, authorization.\n\n    Usage: oama [-V|--version] [-c|--config \u003cconfig\u003e] COMMAND\n\n      Oama is an OAuth credential manager providing store/lookup, automatic renewal\n      and authorization operations. The credentials are stored either by a keyring\n      service or in files encrypted by GnuPG. Oama is useful for IMAP/SMTP or other\n      network clients which cannot authorize and renew OAuth tokens on their own.\n\n    Available options:\n      -h,--help                Show this help text\n      -V,--version             Show version\n      -c,--config \u003cconfig\u003e     Configuration file\n                               (default: \"~/.config/oama/config.yaml\")\n\n    Available commands:\n      access                   Get the access token for email\n      show                     Show current credentials for email\n      renew                    Renew the access token of email\n      authorize                Authorize OAuth2 for service/email\n      printenv                 Print the current runtime environment\n      template                 Print the default config template\n\nMore detailed help for individual commands can also be generated by appending\n`-h` after the command. Shell completion for `bash`, `zsh` and `fish` shells\nare provided.\n\nBefore `oama` is fully operational you need to create the necessary\nconfiguration files. See details in [Configuration](#configuration).\n\n## Configuration\n\n`oama` has a simple configuration system. When you run `oama` at the first\ntime it will create the initial config file `config.yaml` in the\n`$XDG_CONFIG_HOME/oama` directory. If the XDG_CONFIG_HOME environment\nvariable is not set then it defaults to `$HOME/.config`. You need to edit the\ninitially created config file. This YAML file is commented explaining your\noptions, just follow the instructions there.\n\nFirst select the method of storing the OAuth credentials. Then configure the\nservices you are going to use. There are two kinds of services the *builtin*\nones which `oama` already knows and the *user configured* ones. The current\n*builtin* services are `google` and `microsoft`.\n\nFor a *builtin* service the minimum information you need to provide is\n`client_id`. When using the *device code flow* authorization method\n`client_secret` is not needed. Other authorization methods most likely need\n`client_secret`.\n\nFor *user configured* service there are a few more required config options. See\nthe initially created config file for more details.\n\nYou can see **all the configurable options** in the `services:` section of\nthe output of the `oama printenv` command.\n\n### Application `client_id` and `client_secret`\n\nThere are also `client_id_cmd` and `client_secret_cmd` config parameters if you\nwant to keep these parameters in a password manager.\n\n    client_secret = \u003cmy-client-secret\u003e\n    # or alternatively get it from a password manager like pass\n    client_secret_cmd = |\n      pass email/my-app | head -1\n\nPresumably you use only one of the methods but if both are present then the\n`*_cmd` variants get the priority.\n\nFor institutional accounts your organization should provide the\n`client_{id,secret}` pair regardless who is the service provider.\n\nFor personal accounts you can register your own *client application* at your\nservice provider and obtain a `client_{id,secret}` pair.\n\n- Microsoft: [Register an application](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app)\n- Google: [Credentials page](https://console.developers.google.com/apis/credentials)\n\nIf that is too much hassle then you can try to find and use one of the open\nsource email clients' `client_{id,secret}` pair. Most of these desktop clients\nare already registered at many service providers.\n\n### Google Organizational Account\n\nInvoke `oama` with no login hint:\n\n    oama authorize google \u003cyou@company.email\u003e --nohint\n\n### Microsoft accounts\n\nThe default `tenant` for a Microsoft account is `common` which is also\nincluded in the `auth_endpoint` and `token_endpoint` URLs. If you need to\nuse a different `tenant` value then it is enough to specify only the `tenant`\nfield the `*_endpoint` URLs will be automatically changed too.\n\nMicrosoft now primarily expects authorization requests with *device code flow* what\nyou can invoke with the `--device` option. In this case you need to provide `client_id`\nonly.\n\n#### Microsoft Organizational Account\n\nInvoke `oama` using your proper organizational email:\n\n    oama authorize microsoft \u003cyou@company.email\u003e --device\n\nThen visit the `http://localhost:\u003cportnumber\u003e/start` page to perform the steps\nbelow:\n\n - Click \"Sign in with another account\"\n - Click \"Sign-in options\"\n - Click \"Sign in to an organization\"\n - Put in the correct domain name which matches your organization address above\n - Log in with your credentials at the organization.\n\n## Authorization\n\nAfter configuration, you must run the `authorize` command:\n\n    Usage: oama authorize \u003cservice\u003e \u003cemail\u003e [--nohint] [--device]\n\n      Authorize OAuth2 for service/email\n\n    Available options:\n      \u003cservice\u003e                Service name\n      \u003cemail\u003e                  Email address\n      --nohint                 Don't pass login hint\n      --device                 Use OAuth device code flow (RFC 8628)\n      -h,--help                Show this help text\n\nThat is an interactive process involving a browser since you need to login\nand authorize access to your email account. `oama` will lead you through this\nprocess.\n\n## Running `oama` remotely\n\nInstall and configure `oama` on the remote host. Chose a back-end, it can be\neither GPG or KEYRING. Make sure that the back-end installed and **works as\ndesired** on the remote machine.\n\nPick a free, non-privileged `\u003cport-number\u003e` and include\n\n    redirect_uri: http://localhost:\u003cport-number\u003e\n\ninto your service provider configuration section.\n\nLogin into the remote host using the command below:\n\n    ssh -L \u003cport-number\u003e:localhost:\u003cport-number\u003e \u003cremote-host\u003e\n\nStart the authorization on the remote host as usual:\n\n    oama authorize \u003cservice\u003e \u003cemail\u003e\n\nThen just follow the instructions and open the suggested URL in a browser\nrunning on your *local* machine.\n\n## Logging\n\nAll transactions and exceptions are logged to `syslog`. If your OS using\n`systemd` you can inspect the log with a command like below:\n\n    journalctl --identifier oama --identifier msmtp --identifier fdm -e\n\n## Installation\n\n### Precompiled binaries\n\nEach release comes with a few precompiled static binaries\nof `oama`. Select the version you want to download from\n[releases](https://github.com/pdobsan/oama/releases).\n\n#### Archlinux\n\nFor Archlinux users there is also a package on AUR:\n[oama-bin](https://aur.archlinux.org/packages/oama-bin)\n\n### Building from sources\n\nAdditionally to this GitHub repository the source code is also mirrored at\n[Sourcehut](https://git.sr.ht/~petrus/oama).\n\nTo build `oama` from source you need a Haskell development environment,\nwith `ghc 9.12.1` or higher. Either your platform's package system can provide\nthis or you can use [ghcup](https://www.haskell.org/ghcup/).\n\nThere is a `justfile` for building using the\n[just](https://github.com/casey/just) command runner. Invoking `just` without\narguments lists the available recipes.\n\nThe default way to build and install `oama`:\n\n    git clone https://github.com/pdobsan/oama\n    # or git clone https://git.sr.ht/~petrus/oama\n    cd oama\n    cabal update\n    just build         # optional install invokes it\n    just install\n\nDependencies for the default build:\n\n  - `gnupg` Linux package\n  - `secret-tool` utility, part of `libsecret` but in Debian a separate package.\n  - `security` utility in macOS.\n\nThere are alternative methods to build `oama`. The default, without any specific\nconfiguration as above, provides an executable which spawns external utilities\nto manage secrets.\n\nTo use a FFI to an external library API to access `keyring` or `gpg` encryption\nservices you need to run a `config-...` recipe before the `build` step. For example:\n\n    just config-gisecret\n    just build\n\nDependencies for using library API-s:\n\n  - `gpgme` Linux package\n  - `libsecret` Linux package\n  - `gobject-introspection` Linux package\n\nTo test `oama` without installing use the `run` recipe. For example:\n\n    just run\n    just run printenv\n    just run authorize google johndoe@gmail.com\n\n## Issues\n\nPlease, report any problems, questions, suggestions regarding `oama`\nby opening an issue. Alternatively, send a mail to the\n[oama mailing list](mailto:~petrus/oama@lists.sr.ht), no subscription necessary.\n\n### Guidelines for opening an issue\n\n- Make sure that you are using the latest version of `oama`.\n\n- Before opening an issue search [previous issues](https://github.com/pdobsan/oama/issues)\n (both open and closed) and the [oama mailing list](https://lists.sr.ht/~petrus/oama).\n Check whether similar problems have been raised or solved before.\n\n- Attach the **complete output of the `oama printenv`** command. Do not\n  remove lines, get confidential values redacted by replacing them with\n  `\u003csome explanation\u003e`. In particular, indicate what kind of `client_id/secret`\n  you are using. For example, `\u003cmy own app id registered with google\u003e`.\n\n- Indicate what kind of account(s) you are using that is who is the service\n  provider and whether your account is personal or institutional.\n\n- Send also full error messages and related syslog entries. Even when `oama` was called\n  by another program which could have hidden its error messages you might see\n  them in the syslog.\n\n## Alternatives\n\nThe programs below solve similar problems as `oama` does but have different\ntakes on them.\n\n- [mutt_oauth2.py](https://gitlab.com/muttmua/mutt/-/blob/master/contrib/mutt_oauth2.py)\n\n- [email-oauth2-proxy](https://github.com/simonrob/email-oauth2-proxy)\n\n- [pizauth](https://github.com/ltratt/pizauth)\n\n\n## License\n\n`oama` is released under the 3-Clause BSD License, see the file\n[License](License).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpdobsan%2Foama","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpdobsan%2Foama","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpdobsan%2Foama/lists"}