M365 Service Principle
Permissions for the M365 service principle
This document specifies the exact permissions required for the Microsoft 365 / Graph service principal PAA uses. Granting more than the listed permissions is unnecessary. Granting less will cause partial or complete scan failures.
Microsoft 365 / Graph Service Principal
Purpose
Used by Zero Trust Assessment, M365 Security scanning (CIS, CISA SCuBA, EIDSCA, Maester), and Identity Security scanning (service principal risks, managed identities, guest users, application registrations).
Where to Configure
Settings > Microsoft 365
Credential model — certificate, not a standing secret
PAA authenticates to Microsoft Graph with a certificate, not a long-lived client secret.
- During onboarding you provide a temporary client secret. PAA uses it once to provision a certificate, then discards it.
- The certificate’s private key is generated inside, and never leaves, PAA’s Key Vault. Only the public key is written to your app registration.
- PAA rotates the certificate automatically on a rolling schedule — there is no standing credential to expire, leak, or rotate by hand.
- You can revoke PAA’s access at any time by removing the certificate from the app registration or deleting the app registration entirely.
The single write permission this requires (Application.ReadWrite.OwnedBy) is scoped to the app registration PAA owns — its own, and only its own. It cannot read or modify any other application in your tenant. See the permission table below.
Required Microsoft Graph application permissions
All permissions below are application permissions (not delegated) and require admin consent. Every one is read-only except Application.ReadWrite.OwnedBy, which is self-scoped (it manages only PAA’s own certificate credential).
| Permission | Access | Used For |
|---|---|---|
Directory.Read.All | Read | Entra ID directory roles, users, groups, service principals, application registrations, managed identities, organization & domains |
Policy.Read.All | Read | Conditional Access policies, authentication-method / authorization / cross-tenant-access / app-management policies |
RoleManagement.Read.Directory | Read | Privileged Identity Management (PIM) role eligibility & assignment schedules, role-management policies |
AccessReview.Read.All | Read | Access review definitions and instances (requires Entra ID P2) |
DelegatedAdminRelationship.Read.All | Read | GDAP partner (delegated admin) relationships |
DelegatedPermissionGrant.Read.All | Read | OAuth2 delegated permission grants (consent-grant risk analysis) |
IdentityRiskyUser.Read.All | Read | Identity Protection risky users (requires Entra ID P2) |
AuditLog.Read.All | Read | Guest user last sign-in activity (stale external user detection) |
DeviceManagementManagedDevices.Read.All | Read | Intune managed device enrollment and compliance status |
DeviceManagementConfiguration.Read.All | Read | Intune device compliance policies, configuration profiles |
DeviceManagementApps.Read.All | Read | Intune app protection policies, managed applications |
SecurityEvents.Read.All | Read | Microsoft Defender security alerts and Secure Score |
SecurityIncident.Read.All | Read | Microsoft Defender XDR security incidents |
SharePointTenantSettings.Read.All | Read | SharePoint / OneDrive sharing and external-sharing settings |
Application.ReadWrite.OwnedBy | Write — self-scoped | Lets PAA manage only its own certificate credential (provision + auto-rotate). Cannot touch any other app registration. |
Missing a read permission does not fail the whole scan: PAA logs which data area was affected and continues with the data it could collect. Some checks gated on a missing permission report Skipped or Manual review rather than a result.
Additional grants for deep configuration collection
The onboarding script also provisions the following so that PAA’s deeper Exchange Online / Security & Compliance configuration collection works without a second admin-consent prompt later. They are read-oriented and bounded:
| Grant | Type | Used For |
|---|---|---|
Exchange.ManageAsApp | Office 365 Exchange Online app role | App-only access to Exchange Online / Security & Compliance configuration (transport rules, anti-phishing/spam, DLP) via Microsoft’s management endpoints |
| Global Reader | Entra ID directory role | Read-only directory role — the clean, enumerable lever for the configuration surfaces above |
Exchange.ManageAsApp grants management-endpoint access, not mailbox access — PAA reads configuration only and never reads message content. Global Reader is Microsoft’s built-in read-only administrative role.
How to onboard (recommended: onboarding script)
PAA ships an onboarding script (Setup-PaaOnboarding.ps1) that performs every step below idempotently — create the app registration, request admin consent for the permissions above, set the service principal as owner of its own app registration (required for self-scoped certificate management), and generate a short-lived bootstrap secret.
- Run the onboarding script as a Global Administrator and follow the prompts. It outputs the Application (client) ID, the temporary client secret, and your Directory (tenant) ID.
- In PAA Settings > Microsoft 365, enter the M365 Tenant ID, Client ID, and the temporary secret, then click Validate & Test Connection.
- PAA provisions a certificate in its Key Vault, registers the public key on the app, verifies certificate authentication, and discards the bootstrap secret. From this point all collection uses the certificate.
Test Connection verifies the credentials and reports which required permissions have been granted before you run a scan.
Manual alternative
If you prefer to register the app by hand: create the App Registration, add each Microsoft Graph application permission in the table above plus Application.ReadWrite.OwnedBy, add Office 365 Exchange Online > Exchange.ManageAsApp, Grant Admin Consent, assign the Global Reader directory role to the service principal, set the service principal as an owner of its own app registration, then create a temporary client secret and complete steps 2–3 above. PAA replaces that secret with a managed certificate on first connect.
What PAA does with this service principal
| Feature | Data Collected | Permissions Used |
|---|---|---|
| Zero Trust — Identity pillar | Conditional Access policies, named locations, authentication methods, directory role memberships, PIM configuration, risky users | Policy.Read.All, Directory.Read.All, RoleManagement.Read.Directory, IdentityRiskyUser.Read.All |
| Zero Trust — Devices pillar | Device compliance policies, app protection policies, EDR / compliance status | DeviceManagementConfiguration.Read.All, DeviceManagementApps.Read.All, DeviceManagementManagedDevices.Read.All |
| Zero Trust — Data pillar | SharePoint / OneDrive sharing settings, Teams governance, sensitivity & DLP policies | SharePointTenantSettings.Read.All, Policy.Read.All |
| Zero Trust — Security Operations pillar | Unified audit log status, Secure Score, Defender alerts and incidents | SecurityEvents.Read.All, SecurityIncident.Read.All |
| M365 Security — CIS Benchmark | Identity controls, Intune policies, Exchange config, SharePoint, Power BI governance | Most permissions |
| M365 Security — CISA SCuBA | Entra ID, Defender, Teams, Exchange hardening | Directory.Read.All, Policy.Read.All, SecurityEvents.Read.All |
| M365 Security — EIDSCA | Entra ID authorization, authentication, conditional access configuration | Policy.Read.All, Directory.Read.All |
| Identity Security — Service Principals & App Registrations | Credential expiry, app role assignments, federated identity credentials, external owners | Directory.Read.All |
| Identity Security — Managed Identities | App role assignments held by managed identities, RBAC roles | Directory.Read.All |
| Identity Security — Consent grants | OAuth2 delegated permission grants and over-consent risk | DelegatedPermissionGrant.Read.All |
| Identity Security — Guest Users | Privileged guests, stale external users, last sign-in | Directory.Read.All, AuditLog.Read.All |
| Identity Security — Directory Roles & Access Reviews | Service principals holding privileged Entra ID roles, access review coverage | Directory.Read.All, AccessReview.Read.All |
| Tenant Trust — Delegated Admin (GDAP) | Partner delegated-admin relationships into your tenant | DelegatedAdminRelationship.Read.All |
Notes
- Every permission is read-only except
Application.ReadWrite.OwnedBy, which is provably self-scoped — it can manage only the credential of the app PAA owns, and cannot read or modify any other application in your tenant. PAA does not modify any other M365 tenant configuration. - The durable credential is a certificate that PAA generates in its Key Vault and rotates automatically; the bootstrap secret you supply is discarded after first connect. There is no standing secret in steady state.
- Admin consent must be granted by a Global Administrator or Privileged Role Administrator.
AccessReview.Read.AllandIdentityRiskyUser.Read.Allrequire Entra ID P2. Without P2 the related checks return Manual review rather than failing.AuditLog.Read.Allis specifically required for guest user last sign-in dates. Without it, stale guest detection still runs but cannot report sign-in recency.- The service principal must be registered in the same tenant you are assessing. Cross-tenant assessment requires a separate App Registration in the target tenant.
Platform Architecture Authority — Crimson Owl Technologies Last updated: June 2026