---
title: ApplicationAccessPolicy won't scope to a shared mailbox — use a mail-enabled security group
short-title: ApplicationAccessPolicy rejects a shared mailbox
summary: "\"not a security principal\"; scope app-only `Mail.Send` to a mail-enabled security group"
tags: [graph, exchange-online, mail-send, permissions, powershell, shared-mailbox]
applies-to: Exchange Online, Microsoft Graph (application permissions), ExchangeOnlineManagement PowerShell
last-reviewed: 2026-10-09
---

# `ApplicationAccessPolicy` won't scope to a shared mailbox

> **Bottom line.** After granting an app the application-level `Mail.Send` permission it can send as *anyone* in the tenant, so you fence it in with `New-ApplicationAccessPolicy`. Passing the shared mailbox as `-PolicyScopeGroupId` fails with `The identity of the policy scope is not a security principal.` — a shared mailbox has a disabled account and isn't one. Put the mailbox in a **mail-enabled security group** and scope the policy to that group instead.
>
> **Ve zkratce.** Když aplikaci udělíte aplikační oprávnění `Mail.Send`, může odesílat za **kohokoli** v tenantu – proto se rozsah omezuje přes `New-ApplicationAccessPolicy`. Předání sdílené schránky jako `-PolicyScopeGroupId` skončí chybou `The identity of the policy scope is not a security principal.`, protože sdílená schránka má zakázaný účet a principal to není. Vložte schránku do **mail-enabled security group** a policy nasměrujte na tu skupinu.

## Symptom

You created a shared mailbox for an unattended sender (`support@`, `noreply@`) and want the app restricted to it:

```powershell
New-ApplicationAccessPolicy -AppId <appId> `
  -PolicyScopeGroupId support@contoso.com `
  -AccessRight RestrictAccess -Description "Mailer - support mailbox only"
```

```
New-ApplicationAccessPolicy: ||The identity of the policy scope is not a security principal.
```

Using the mailbox GUID (`ExternalDirectoryObjectId`) instead of the SMTP address fails the same way.

## Cause

`-PolicyScopeGroupId` accepts a **security principal**: a mail-enabled security group, a Microsoft 365 group, or a regular user mailbox. A shared mailbox is backed by a *disabled* user account, so Exchange refuses it as a policy scope.

Waiting doesn't help either. A freshly created mailbox also emits `An error occurred while trying to prepopulate newly created mailbox … Error: 0x8004010F` warnings, which look like a replication delay and tempt you into retrying for a while — but the rejection is by design, not a timing issue.

## Fix

Wrap the mailbox in a mail-enabled security group and scope the policy to the group:

```powershell
$smtp  = "support@contoso.com"
$appId = "<application (client) id>"
$group = "Mailer Scope"

# 1) mail-enabled security group holding every mailbox the app may send as
New-DistributionGroup -Name $group -Type Security `
  -PrimarySmtpAddress "mailer-scope@contoso.com"
Add-DistributionGroupMember -Identity $group -Member $smtp

# 2) scope the app to that group
New-ApplicationAccessPolicy -AppId $appId `
  -PolicyScopeGroupId "mailer-scope@contoso.com" `
  -AccessRight RestrictAccess -Description "Mailer - scoped senders only"

# 3) verify BOTH directions - a policy you never tested is a policy you don't have
Test-ApplicationAccessPolicy -Identity $smtp -AppId $appId              # Granted
Test-ApplicationAccessPolicy -Identity ceo@contoso.com -AppId $appId    # Denied
```

Adding another allowed sender later is then group membership, not a second policy.

Propagation takes up to about an hour. Right after the change, a `403` from `sendMail` is expected — wait before you debug it.

## Related traps in the same job

**A shared mailbox needs no licence.** `New-Mailbox -Shared` gives you up to 50 GB for free and app-only `Mail.Send` works against it normally — the right home for an unattended `support@` sender.

**Exchange sessions don't survive between separate shell invocations.** `Connect-ExchangeOnline` lives in process memory only. If your automation runs each command in a fresh process, connect **and** run the commands in one invocation; `Connect-AzAccount` behaves differently because it persists its context to disk.

**You may not need a second interactive sign-in for Graph.** If you're already signed in with Azure PowerShell as an administrator, `Get-AzAccessToken -ResourceUrl "https://graph.microsoft.com"` often returns a token whose `scp` already covers `Application.ReadWrite.All` and `AppRoleAssignment.ReadWrite.All` — enough to create the app registration and grant admin consent over REST. Decode the payload and check `scp` before relying on it. The token comes back as a `SecureString`; unwrap it with `[System.Net.NetworkCredential]::new("", $token).Password`.

**Function App settings are written as a whole set.** `PUT …/config/appsettings` replaces everything. Read the current settings, merge your keys in, then write — and afterwards verify the pre-existing keys are still present. Writing only the new keys wipes the rest.

## Adding a second sender later

**The sender must be a mailbox.** `/users/{address}/sendMail` works for user and shared mailboxes only. A distribution list such as `info@` cannot be the sender; check `Get-Recipient <address> | Select RecipientTypeDetails` before you put the address into configuration.

**Extend the scope by group membership, not by a new policy.** Add the new mailbox to the mail-enabled security group the policy points at. If the `*-ApplicationAccessPolicy` cmdlets are missing from your Exchange Online session (they were absent for a Global Administrator in ExchangeOnlineManagement 3.10 while the policy was still enforced), find the group by its members: list `Get-DistributionGroup -RecipientTypeDetails MailUniversalSecurityGroup` and pick the one that already contains the working sender mailbox.

**Until the change propagates, Graph keeps answering 403** with `Access to OData is disabled: [RAOP] : Blocked by tenant configured AppOnly AccessPolicy settings.` In our case it still failed after 15 minutes and passed after about an hour. Test once after an hour instead of in a loop, especially when each test creates real records or e-mails.
