Skip to content

Commit 4991542

Browse files
authored
Add Google Cloud service account support (#224)
Authentication can now be handled via a Google Cloud service account
1 parent df9927f commit 4991542

File tree

3 files changed

+122
-46
lines changed

3 files changed

+122
-46
lines changed

README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,9 @@ The [sample configuration file](https://github.com/simonrob/email-oauth2-proxy/b
7373
- Gmail / Google Workspace: register a [Google API desktop app client](https://developers.google.com/identity/protocols/oauth2/native-app)
7474
- AOL and Yahoo Mail (and subproviders such as AT&T) are not currently allowing new client registrations with the OAuth email scope – the only option here is to reuse the credentials from an existing client that does have this permission.
7575

76-
The proxy also supports the [client credentials grant](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-client-creds-grant-flow) and [resource owner password credentials grant](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth-ropc) OAuth 2.0 flows if needed.
77-
Please note that currently only Office 365 is known to support these methods.
76+
The proxy supports [Google Cloud service accounts](https://cloud.google.com/iam/docs/service-account-overview) for access to Google Workspace Gmail.
77+
It also supports the [client credentials grant (CCG)](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-client-creds-grant-flow) and [resource owner password credentials grant (ROPCG)](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth-ropc) OAuth 2.0 flows.
78+
Please note that currently only Office 365 is known to support the CCG and ROPCG methods.
7879
See the [sample configuration file](https://github.com/simonrob/email-oauth2-proxy/blob/main/emailproxy.config) for further details.
7980

8081

@@ -213,7 +214,7 @@ You will know intervention is necessary if the proxy exits (rather than restarts
213214
To resolve this, exit the proxy and then run `launchctl load ~/Library/LaunchAgents/ac.robinson.email-oauth2-proxy.plist` from a terminal.
214215
A permission pop-up should appear requesting file access for python.
215216
Once this has been approved, the proxy's menu bar icon will appear as normal.
216-
In some cases — particularly when running the proxy in a virtual environment, or using the built-in macOS python, rather than the python.org version, or installations managed by, e.g., homebrew, pyenv, etc — the permission prompt does not appear.
217+
In some cases — particularly when running the proxy in a virtual environment, or using the built-in macOS python, rather than the python.org version, or installations managed by, e.g., homebrew, pyenv, etc. — the permission prompt does not appear.
217218
If this happens it is worth first trying to `unload` and then `load` the service via `launchctl`.
218219
If this still does not cause the prompt to appear, the only currently-known resolution is to run the proxy outside of a virtual environment and manually grant Full Disk Access to your python executable via the privacy settings in the macOS System Preferences.
219220
You may also need to edit the proxy's launch agent plist file, which is found at the location given in the command above, to set the path to your python executable – it must be the real path rather than a symlink (the `readlink` command can help here).
@@ -226,7 +227,7 @@ Please feel free to [open an issue](https://github.com/simonrob/email-oauth2-pro
226227
## Advanced features<a id="advanced-features"></a>
227228
The [plugins variant](https://github.com/simonrob/email-oauth2-proxy/tree/plugins) has an additional feature that enables the use of separate scripts to modify IMAP/POP/SMTP commands when they are received from the client or server before passing through to the other side of the connection.
228229
This allows a wide range of additional capabilities or triggers to be added the proxy.
229-
For example, the [IMAPIgnoreSentMessageUpload plugin](https://github.com/simonrob/email-oauth2-proxy/blob/plugins/plugins/IMAPIgnoreSentMessageUpload.py) intercepts any client commands to add emails to the IMAP sent messages mailbox, which resolves message duplication issues for servers that automatically do this when emails are received via SMTP (e.g., Office 365, Gmail, etc).
230+
For example, the [IMAPIgnoreSentMessageUpload plugin](https://github.com/simonrob/email-oauth2-proxy/blob/plugins/plugins/IMAPIgnoreSentMessageUpload.py) intercepts any client commands to add emails to the IMAP sent messages mailbox, which resolves message duplication issues for servers that automatically do this when emails are received via SMTP (e.g., Office 365, Gmail, etc.).
230231
The [IMAPCleanO365ATPLinks plugin](https://github.com/simonrob/email-oauth2-proxy/blob/plugins/plugins/IMAPCleanO365ATPLinks.py) restores "Safe Links" modified by Microsoft Defender for Office 365 to their original URLs.
231232
The [SMTPBlackHole plugin](https://github.com/simonrob/email-oauth2-proxy/blob/plugins/plugins/SMTPBlackHole.py) gives the impression emails are being sent but actually silently discards them, which is useful for testing email sending tools.
232233
See the [documentation and examples](https://github.com/simonrob/email-oauth2-proxy/tree/plugins/plugins) for further details, additional sample plugins and setup instructions.
@@ -245,7 +246,7 @@ For Docker, blacktirion has an [example configuration](https://github.com/blackt
245246

246247
If you already use postfix, the [sasl-xoauth2](https://github.com/tarickb/sasl-xoauth2) plugin is probably a better solution than running this proxy.
247248
Similarly, if you use an application that is able to handle OAuth 2.0 tokens but just cannot retrieve them itself, then [pizauth](https://github.com/ltratt/pizauth), [mailctl](https://github.com/pdobsan/mailctl) or [oauth-helper-office-365](https://github.com/ahrex/oauth-helper-office-365) may be more appropriate.
248-
There are also dedicated helpers available for specific applications (e.g., [mutt_oauth2](https://gitlab.com/muttmua/mutt/-/blob/master/contrib/mutt_oauth2.py)), and several open-source email clients that support OAuth 2.0 natively (e.g., [Thunderbird](https://www.thunderbird.net/), [Mailspring](https://getmailspring.com/), [FairEmail](https://email.faircode.eu/), [Evolution](https://wiki.gnome.org/Apps/Evolution), etc).
249+
There are also dedicated helpers available for specific applications (e.g., [mutt_oauth2](https://gitlab.com/muttmua/mutt/-/blob/master/contrib/mutt_oauth2.py)), and several open-source email clients that support OAuth 2.0 natively (e.g., [Thunderbird](https://www.thunderbird.net/), [Mailspring](https://getmailspring.com/), [FairEmail](https://email.faircode.eu/), [Evolution](https://wiki.gnome.org/Apps/Evolution), etc.).
249250

250251
[DavMail](http://davmail.sourceforge.net/) is an alternative to this proxy that takes the same approach of providing a local IMAP/POP/SMTP server (and more) for Exchange/Office 365, though it does this by translating these protocols into Exchange API calls rather than proxying the connection.
251252
That approach is very useful in situations where server-side IMAP/POP/SMTP is not supported or enabled, or the full Exchange capabilities are needed, but it has limitations in terms of speed and the number of email messages that can be retrieved.

emailproxy.config

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -121,17 +121,36 @@ documentation = Accounts are specified using your email address as the section h
121121
- The proxy supports the client credentials grant (CCG) and resource owner password credentials grant (ROPCG) OAuth
122122
2.0 flows (both currently only known to be available for Office 365). To use either of these flows, add an account
123123
entry as normal, but do not add a `permission_url` value (it does not apply, and its absence signals to the proxy to
124-
use the appropriate token retrieval mechanism). An example is given for both methods towards the end of the sample
125-
account entries below.
124+
use the appropriate token retrieval mechanism). For CCG, set `oauth2_scope = https://outlook.office365.com/.default`
125+
and `oauth2_flow = client_credentials`. For ROPCG, set `oauth2_flow = password` (and use a standard scope value). An
126+
example is given for both methods towards the end of the sample account entries below.
126127

127128
- WARNING: Please note that by default the CCG flow has essentially no local access control when creating new
128129
accounts (no user consent is involved, so the proxy cannot validate login attempts unless an account entry
129-
already exists its configuration file). This is especially important when using the proxy's catch-all feature
130-
(which is likely to be the case given the typical use-cases for the CCG flow). Because of this, you are highly
131-
encouraged to enable the proxy's secret encryption option - see `encrypt_client_secret_on_first_use` at the end
132-
of this file. In addition, if you are using the proxy in an environment where there is any possibility of
133-
malicious access attempts before the first valid login, pre-encrypting account entries is highly recommended.
134-
See the example script at https://github.com/simonrob/email-oauth2-proxy/issues/61#issuecomment-1259110336.
130+
already exists its configuration file). Using the CCG flow with the proxy in a publicly-accessible context is
131+
not advised. This is especially important when using the proxy's catch-all feature (which is likely to be the
132+
case given the typical use-cases for the CCG flow). Because of this, you are highly encouraged to enable the
133+
proxy's secret encryption option - see `encrypt_client_secret_on_first_use` at the end of this file. In
134+
addition, if you are using the proxy in an environment where there is any possibility of malicious access
135+
attempts before the first valid login, pre-encrypting account entries is highly recommended. See the example
136+
script at https://github.com/simonrob/email-oauth2-proxy/issues/61#issuecomment-1259110336.
137+
138+
Gmail customisation:
139+
- The proxy supports the use of service accounts with Gmail for Google Workspace (note: normal Gmail accounts do not
140+
support this method). To use this option, add an account entry as normal, but do not add a `permission_url` value
141+
(it does not apply, and its absence signals to the proxy to use the appropriate token retrieval mechanism). Set
142+
`oauth2_flow = service_account`. The service account key itself can either be referenced in an external file, or
143+
pasted directly into the account entry. For the file approach, set `client_id = file` and `client_secret` to the
144+
full path to the JSON key file. To include the key directly, set `client_id = key`, then paste the full contents of
145+
your service account's JSON key as the value for `client_secret`, making sure all lines are indented by at least one
146+
space (so that the proxy can tell they are all part of one value). An example is given for both methods towards the
147+
end of the sample account entries below.
148+
149+
- WARNING: Please note that the same potential security issues outlined above with O365's CCG flow also apply to
150+
the service account method: there is essentially no local access control when creating new accounts. Using a
151+
service account with the proxy in a publicly-accessible context is not advised. You are highly encouraged to
152+
enable the proxy's secret encryption option (see `encrypt_client_secret_on_first_use` at the end of this file)
153+
and consider pre-encrypting account entries.
135154

136155
Advanced account configuration:
137156
- For most configurations the default `redirect_uri` value of `http://localhost` is correct, unless you have
@@ -201,6 +220,25 @@ redirect_uri = http://localhost
201220
client_id = *** your client id here ***
202221
client_secret = *** your client secret here ***
203222

223+
224+
documentation = *** note: this is an advanced Google account example; in most cases you want the version above instead ***
225+
token_url = https://oauth2.googleapis.com/token
226+
oauth2_scope = https://mail.google.com/
227+
oauth2_flow = service_account
228+
redirect_uri = http://localhost
229+
client_id = file
230+
client_secret = *** your /path/to/service-account-key.json here ***
231+
232+
233+
documentation = *** note: this is an advanced Google account example; in most cases you want the version above instead ***
234+
token_url = https://oauth2.googleapis.com/token
235+
oauth2_scope = https://mail.google.com/
236+
oauth2_flow = service_account
237+
redirect_uri = http://localhost
238+
client_id = key
239+
client_secret = *** your pasted service account JSON key file contents here,
240+
making sure to indent all lines by at least one space ***
241+
204242
[Advanced proxy configuration]
205243
documentation = The parameters below control advanced options for the proxy. In most cases you will not need to modify
206244
the values in this section. If any of these values are not found, the proxy will assume the default value, which
@@ -215,7 +253,8 @@ documentation = The parameters below control advanced options for the proxy. In
215253
be laborious or need administrator intervention, this can potentially result in a denial-of-service issue, whether
216254
malicious or not. It can also be the source of confusion if using a client (such as Firefox) that stores a separate
217255
password per protocol for each account, but does not make this clear when changing account passwords. Set this
218-
option to False and the proxy will instead return an error when an incorrect password is provided.
256+
option to False and the proxy will instead return an error when an incorrect password is provided. For accounts
257+
using the O365 CCG flow or a Google Cloud service account this option will be overridden and always set to False.
219258

220259
- encrypt_client_secret_on_first_use (default = False): The proxy encrypts sensitive configuration values (e.g.,
221260
cached access tokens) using the password that is given when accessing an account via IMAP/POP/SMTP. It does not do
@@ -242,7 +281,7 @@ documentation = The parameters below control advanced options for the proxy. In
242281
that does not need to be configured manually. Any account-level configuration will override domain-level values
243282
(except for account access and refresh tokens). If needed, the global catch-all section [@] can also be used. Please
244283
note that this option is not fully compatible with `encrypt_client_secret_on_first_use` unless all IMAP/POP/SMTP
245-
accounts at the same domain use the same password, or you undertake additional manual configuraton steps - see the
284+
accounts at the same domain use the same password, or you undertake additional manual configuration steps - see the
246285
discussion at https://github.com/simonrob/email-oauth2-proxy/issues/214#issuecomment-1861593781 for details.
247286

248287
[emailproxy]

0 commit comments

Comments
 (0)