Skip to main content

Outlook Application Access (Client Credentials)

This guide shows you how to set up application-level access to Microsoft 365 mailboxes using the OAuth2 client credentials flow. This allows EmailEngine to access any mailbox in your organization without interactive user logins. The outlookService provider that implements it is available since EmailEngine v2.65.0.

Overview​

What is Application Access?​

Application access uses the OAuth2 client credentials grant to authenticate as the application itself, rather than on behalf of a signed-in user. The application receives its own identity and permissions, and can access any mailbox that the admin has authorized.

Application Access vs Delegated Access​

EmailEngine supports two types of Outlook OAuth2 integrations:

FeatureApplication AccessDelegated Access
AuthenticationApp authenticates as itself (client credentials)User signs in interactively
User InteractionNone requiredEach user must complete OAuth2 login
PermissionsApplication permissions with admin consentDelegated permissions with user consent
Mailbox AccessAny mailbox in the organizationOnly the signed-in user's mailbox
Email BackendMS Graph API onlyIMAP/SMTP or MS Graph API
Account SetupREST API onlyHosted auth form or REST API
Tenant RequirementSpecific tenant ID requiredCan use "common", "organizations", or tenant ID
Best ForAutomated systems, shared mailboxes, complianceUser-facing apps, individual accounts

For delegated access setup, see Setting Up Outlook and Microsoft 365.

When to Use Application Access​

Best For:

  • Enterprise Microsoft 365 deployments with centralized management
  • Accessing shared mailboxes or multiple user mailboxes
  • Automated workflows without user interaction (helpdesk, compliance, archiving)
  • Service integrations where interactive login is not possible
  • Systems that need to monitor or process email across an organization

Not Suitable For:

  • Personal Microsoft accounts (@hotmail.com, @outlook.com, @live.com)
  • Applications where users should individually control access
  • Scenarios requiring IMAP/SMTP protocols (application access uses MS Graph API only)

Benefits and Limitations​

Benefits​

No User Consent Required:

  • Access granted by admin once for the entire organization
  • No OAuth2 login flow for each user
  • No interactive login for any mailbox in the tenant

Centralized Management:

  • Admin controls all access from Azure portal
  • Easy to revoke for the entire organization
  • Audit trail via Azure AD sign-in logs

Scalability:

  • Add new mailboxes without re-authentication
  • Access any user's mailbox with the same app credentials
  • Ideal for enterprise deployments

Limitations​

Microsoft 365 Only:

  • Does not work with personal Microsoft accounts
  • Requires a paid Microsoft 365 subscription

Requires Admin Consent:

  • Must have Azure AD admin privileges
  • Cannot be delegated to non-admin users

MS Graph API Only:

  • Application access uses the MS Graph API backend exclusively
  • IMAP/SMTP protocols are not available with client credentials

Organization-Scoped:

  • Only works for mailboxes in your Microsoft 365 organization
  • Cannot access external accounts

Client Secret Expiration:

  • The Azure portal issues client secrets with a lifetime of up to 24 months
  • Must be rotated before expiration to avoid service disruption

Step 1: Create Azure AD Application​

Go to Azure Portal and navigate to Microsoft Entra ID > App Registrations.

Click New registration.

Application Name​

Choose a descriptive name (e.g., "EmailEngine Application Access").

Supported Account Types​

Select "Accounts in this organizational directory only" (single tenant). Application access requires a specific tenant, so multi-tenant configurations are not applicable.

Redirect URI​

Leave the redirect URI empty. The client credentials flow does not use redirects.

Click Register to create the application.

Copy Application (Client) ID​

On the application overview page, copy the Application (client) ID. You will need this when configuring EmailEngine.

Copy Directory (Tenant) ID​

Also copy the Directory (tenant) ID from the overview page. Unlike delegated access which can use "common" or "organizations", application access requires the specific tenant ID.

Tenant ID Required

Application access always requires a specific tenant ID. You cannot use "common", "organizations", or "consumers" as the authority value. The tenant ID is a UUID like f8cdef31-a31e-4b4a-93e4-5f571e91255a.

Step 2: Configure Application Permissions​

Click API permissions in the left menu.

By default, only the User.Read delegated permission exists. Remove it and add application permissions instead.

Click Add a permission > Microsoft Graph > Application permissions.

Add the following permissions:

  • Mail.ReadWrite - Read and write mail in all mailboxes
  • Mail.Send - Send mail as any user
  • User.Read.All - Read all users' profiles (needed for mailbox resolution)
Application Permissions, Not Delegated

Make sure you select Application permissions, not Delegated permissions. These are in separate tabs when adding permissions. Application permissions apply to the app itself and require admin consent. Delegated permissions apply on behalf of a signed-in user and are used in the delegated access flow.

After adding the permissions, click Grant admin consent for [Your Organization].

