Skip to content

Conversation

@FreakIsTea
Copy link

@FreakIsTea FreakIsTea commented Dec 23, 2025

With upcoming changes on cloud providers, SMTP will not be working with AgnosticAuthentication. I added configuration to enable XOAUTH2 authentication with the OAUTH2 client credentials flow. The AgnosticAuthentication will still be the default, and current configs will work the same (no breaking changes). With the following config, the XOAUTH2 authentication can be enabled:

  • EMAIL_SMTP_AUTH_MECHANISM => Sets the authentication mechanism. Options: AGNOSTIC, XOAUTH2. Default: AGNOSTIC.
  • EMAIL_SMTP_OAUTH_CLIENT_ID => Client ID for the OAUTH2 client credentials flow
  • EMAIL_SMTP_OAUTH_CLIENT_SECRET => Client Secret for the OAUTH2 client credentials flow
  • EMAIL_SMTP_OAUTH_TOKEN_URL => Token Endpoint for OAUTH2 (IdP specific)
  • EMAIL_SMTP_OAUTH_SCOPES => Scopes to fetch for the token

Right now, I haven't added any documentation yet. I'd like for the PR to be checked first and then finalize the PR with the documentation after all necessary changes have been made.

Feel free to suggest changes and ask questions if something's not clear!

@FreakIsTea FreakIsTea changed the title Feature/smtp oauth XOAUTH2 Authentication Mechanism for SMTP Dec 23, 2025
Copy link
Contributor

@mattwoberts mattwoberts left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this @FreakIsTea !

It's a good solution for working with XOAUTH2 that doesn't involve swapping out to another smtp package.

One issue - the authenticate method is called for every email sent, so I think this current code will go and fetch a new token for each email sent. We'd need to implement token caching with this, presumably with the TokenSource method..

@FreakIsTea
Copy link
Author

Hi @mattwoberts

Sorry for only getting back to you now. This is a good idea, I'll implement this. Please then check my code for code smells etc. as this is my first time coding in go.

@FreakIsTea
Copy link
Author

I added the token caching by doing the following:

  • Creating a key for the TokenSource by hashing the config data.
  • Creating a map which holds the mapping key <-> TokenSource
  • Checking if the map contains a TokenSource => if not, it will be created
  • Getting the token via the appropriate TokenSource.Token() method

If there are more inputs, please tell me. I'd be happy to get this change into the project 😁

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants