An SMTP relay that accepts SMTP submissions from legacy clients and forwards messages to Microsoft Graph using OAuth 2.0 client credentials.
This repository implements a small, stateless SMTP server that bridges the gap between legacy SMTP clients and Microsoft 365's modern authentication requirements:
- π OAuth 2.0 Authentication: Uses application credentials instead of user passwords
- π§ Microsoft Graph Integration: Sends email via the Microsoft Graph API
- π SMTP Compatibility: Works with any SMTP client (AUTH LOGIN/PLAIN)
- π Stateless & Scalable: Can be deployed in multiple instances for high availability
- π Security-First: Supports TLS encryption and Azure Key Vault integration
- π Azure Tables Support: Optional centralized credential management
| Feature | SMTP OAuth Relay | Azure Communication Services | Microsoft 365 High Volume Email (Preview) |
|---|---|---|---|
| Purpose | Bridge legacy SMTP clients to Microsoft 365 | General email/SMS/voice service | High-volume transactional email |
| Use Case | Legacy devices, printers, apps without OAuth | Application email/SMS at scale | Marketing, newsletters, bulk email |
| SMTP Support | β SMTP compatibility | β SMTP available | β SMTP compatibility |
| Send Externally | β Yes (to any recipient) | β Yes (to any recipient) | β No (only internal) |
| Legacy Device Support | β Excellent | β Excellent | |
| Multi-tenant | β Yes | β No | β No |
| Sender Address | Uses existing M365 mailboxes | Custom domains | Uses dedicated Mailbox (HVE-Account) |
| Pricing | Free (self-hosted) | Pay-per-use (email/SMS/calls) | Free in Preview |
| Infrastructure | Self-hosted (Docker/K8s) | Fully managed Azure service | Fully managed Microsoft service |
| Deliverability | Microsoft 365 reputation | Separate IP pools and reputation | Microsoft 365 reputation |
| Volume Limits | Based on M365 mailbox limits | Very high (purpose-built for scale) | Very high (designed for bulk) |
| Setup Complexity | Moderate (deploy + Entra app) | Moderate (provision resource + Entra app) | Low (create HVE-Account) |
*Some legacy devices may not support providing a dedicated From address or may implement a character limit, which won't work with ACS.
Refer to the Installation Guide for detailed steps.
docker run --name smtp-relay -p 8025:8025 \
-v $(pwd)/certs:/usr/src/smtp-relay/certs \
-e LOG_LEVEL=INFO \
-e TLS_SOURCE=file \
-e REQUIRE_TLS=true \
ghcr.io/justiniven/smtp-oauth-relay:latest| Setting | Value |
|---|---|
| SMTP Server | Your relay hostname |
| Port | 8025 |
| Security | STARTTLS |
| Username | tenant_id@client_id |
| Password | Your app's client secret |
- Installation Guide - Docker, Kubernetes, manual installation
- Configuration Reference - All environment variables explained
- Azure/Entra ID Setup - Create and configure Azure applications
- Client Setup Guide - Configure email clients, printers, applications
- Authentication Guide - Username formats, UUID encoding, lookup tables
- Azure Tables Integration - Centralized credential management
- Architecture & How It Works - Technical implementation details
- FAQ - Frequently asked questions
Direct UUID Format:
12345678-1234-1234-1234-123456789abc@abcdefab-1234-5678-abcd-abcdefabcdef
Base64URL Encoded (shorter):
EjRWeBI0EjQSNBI0VnirzQ@q83rrBI0VnirzN21q837qg
Azure Tables Lookup (custom):
printer1@lookup
- File: Load from filesystem (development, production with Let's Encrypt)
- Azure Key Vault: Managed certificate storage with automatic rotation
- Off: Disable TLS (development only)
- β Multiple tenant support (single relay for multiple organizations)
- β Application Access Policies integration (restrict sender addresses)
- β Azure Tables for simplified credentials
- β Sender address override
- β Horizontal scaling (stateless design)
- β Comprehensive logging and monitoring
- Network printers with scan-to-email
- Multifunction devices
- Fax servers
- Security cameras
- Monitoring systems (Grafana, Nagios)
- CI/CD pipelines (Jenkins, GitLab)
- Content management systems (WordPress, Drupal)
- Custom applications without OAuth support
- NAS devices (Synology, QNAP)
- Firewalls and routers
- UPS systems
- IoT devices
- Python 3.11+ (if running manually)
- Docker (recommended) or Kubernetes
- Network access to Microsoft APIs
- TLS certificate (production)
- Microsoft 365 / Exchange Online tenant
- Microsoft Entra ID (Azure AD)
- Application registration with Mail.Send permission
- Azure Key Vault (for certificate management)
- Azure Table Storage (for credential lookup)
- Managed Identity (for Azure services)
This relay implements security best practices:
- π TLS Encryption: Protects credentials in transit
- π OAuth 2.0: No user passwords stored or transmitted
- π‘οΈ Application Permissions: Centrally managed in Azure
- π Audit Logging: Full activity logs in Azure AD
- π« Access Policies: Restrict sender addresses
- π Secret Rotation: Regular credential rotation support
- π Documentation: Comprehensive guides in the
docs/folder - π Bug Reports: GitHub Issues
- π‘ Feature Requests: GitHub Issues
- π€ Contributions: Pull requests welcome!
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Built with:
- aiosmtpd - SMTP server framework
- Microsoft Graph API - Email sending
- Microsoft Identity Platform - OAuth authentication
Ready to get started? β Installation Guide