This step is mandatory for application permissions. Unlike delegated permissions where users can consent individually, application permissions must be explicitly approved by an Azure AD administrator.

Verify that all three permissions show a green checkmark under the "Status" column, indicating admin consent has been granted.

Step 4: Create Client Secret​

Click Certificates & secrets in the left menu.

Click New client secret.

Description: Give it a meaningful name (e.g., "EmailEngine Secret")

Expires: Choose an expiration period. The Azure portal offers up to 24 months.

Copy Secret Immediately

The secret value is only shown once. Copy it immediately after creation - you cannot retrieve it later. If you lose it, you must generate a new secret.

Copy the value from the Value column (not the "Secret ID").

Secret Expiration Reminder

Set a calendar reminder to rotate the client secret before it expires. When the secret expires, all accounts using this OAuth2 application will fail to authenticate until a new secret is configured in EmailEngine.

Step 5: Configure EmailEngine​

Now configure EmailEngine to use the Azure application for mailbox access.

Add Outlook (application) OAuth2 Application​

  1. Open the EmailEngine dashboard
  2. Navigate to Integrations > OAuth2 Apps
  3. Click Create OAuth2 app
  4. Select Outlook (application)

Configure OAuth2 Settings​

Application name: Give it a descriptive name (e.g., "Outlook Application Access")

Base scope: Fixed to MS Graph API, the only mode application access supports. The card also lists the two endpoints Microsoft Graph posts change notifications to

Application (client) ID: Paste the Application (client) ID from Azure

Client secret: Paste the secret value you copied earlier

Azure cloud environment: Select your Microsoft cloud environment (default: Azure global service)

Directory (tenant) ID: Paste the Directory (tenant) ID from Azure. This must be the specific tenant UUID; the API field is authority.

No Redirect URL

Unlike delegated access, application access does not require a redirect URL. The client credentials flow authenticates directly with Azure without browser redirects.

Click Register app to save.

Find Your App ID​

After registering, note the App ID displayed in the OAuth2 application list. This is a base64url-encoded identifier (e.g., AAABkTn2CRQAAAAB) that you need when adding accounts via the API.

You can also find it via the API:

curl https://emailengine.example.com/v1/oauth2 \
-H "Authorization: Bearer YOUR_EMAILENGINE_TOKEN"

Verify the Setup​

Before adding accounts, use the Verify setup button on the OAuth2 app's page (or POST /v1/oauth2/{app}/verify, both since v2.68.0) to test the configuration. The verifier obtains a client-credentials token and - if you provide a test mailbox address - reads that user's id, mail, and userPrincipalName from Microsoft Graph, which is what User.Read.All is granted for. Each step is reported as passed, failed, or skipped with a hint for fixing failures.

Step 6: Add Email Accounts​

The hosted authentication form is not available for application access because there is no interactive user login. Instead, add accounts either through the REST API or directly from the admin dashboard.

Add Account via the Admin UI​

The OAuth2 app's detail page in the EmailEngine dashboard provides an Add account button (since v2.68.0) that opens a dialog asking for the full name, the email address, and an optional account identifier, and registers the account directly - no API call needed. Leave the identifier blank to have one generated.

Add Account via API​

Add accounts using the Register Account API endpoint:

curl -X POST https://emailengine.example.com/v1/account \
-H "Authorization: Bearer YOUR_EMAILENGINE_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"account": "user123",
"name": "John Doe",
"email": "john@contoso.com",
"oauth2": {
"provider": "AAABkTn2CRQAAAAB",
"auth": {
"user": "john@contoso.com"
}
}
}'

Replace AAABkTn2CRQAAAAB with your actual App ID from EmailEngine.

Key points:

  • No accessToken or refreshToken needed - EmailEngine obtains tokens automatically via client credentials
  • The auth.user field specifies which mailbox to access
  • The email field should match the mailbox email address
  • EmailEngine handles token acquisition and renewal automatically

Response:

{
"account": "user123",
"state": "new"
}

The account should transition to the "connected" state within moments.

Add Multiple Accounts​

You can add any mailbox in your organization using the same App ID:

# Add multiple accounts (replace APP_ID with your actual App ID)
curl -X POST https://emailengine.example.com/v1/account \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"account": "sales-1",
"email": "alice@contoso.com",
"oauth2": {
"provider": "AAABkTn2CRQAAAAB",
"auth": { "user": "alice@contoso.com" }
}
}'

curl -X POST https://emailengine.example.com/v1/account \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"account": "sales-2",
"email": "bob@contoso.com",
"oauth2": {
"provider": "AAABkTn2CRQAAAAB",
"auth": { "user": "bob@contoso.com" }
}
}'

Verify Accounts​

Check the account status:

curl https://emailengine.example.com/v1/account/user123 \
-H "Authorization: Bearer YOUR_TOKEN"

The account should show "state": "connected" when successfully linked.

Shared Mailboxes​

