Exchange mailbox delegation
The identity pane supports direct Full Access and delegation revocation for an Entra account. Live Send As grants are blocked in this candidate. Google Workspace and Active Directory report delegation as unsupported. Delegation is disabled by default and refuses in demo mode.
Full Access has separate positive evidence. The corrected live connector pilot at 09:13–09:14 UTC on 5 September passed an in-scope grant, repeated grant, revocation and an out-of-scope refusal with the five-command role. Independent cleanup followed. That result does not validate Send As grants or certify every school’s environment. Full Access and authorised revocations can be enabled after the environment-specific checks below; a blanket delegation shutdown is not required by the Send As containment.
On 8 September, the deployed RC2 staging UI also passed an in-scope Full Access grant and revoke, with a fresh identity check for each action. Independent Exchange reads confirmed the intended grant, no reverse/out-of-scope grant, and zero remaining direct test permissions after the UI revoke. Intent and completion audit rows matched both actions. Temporary consent, secret, role membership and staging credentials were removed. This is a bounded validation of the test environment; each school’s configuration still needs the checks below.
identity.mailbox.delegate permits either revocation. Full
Access grants also need identity.mailbox.fullaccess. Every request needs step-up,
the mailbox owner’s name or sign-in address typed by hand, and a reason of at
least ten characters. Both accounts are resolved live. The audit intent is saved
before Exchange is called. Grants are capped at ten per technician per hour;
revocations are exempt. These actions cannot be registered as AI or MCP tools.
Full Access allows reading private items. Send As lets the delegate send as the mailbox owner. Neither control removes rights inherited through groups. Auto-mapping defaults off and only applies when adding a new Full Access grant; an existing grant is reported unchanged. Exchange propagation can take time. If the process times out or its outcome cannot be confirmed, verify the direct permissions in Exchange before retrying. Plugboard does not automatically retry these writes.
Configure the school-owned credential
Section titled “Configure the school-owned credential”Follow Microsoft’s app-only authentication guide. Use a CSP certificate, not a Windows CNG certificate. For example, on Windows:
$exoCertificate = New-SelfSignedCertificate -DnsName '<school>.onmicrosoft.com' -CertStoreLocation 'cert:\CurrentUser\My' -NotAfter (Get-Date).AddYears(1) -KeySpec KeyExchange$exoPassword = Read-Host 'PFX password' -AsSecureString$exoCertificate | Export-PfxCertificate -FilePath './exo.pfx' -Password $exoPassword$exoCertificate | Export-Certificate -FilePath './exo.cer'Upload the public certificate to the existing app registration. Grant the Office 365 Exchange Online Exchange.ManageAsApp application permission and admin consent. The existing client secret remains in use for Graph reads.
Use a custom Exchange role group with only the cmdlets needed here:
Get-MailboxPermission, Add-MailboxPermission, Remove-MailboxPermission,
Get-RecipientPermission, Remove-RecipientPermission.
Do not grant Add-RecipientPermission while live Send As grants are blocked.
Determine their parent roles in the actual tenant using
Get-ManagementRoleEntry '*\<cmdlet>'; do not assume every cmdlet belongs to
Mail Recipients. Derive and reduce the appropriate roles, then verify the final
entry and parameter list before assigning the app’s Exchange service principal.
Use the enterprise application’s object ID, not the app registration object ID.
Microsoft documents the custom role-group procedure in the same guide.
New tenants may first require the one-time
Enable-OrganizationCustomization
operation before custom roles can be created. Allow provisioning to finish;
do not substitute a broad built-in role if custom-role creation is unavailable.
Set an explicit recipient write scope covering the intended test mailboxes first.
Without one the credential can modify every recipient allowed by its roles across
the tenant. A UserMailbox filter alone does not exclude sensitive staff mailboxes.
Do not use Organization Management, Recipient Management or an unmodified broad
parent role as a workaround for a missing cmdlet. Check for other role-group or
Entra role assignments that broaden this app’s effective access. Verify an
in-scope Full Access grant/revoke and an out-of-scope refusal using test
accounts, and retain the evidence. A recipient-filter lookup alone is not the
negative write test. Do not attempt a live Send As grant as an acceptance step.
In Admin → Connectors → Microsoft Entra ID, supply the primary
<school>.onmicrosoft.com organisation domain, base64 PFX and its password, then
keep mailbox delegation disabled for normal school use until that environment’s
acceptance checks pass. Enable it only for the authorised non-production pilot
while validating those checks. A saved certificate derives a public thumbprint on
the server; the PFX and password are encrypted in the vault. Partial credential
updates preserve existing Graph credentials. The connection test validates Graph
and the local certificate; it does not certify Exchange RBAC. Exchange checks
authentication and authorisation when an operation runs.
Accept the deployed environment
Section titled “Accept the deployed environment”Record the deployed version/image, service account, runtime versions, reviewed five-command role and target scope. Use authorised non-production mailboxes.
- Import the pinned module as the API service account and confirm its certificate can authenticate. A connector connection test alone is insufficient.
- Exercise Full Access grant, repeated grant and revoke through the deployed product. Independently verify the permissions after each step, then confirm the same app refuses an out-of-scope Full Access write.
- Check role permissions, step-up, typed confirmation and reason in the actual UI/API. Confirm an audit intent and the actual outcome for successful, unchanged, refused and uncertain results. A direct connector pilot does not prove these deployed UI and audit paths.
- Confirm live Send As grant is unavailable/refused without a provider write. Its future Microsoft boundary test is separate work and is not enabled by this checklist. Revocation remains subject to Exchange permissions; keep an independent administrator available for cleanup outside the app’s scope.
- Independently remove test permissions and verify cleanup. Retain evidence without PFX material, tokens or real mailbox content before allowing school use.
Rotation and revocation
Section titled “Rotation and revocation”An hourly local certificate check marks the connector unhealthy when the certificate is invalid or has fewer than fourteen days left. It does not query Exchange and cannot detect a role removed in Microsoft.
To rotate, upload the new public certificate in Entra, replace the PFX/password in connector settings, verify a scoped test operation, then remove the old public certificate in Entra. On suspected compromise, disable delegation in Plugboard, remove the compromised public certificate or app role assignment in Microsoft, review both Exchange and Plugboard audit logs, and explicitly remove any unwanted mailbox grants. Disabling the feature does not revoke existing mailbox access or invalidate a stolen credential; Microsoft-side revocation is required.
Native and source installs
Section titled “Native and source installs”The container includes the runtime. Native/source installs must separately install PowerShell 7.6.5, OpenSSL, and ExchangeOnlineManagement 3.10.1 so the API service account can execute/import them. Test as that service account, not only as the installer. These optional delegation dependencies are not downloaded by the native installer. Keep delegation disabled until runtime and live scoped RBAC checks pass.
Runtime and release checks
Section titled “Runtime and release checks”The runtime image pins PowerShell 7.6.5 and ExchangeOnlineManagement 3.10.1. The module download is SHA-256 checked. Children receive a minimal environment with PowerShell telemetry opt-outs, no application database or vault keys, fixed code and argument arrays, a sixty-second deadline, and bounded output. Each instance executes one operation at a time with a bounded queue.
Verify module import as the image’s node user, scan the final image including
vendored .NET dependencies, and record measured image size at release. Do not add
standing scan exclusions for PowerShell: any accepted finding needs a specific
CVE, owner, rationale and expiry; an expired acceptance blocks release.