Late December 2026 is a milestone, not permission to wait
Microsoft plans to disable SMTP AUTH Basic authentication by default in existing Exchange Online tenants at the end of December 2026. An administrator will still be able to turn it back on when needed. For new tenants created after that period, OAuth will be the supported default. Microsoft plans to announce the final removal date in the second half of 2027.
That distinction matters: December is not yet an irreversible shutdown for every tenant. It is still a security change designed to expose the remaining dependencies. Turning Basic back on without an expiry date merely postpones an outage while leaving a reusable password inside a printer, script or rarely reviewed application.
The practical objective is straightforward: know exactly what sends through smtp.office365.com, move each flow to the right method, then remove the exception. Critical systems deserve an end-to-end delivery test, not merely a message accepted by the SMTP server.
What goes away and what remains available
SMTP AUTH is the submission protocol; Basic and OAuth are two ways to authenticate to it. The announced retirement targets SMTP AUTH with a username and password. A compatible application can continue using smtp.office365.com with STARTTLS and XOAUTH2. You can also leave SMTP for Microsoft Graph or use Exchange Online relay identified by a certificate or public IP address.
Do not confuse user authentication with workload authentication. An interactive client can obtain a delegated token on a person's behalf. A background service instead uses its own identity, a certificate or federated credential, and permission limited to the mailboxes it actually needs.
OAuth does not fix old encryption. SMTP submission requires TLS 1.2 or 1.3, and Microsoft recommends port 587 with STARTTLS. A device that cannot obtain a token or negotiate modern TLS needs a different architecture.
| Path | Authentication | Reasonable use | Control point |
|---|---|---|---|
| Modern SMTP AUTH | OAuth 2.0 / XOAUTH2 | Application that must retain SMTP | SMTP AUTH enabled only for the required mailbox |
| Microsoft Graph | Entra ID token | Modifiable application or script | Mail.Send limited through RBAC |
| Exchange Online relay | Certificate or static public IP | Local equipment without OAuth | Connector, port 25, SPF and firewall |
| Direct Send | None | Last resort for internal recipients | No external recipients; normal filtering applies |
| Azure Communication Services Email | Service identity or key | Transactional or Azure-hosted application | Domain, quota and service cost |
Start with 90 days of data, then talk to owners
In the Exchange admin centre, the SMTP AUTH Clients report is under Reports > Mail Flow. It separates Basic Auth, displayed as TlsAuthLogin, from Modern Auth, displayed as XOAUTH2. It also shows the sender, volume and TLS version. Extend the range to 90 days and export the CSV; seven days will miss a monthly report, certificate alert or payroll job.
The report does not know the printer name or the ERP owner. Correlate sender address, source IP, firewall logs, message trace and local configurations. Ask application teams what triggers the email, who receives it and what happens when delivery fails.
Create one record per flow, not merely per account. One alerts@ account can hide ten systems with different constraints. Separating them lets you migrate one device at a time, revoke one integration without breaking others and assign a real owner.
| Inventory field | Example | Why it matters |
|---|---|---|
| Source and owner | MFP-FLOOR2 / Infrastructure team | Someone can test and decide |
| Account and From address | scanner@contoso.com | Exposes shared passwords and Send As |
| Host, port and TLS | smtp.office365.com:587 / STARTTLS | Confirms the path actually in use |
| Authentication mode | TlsAuthLogin | Separates Basic from XOAUTH2 |
| Recipients | Internal and external | Eliminates Direct Send in some cases |
| Volume and size | 400 messages/day, 12 MB attachments | Affects quotas, attachments and target service |
| Criticality and frequency | Immediate fire alarm | Determines order, monitoring and rollback |
| OAuth capability | Firmware required / none | Decides between update, Graph or relay |
| Target method and wave | Certificate relay / wave 2 | Turns an inventory into a plan |
Choose the target by system, not with one universal recipe
The best replacement is usually the option the product officially supports. A recent printer may obtain an OAuth token in its web interface; an ERP may offer a Microsoft 365 connector; an internal application can call Graph; an old controller may only reach a local relay. Forcing one answer everywhere increases both privilege and troubleshooting effort.
Require vendor documentation and the minimum firmware or software release. An OAuth button does not guarantee app-only flow, shared mailbox support or certificate rotation. Test the sender, external recipients, attachments and token renewal as well.
| Source | First choice | Fallback | Avoid |
|---|---|---|---|
| Recent printer | Vendor-supported native OAuth | Restricted local relay | An employee's password |
| Legacy printer | Certificate/IP relay from an isolated VLAN | Internal-only Direct Send | Re-enabling Basic indefinitely |
| Internally developed app | Graph Mail.Send or SMTP OAuth | Azure Communication Services Email | A new System.Net.Mail dependency |
| Commercial application | Supported OAuth connector | Approved relay service | Unsupported vendor workaround |
| PowerShell script | Microsoft Graph with certificate or managed identity | Transactional email API | Send-MailMessage with a password |
| Monitoring and alerts | Native webhook, Graph or dedicated relay | Transactional email service | One global account shared by every tool |
| High-volume internal mail | High Volume Email with OAuth when suitable | Controlled relay | User mailbox as a bulk engine |
Read the Exchange Online settings before changing them
Exchange Online has both an organization setting and a mailbox setting. At mailbox level, $null inherits from the tenant, $true disables SMTP AUTH and $false explicitly enables it. That final value can survive organization-wide hardening, so inventory exceptions before and after the change.
Entra security defaults disable SMTP AUTH. An Exchange authentication policy can also block Basic. Do not disable broad protections to repair one device: select another path or use a named, documented and temporary exception.
Connect-ExchangeOnline
Get-TransportConfig |
Select-Object SmtpClientAuthenticationDisabled
Get-CASMailbox -ResultSize Unlimited |
Select-Object DisplayName, PrimarySmtpAddress, SmtpClientAuthenticationDisabled |
Export-Csv .\smtp-auth-mailboxes.csv -NoTypeInformation -Encoding UTF8
Get-OrganizationConfig |
Select-Object DefaultAuthenticationPolicy
Get-AuthenticationPolicy |
Select-Object Name, AllowBasicAuthSmtp# $false enables SMTP AUTH for this mailbox; OAuth is still preferred.
Set-CASMailbox -Identity alerts@contoso.com `
-SmtpClientAuthenticationDisabled $false
Get-CASMailbox -Identity alerts@contoso.com |
Select-Object PrimarySmtpAddress, SmtpClientAuthenticationDisabledChoose delegated or app-only OAuth
Delegated flow fits when a user is present and the application acts on their behalf. For SMTP, the delegated scope is https://outlook.office.com/SMTP.Send; offline_access allows a refresh token when the scenario requires one. The client must be able to open an interactive sign-in, handle consent and renew tokens.
App-only flow fits a service, job or gateway with no user. The workload requests a token for https://outlook.office365.com/.default and Exchange then authorizes the application identity to send for a mailbox scope. Prefer a certificate or federated identity over a static secret when supported.
For a new app-only SMTP deployment, Exchange RBAC for Applications can grant Application SMTP.SendAsApp to a precise set of mailboxes. This avoids an unscoped Entra permission across every mailbox. Entra and RBAC grants are additive, so remove any old organization-wide permission that would defeat the scope.
| Question | Delegated OAuth | App-only OAuth |
|---|---|---|
| User present | Yes | No |
| Typical context | Client or user-initiated function | Service, ERP, relay or scheduled job |
| SMTP authorization | SMTP.Send on behalf of the user | Application SMTP.SendAsApp in Exchange RBAC |
| Token | Access plus refresh based on flow | Client credentials |
| Preferred credential | User session and policy | Certificate, federated identity or managed identity when available |
| Scope | User and consent | Mailboxes explicitly included in the resource scope |
Configure app-only SMTP OAuth with an Exchange scope
First create a single-tenant app registration and its Entra service principal. In the recommended RBAC model for SMTP, do not add Exchange Online SMTP.SendAsApp on the API permissions page: the role and scope are granted in Exchange. Use the enterprise application's Object ID, not the Object ID shown under App registrations, when creating the Exchange pointer.
The following example limits the application to direct members of a mail-enabled security group. Nested groups are not included. Replace every identifier and distinguished name; test both an allowed mailbox and one deliberately outside the scope. Authorization caching can take 30 minutes to two hours even when Test-ServicePrincipalAuthorization already reflects the configuration.
Connect-ExchangeOnline
New-ServicePrincipal `
-AppId 11111111-1111-1111-1111-111111111111 `
-ObjectId 22222222-2222-2222-2222-222222222222 `
-DisplayName "SMTP OAuth - ERP"
# Use the real DistinguishedName of a mail-enabled group.
New-ManagementScope `
-Name "SMTP OAuth Senders" `
-RecipientRestrictionFilter "MemberOfGroup -eq 'CN=SMTP OAuth Senders,OU=contoso.onmicrosoft.com,DC=COM'"
New-ManagementRoleAssignment `
-Name "ERP SMTP OAuth" `
-Role "Application SMTP.SendAsApp" `
-App 11111111-1111-1111-1111-111111111111 `
-CustomResourceScope "SMTP OAuth Senders"Test-ServicePrincipalAuthorization `
-Identity 11111111-1111-1111-1111-111111111111 `
-Resource alerts@contoso.com | Format-Table
Test-ServicePrincipalAuthorization `
-Identity 11111111-1111-1111-1111-111111111111 `
-Resource executive@contoso.com | Format-TableXOAUTH2 replaces the password in the SMTP conversation
After obtaining a token, the client connects to smtp.office365.com, negotiates STARTTLS and uses SASL XOAUTH2. The encoded string contains the sender address and Bearer followed by the token, separated by Control-A. The token is short-lived, audience-bound and renewed by the application; never write it to debug logs.
A 235 response confirms authentication only. The client must still submit the message, process SMTP responses and retain failures. A 535 response often points to the wrong audience, missing permission, out-of-scope mailbox, disabled SMTP AUTH or configuration that is still propagating.
base64(
"user=alerts@contoso.com" + Control-A +
"auth=Bearer <ACCESS_TOKEN>" + Control-A + Control-A
)
AUTH XOAUTH2 <BASE64_STRING>Server: smtp.office365.com
Port: 587
Security: STARTTLS
TLS: 1.2 or 1.3
Authentication: OAuth 2.0 / XOAUTH2
App-only audience: https://outlook.office365.com/.defaultMicrosoft Graph is often simpler for an application you can change
Graph avoids maintaining an SMTP conversation and exposes POST /users/{id}/sendMail. Mail.Send is available as a delegated or application permission. HTTP 202 means the request was accepted, not that the recipient received the message; monitor transport failures and use message trace just as you would with SMTP.
The Microsoft Graph PowerShell module works well for scripts. This example uses a certificate from the local store instead of a secret written into the file. For app-only access, scope Application Mail.Send to the required sender mailboxes through RBAC for Applications and remove an equivalent global Entra grant that would make the scope ineffective.
Connect-MgGraph `
-TenantId "33333333-3333-3333-3333-333333333333" `
-ClientId "11111111-1111-1111-1111-111111111111" `
-CertificateThumbprint "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
$message = @{
message = @{
subject = "Alert: low disk space"
body = @{
contentType = "Text"
content = "FILE-SRV01 has less than 10% free space."
}
toRecipients = @(
@{ emailAddress = @{ address = "operations@contoso.com" } }
)
}
saveToSentItems = $true
}
Send-MgUserMail `
-UserId "alerts@contoso.com" `
-BodyParameter $message
Disconnect-MgGraphLegacy printers need a relay, not pretend OAuth
If the manufacturer offers Microsoft 365 OAuth firmware, test it first. Confirm consent flow, sender mailbox, token renewal and secondary features: scanning, internet fax, meter reports and technical alerts do not always share the same SMTP profile.
If the device cannot use OAuth, place it in a dedicated VLAN and let it reach only a controlled SMTP gateway. The gateway can then send through Graph, SMTP OAuth, Azure Communication Services Email or an Exchange Online connector. It must accept only expected source IPs, approved senders and required destinations; an open relay quickly turns a compatibility issue into an incident.
Exchange Online relay to the tenant MX endpoint uses port 25 and identifies the source with a certificate — preferred — or an unshared static public IP address. It does not require a licensed mailbox and supports external recipients. It is not suitable for a third-party or Azure-hosted application that cannot meet the connector's source requirements.
| Device option | External recipients | Identity | Main constraint |
|---|---|---|---|
| Native OAuth to smtp.office365.com | Yes | Entra token and licensed mailbox | Compatible firmware and OAuth flow |
| Local gateway to Graph/OAuth | Yes | Gateway workload identity | Server maintenance and monitoring |
| Exchange Online relay | Yes | Certificate or static public IP | Port 25, connector, SPF and local source |
| Direct Send | No | None | Internal only and filtered like Internet mail |
| Legacy IIS SMTP | Not recommended | Varies | Feature removed after Windows Server 2022 and unsupported scenario |
Harden the gateway and connector
A gateway concentrates flows, so treat it as security infrastructure. Two instances may be necessary when failure would block essential alerts or scans. Centralize logs, synchronize time, patch the system and test the queue after every change.
Never allow the entire user VLAN to relay. Use precise source IPs, reject unapproved From domains, limit size and rate, and prevent the gateway from delivering directly to the Internet. If the Exchange connector trusts an IP, monitor public address changes; if it trusts a certificate, alert well before expiry.
- Source: reserved printer and application IPs, never 0.0.0.0/0.
- Sender: accepted domain and approved addresses per system.
- Destination: internal only whenever the requirement allows it.
- Transport: TLS 1.2 or 1.3 on every capable segment.
- Logging: source, From, recipient, message ID, result and latency.
- Credentials: non-exportable certificate or workload identity; no keys in scripts.
- Operations: queue, retry, certificate, disk space and updates under monitoring.
Migrate scripts, applications and alerts without losing failures
An old script does not become reliable merely because it calls Graph. Preserve its operational contract: recipient, attachment, From identity, priority, log, failure alert and retry behaviour. Replace Send-MailMessage and new code based on System.Net.Mail.SmtpClient with Graph or an SMTP library that genuinely supports XOAUTH2.
For alerts, remove the circular dependency where the email service must report its own outage. Add an independent channel — Teams webhook, monitoring platform, SMS or transactional service — for critical mail alerts. A daily end-to-end test with a unique correlation ID detects silent delivery failure.
- Test plain text, HTML and the largest expected attachment.
- Confirm From, Reply-To, external recipients, groups and shared mailboxes.
- Handle 429, SMTP 4xx and temporary errors with exponential backoff.
- Retain a correlation ID without logging the token or sensitive content.
- Define how long a message may wait before being declared failed.
- Expire certificates and secrets in a test environment to validate the alert.
Deploy in waves with a short rollback
Start with a visible, non-critical and representative flow. Run old and new paths in parallel only when the application can prevent duplicates. Otherwise prepare rollback, change the endpoint, test real recipients and observe the logs for a defined period.
Wave success is not the number of changed configurations. It is the expected messages received, errors handled and old secrets removed. Close each wave with the service owner before moving to the next one.
| Wave | Scope | Exit criterion |
|---|---|---|
| 0 — Lab | Test mailbox and application | OAuth, scope, TLS, logging and out-of-scope denial confirmed |
| 1 — Pilot | One non-critical script and printer | Stable internal/external delivery and attachments |
| 2 — Applications | ERP, backup, monitoring and jobs | Owners approve and old credential is removed |
| 3 — Device fleet | Printers, NAS, UPS and controllers | No TlsAuthLogin remains for migrated systems |
| 4 — Block | Basic policy followed by organization setting | Alerts and SMTP AUTH report show no unknown dependency |
| 5 — Cleanup | Accounts, permissions, connectors and rules | Dated, minimal and monitored exceptions |
Troubleshoot in order without restoring Basic after the first 535
Start with network and TLS, then the token, then Exchange authorization. Decode only the token header in an approved tool and never send it to a public website: the audience must be Outlook for SMTP or Graph for sendMail, the tenant must match and the token must not be expired.
Next test the application identity and mailbox with Test-ServicePrincipalAuthorization. Confirm SMTP AUTH is not disabled for that mailbox, allow for RBAC propagation and inspect From. A 5.7.60 code typically means the authenticated identity cannot send as the selected address.
| Symptom | Likely cause | First check |
|---|---|---|
| 535 5.7.3 | Token, audience, permission, scope or SMTP AUTH | Token audience and Test-ServicePrincipalAuthorization |
| 5.7.60 Send As denied | Different From without permission | Authenticated address and Send As rights |
| TLS connection fails | Port, TLS inspection or old protocol | STARTTLS on 587 and TLS 1.2+ |
| Graph 202 but no message | Accepted request followed by processing or transport failure | Message trace and NDR |
| Internal works, external fails | Direct Send or unidentified connector | Chosen method, MX, IP/certificate and SPF |
| Works and then stops | Token not renewed, expired certificate or quota | Identity logs, expiry and limits |
| RBAC test InScope but 535 | Cache, wrong enterprise identity or additive permission | Object ID, role, old grants and delay |
Remove Basic and prove the migration holds
When the report no longer shows TlsAuthLogin for the expected flows, block Basic through policy, observe, then disable SMTP AUTH organization-wide if no OAuth SMTP use remains. If applications still use SMTP OAuth, keep the protocol off globally and enable only required mailboxes, subject to the Entra and Exchange protections in your tenant.
A Basic exception needs an owner, justification, source address, alert and expiry date. Re-enabling it is rollback, not a final architecture. Review the SMTP AUTH report weekly during transition and include it in the monthly Microsoft 365 review afterwards.
- The 90-day report has no ownerless Basic client.
- Every sender has a target method, scope and monitoring.
- Shared accounts and stored passwords have been removed.
- Graph and SMTP applications are limited to required mailboxes.
- Legacy printers use a closed, segmented relay.
- Tests cover external recipients, attachments and error recovery.
- The mail system's alert channel does not depend only on itself.
- Remaining exceptions expire automatically or trigger review.
# A mailbox moved to Graph or another service
Set-CASMailbox -Identity old-scanner@contoso.com `
-SmtpClientAuthenticationDisabled $true
# When no Basic or OAuth SMTP AUTH flow is required
Set-TransportConfig -SmtpClientAuthenticationDisabled $true
Get-TransportConfig |
Select-Object SmtpClientAuthenticationDisabled