Application access suits shared mailboxes: use the shared mailbox address as the auth.user value.

curl -X POST https://emailengine.example.com/v1/account \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"account": "support-inbox",
"email": "support@contoso.com",
"oauth2": {
"provider": "AAABkTn2CRQAAAAB",
"auth": { "user": "support@contoso.com" }
}
}'

No additional delegation configuration is needed - the application permissions grant direct access to all mailboxes.

Cloud Environments​

EmailEngine supports multiple Microsoft cloud environments. Select the appropriate cloud in the Azure cloud environment field when creating the OAuth2 application to use the correct authentication and API endpoints. Client credentials request the single scope {graph-endpoint}/.default, so the cloud decides which Graph endpoint that is.

CloudValueUse Case
Azure global serviceglobalStandard Microsoft 365 (default)
GCC Highgcc-highUS Government L4
DoDdodUS Department of Defense L5
Azure ChinachinaChina (operated by 21Vianet)

The Entra ID and Microsoft Graph endpoints behind each value are listed under Microsoft cloud environments on the delegated access page.

Configuring Cloud Environment via API​

When creating the OAuth2 application via the API, specify the cloud parameter:

curl -X POST "https://emailengine.example.com/v1/oauth2" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Outlook Application Access (GCC High)",
"provider": "outlookService",
"enabled": true,
"cloud": "gcc-high",
"clientId": "YOUR_CLIENT_ID",
"clientSecret": "YOUR_CLIENT_SECRET",
"authority": "YOUR_TENANT_ID"
}'

redirectUrl is not needed, and baseScopes, extraScopes, and skipScopes are ignored for this provider.

Government Cloud Registration

For government clouds (GCC High, DoD) and sovereign clouds (China), you must:

  1. Register your Azure AD application in the corresponding Azure portal for that cloud environment
  2. Your organization must have a subscription in that cloud environment
  3. Use the correct Azure portal URL for app registration

You cannot use an app registered in the global Azure portal for government or China cloud environments.

Account Management​

Listing Accounts​

Application access accounts appear like any other OAuth2 account:

curl https://emailengine.example.com/v1/accounts \
-H "Authorization: Bearer YOUR_TOKEN"

Updating Accounts​

Update account settings using the Update Account API endpoint:

curl -X PUT https://emailengine.example.com/v1/account/user123 \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "John Doe (Updated)"
}'

Deleting Accounts​

Delete accounts using the Delete Account API endpoint:

curl -X DELETE https://emailengine.example.com/v1/account/user123 \
-H "Authorization: Bearer YOUR_TOKEN"

Security Best Practices​

Client Secret Management​

Do:

  • Store client secrets in secret management systems (Azure Key Vault, AWS Secrets Manager, HashiCorp Vault)
  • Set calendar reminders for secret rotation before expiration
  • Use separate Azure AD applications for different environments (dev/staging/prod)
  • Monitor Azure AD sign-in logs for unusual activity

Don't:

  • Commit secrets to version control
  • Share secrets via email or chat
  • Use the same secret across multiple environments
  • Ignore expiration warnings

Permission Scope​

Principle of Least Privilege:

  • Mail.ReadWrite, Mail.Send, and User.Read.All are the minimum required permissions
  • Review permissions periodically and remove any that are no longer needed
  • Consider using separate applications for read-only and read-write access patterns
  • Document why each permission is needed for compliance audits

Monitoring​

  • Enable Azure AD audit logs for the application
  • Monitor EmailEngine account states for authentication errors
  • Set up alerts for client secret expiration (Azure AD notifies admins)
  • Review the list of accessed mailboxes regularly
Enable Field Encryption

By default, EmailEngine stores credentials in cleartext in Redis. To protect sensitive data like client secrets, enable field encryption. See Setting Up Encryption for configuration instructions.

Change Notifications​

Application access accounts sync through Microsoft Graph change notifications, like every account on the MS Graph API backend. EmailEngine creates a subscription per mailbox, renews it on an hourly pass, recovers notifications Microsoft reports as missed, and reports a mailbox it can no longer subscribe to as a connectError with the code SubscriptionSetupError (since v2.80.0). The two endpoints Microsoft must reach, the subscription lifetime and retry schedule, the recovery of missed notifications and the outlookSubscription field of the account response are described under MS Graph API Backend on the delegated access page.

Public HTTPS Required

Microsoft validates the notification URL when the subscription is created, and there is no polling fallback for MS Graph accounts. If your EmailEngine instance is behind a firewall or on a private network, configure a reverse proxy or a tunnel so that {serviceUrl}/oauth/msg/notification and {serviceUrl}/oauth/msg/lifecycle are reachable from Microsoft's servers; until they are, no new mail is detected.

Official Microsoft Documentation​

For the most up-to-date information, refer to Microsoft's official documentation:

Client Credentials Flow​

Application Permissions​

See Also​