A Complete Guide for Developers (Shared Mailbox + Azure App Registration + Graph API)
Sending email from a shared mailbox (e.g., no-reply@yourdomain.com) through a backend application is a very common requirement in modern systems — especially for automated notification systems, workflows, and customer-facing apps.
But getting all the Microsoft 365 configuration correct can be tricky.
This guide gives you one clear, end-to-end setup that works reliably in .NET 8/10 Web APIs, Azure-hosted services, microservices, and on-prem systems.
We will cover:
- Why send email using a shared mailbox
- Creating the shared mailbox
- Setting up an Azure App Registration
- Granting Graph API permissions
- Creating a Distribution Group
- Creating an Application Access Policy
- Setting mailbox permissions for users
- C# implementation using Microsoft Graph SDK
- Advantages of this approach
Let’s get started.
Why Use a Shared Mailbox Instead of a Regular User Account?
A shared mailbox is ideal for system emails:
- No license required
- Not tied to a specific employee
- Centralized and auditable
- Can be managed by admins
- Supports “Send As” and “Send on Behalf”
- Works perfectly with Microsoft Graph
By combining a shared mailbox with an Azure App Registration, your backend app can send emails without storing passwords, without SMTP, and without MFA issues.
Step 1 — Create a Shared Mailbox
In the Microsoft 365 Admin Center:
Teams & Groups → Shared Mailboxes → Add a shared mailbox
Example:
- Name: No Reply
- Email: no-reply@yourdomain.com
Shared mailboxes do not have passwords or logins.
Step 2 — Create an App Registration in Azure
Go to Azure Portal → Azure Active Directory → App registrations → New registration
- Name: MindAurora Email Service
- Type: Accounts in this organization directory only
- No redirect URI needed
After creation, save:
- Client ID
- Tenant ID
Generate a Client Secret:
Azure AD → App → Certificates & Secrets → New client secret
Store securely (KeyVault recommended). Make sure you store the secret somewhere as you can only see it once in the Azure Portal.
Step 3 — Add Graph API Application Permissions
Go to:
Azure AD → App → API Permissions → Add permission → Microsoft Graph → Application
Add:
- Mail.Send
Click Grant admin consent.
❗Important
Use Application permissions, not delegated.
Backend services should not impersonate a logged-in user.
Step 4 — Create a Mail-Enabled Security Group
Application Access Policies cannot be assigned directly to mailboxes.
They must target a mail-enabled security group.
In Microsoft 365 Admin Center:
Teams & Groups → Add group
- Type: Security
- Name: MailSenders
- Email: mailsenders@yourdomain.com
- Enable “Mail Enabled”
Then add the shared mailbox as a member:
no-reply@yourdomain.com
Step 5 — Create an Application Access Policy
This step tells Exchange:
“This App Registration is allowed to access only the mailboxes in this group.”
Open PowerShell:
Install-Module ExchangeOnlineManagement
Connect-ExchangeOnline
Create policy:
Where ‘PolicyScoreGroupId’ is the name of the Mail-Enabled Security group/
New-ApplicationAccessPolicy `
-AppId "<CLIENT-ID>" `
-PolicyScopeGroupId "mailsenders@yourdomain.com" `
-AccessRight RestrictAccess `
-Description "Allow app to send mail via no-reply shared mailbox"
Test:
Test-ApplicationAccessPolicy `
-Identity no-reply@yourdomain.com `
-AppId "<CLIENT-ID>"
Expected:
AccessCheckResult : Granted
Step 6 — (Optional) Grant Mailbox Permissions to Users
If people also need to send from this mailbox manually, or see the mailbox, you need to use powershell to give acces.
❗Important: Never do this via Microsoft Portal, always use PowerShell. If you use the Microsoft Portal you can break the permissions for your App Registration.
PowerShell:
Add-MailboxPermission -Identity sharedmailbox@yourdomain.com -User UserIdFromPortal -AccessRights FullAccess
Step 7 — C# Integration Using Microsoft Graph SDK
Install package:
dotnet add package Microsoft.Graph
dotnet add package Azure.Identity
Code:
using Azure.Identity;
using Microsoft.Graph;
public class EmailService
{
private readonly GraphServiceClient _graph;
public EmailService(string tenantId, string clientId, string clientSecret)
{
var credential = new ClientSecretCredential(tenantId, clientId, clientSecret);
_graph = new GraphServiceClient(credential);
}
public async Task SendEmailAsync()
{
var message = new Message
{
Subject = "Hello from the shared mailbox",
Body = new ItemBody
{
ContentType = BodyType.Html,
Content = "<h1>Hello World!</h1><p>This email was sent from a .NET 10 API.</p>"
},
ToRecipients =
[
new Recipient
{
EmailAddress = new EmailAddress
{
Address = "recipient@example.com"
}
}
]
};
await _graph.Users["no-reply@yourdomain.com"]
.SendMail
.PostAsync(new Microsoft.Graph.Users.Item.SendMail.SendMailPostRequestBody
{
Message = message,
SaveToSentItems = true
});
}
}
This sends an email as the shared mailbox, using only the App Registration credentials.
No passwords.
No SMTP.
No MFA issues.
No local Outlook profiles.
Advantages of This Approach
✔ 1. No passwords — ever
Using the Graph API + App Registration avoids storing or emailing credentials.
✔ 2. MFA safe
MFA breaks SMTP, but Application Permissions with Graph are fully compatible.
✔ 3. Secure and compliant
Application Access Policies enforce least privilege, limiting mailbox access.
✔ 4. Works from any environment
Docker, Azure Functions, Kubernetes, IIS, Windows services — all supported.
✔ 5. Centralized identity and auditing
Shared mailbox activity is trackable in Microsoft 365 compliance logs.
✔ 6. No user dependency
If an employee leaves, your app still works.
✔ 7. Future-proof
SMTP AUTH is being phased out; Graph API is the modern replacement.