SMTP OAuth Relay¶
A small, stateless SMTP server that lets legacy clients (printers, NAS, monitoring tools, line-of-business apps) send mail through Microsoft 365 using OAuth 2.0 client credentials and the Microsoft Graph API — no Basic Authentication required.
flowchart LR
A[Legacy SMTP client] -->|SMTP + STARTTLS| B(SMTP OAuth Relay)
B -->|OAuth 2.0 token| C[Microsoft Entra ID]
B -->|sendMail| D[Microsoft Graph]
D --> E[Exchange Online]
- OAuth 2.0 client credentials — app credentials instead of user passwords
- Microsoft Graph — sends via the
sendMailendpoint - SMTP compatible — any client supporting
AUTH LOGIN/PLAIN+ STARTTLS - Stateless — scale horizontally behind a load balancer
- TLS from file or Azure Key Vault
- Azure Tables — optional central credential lookup
Quick start¶
Three steps to a working relay. You need a Microsoft 365 tenant and permission to register an Entra ID application.
1. Create Entra ID credentials (PowerShell)¶
The New-RelayEntraApp.ps1 script registers the app, creates a secret, and restricts it to a single sender mailbox.
# Prerequisites: PowerShell 5.1+, Microsoft.Graph and ExchangeOnlineManagement modules
Connect-MgGraph -Scopes "Application.ReadWrite.All", "AppRoleAssignment.ReadWrite.All" -NoWelcome
Connect-ExchangeOnline -ShowBanner:$false
Invoke-WebRequest `
-Uri "https://raw.githubusercontent.com/JustinIven/smtp-oauth-relay/main/New-RelayEntraApp.ps1" `
-OutFile "New-RelayEntraApp.ps1"
.\New-RelayEntraApp.ps1 -DisplayName "SMTP OAuth Relay" -SenderAddress "noreply@example.com"
The script prints the SMTP username (tenant_id@client_id) and SMTP password (client secret). Save them — the secret cannot be retrieved later.
2. Run the relay¶
docker run --name smtp-relay -p 8025:8025 \
-e TLS_SOURCE=off \
-e REQUIRE_TLS=false \
ghcr.io/justiniven/smtp-oauth-relay:latest
TLS is recommended
Only disable TLS for testing in a trusted network. Use TLS_SOURCE=file or TLS_SOURCE=keyvault in production.
Deploys an Azure Container Instance with a managed identity. See the Azure install guide.
3. Point your client at the relay¶
| Setting | Value |
|---|---|
| Server | Your relay hostname |
| Port | 8025 |
| Security | STARTTLS |
| Username | tenant_id@client_id (from step 1) |
| Password | Client secret (from step 1) |
Verify it works
Next steps¶
- Install — Docker, Azure, Kubernetes, or manual
- Entra ID setup — app registration and sender restrictions
- Configuration — environment variable reference
- Client setup — printers, NAS, firewalls, apps
- Authentication — username formats and encoding
- FAQ — common questions
When to use this relay¶
| SMTP OAuth Relay | Azure Communication Services | M365 High Volume Email | |
|---|---|---|---|
| Purpose | Bridge legacy SMTP to M365 | App email/SMS at scale | Bulk/transactional |
| Send externally | internal only | ||
| Sender address | Existing M365 mailboxes | Custom domains | Dedicated HVE account |
| Multi-tenant | |||
| Pricing | Free (self-hosted) | Pay-per-use | Free (preview) |
| Hosting | Self-hosted | Managed | Managed |