Microsoft 365 service principal best practices
How to design, deploy, and operate service principals safely — credentials, permissions, and lifecycle.
Service principals in Microsoft Entra ID are the non-human identities used by applications, scripts, and integrations. They typically outnumber human users 10:1 in mature tenants, hold significant permissions, and are increasingly the target of attacks. Designed well, they're a non-issue; designed badly, they're a major attack surface.
What service principals are
Every application integrated with Entra ID — internal apps, third-party SaaS apps consented to, custom scripts using Graph — has:
- An app registration in the application's home tenant (defining the app).
- A service principal in each consuming tenant (the app's instance there).
The service principal holds:
- Permissions granted to the app.
- Client secrets or certificates for authentication.
- Role assignments if applicable.
- Sign-in activity logs.
The risks
Service principals are attack targets because:
- They often hold broad permissions — read mail, read all files, modify users.
- They typically use static credentials that don't rotate often.
- They often lack MFA — they're non-interactive.
- They're frequently overlooked — humans get periodic credential rotation; service principals don't.
- A compromised service principal acts continuously without raising the alarms human compromise does.
A breach involving a service principal can be far more impactful than one involving a human account.
Authentication choices
Service principals authenticate via:
Client secrets (avoid where possible)
A shared secret — a password for the app. Issues:
- Stored in code or config — leaks happen.
- Don't rotate automatically — admins must remember.
- No expiration enforcement by default — secrets last forever.
Use only when the alternatives don't work.
Certificates
A certificate uploaded to the service principal:
- Stronger than secrets — harder to extract from configuration.
- Can have expiration properly tracked.
- Stored in certificate stores rather than code.
Better than secrets but still requires private-key management.
Federated credentials (the modern standard)
Workload identity federation trusts external token issuers — GitHub Actions, AWS, GCP, Kubernetes — to provide short-lived federated credentials:
- No long-lived credentials at all.
- GitHub Actions token federated with Entra trust → Entra issues access token → app calls Graph.
- No secrets to leak.
For modern app deployment scenarios (CI/CD pipelines, cloud-hosted workloads), federated credentials are the right answer.
Managed identities (for Azure-hosted workloads)
Azure VMs, Azure Functions, App Service, AKS, and other Azure compute can have managed identities — Entra automatically manages the credentials, the app uses them transparently. No secrets, no rotation, nothing to manage.
For any Azure-hosted Microsoft 365 integration, managed identities are the default choice.
Permissions hygiene
The most important principle: least privilege.
- Request only the scopes you need in the app registration.
- Use delegated permissions when the app acts on a user's behalf.
- Use application permissions only when the app needs tenant-wide access without a user.
- Audit consented permissions periodically.
A typical pattern: an automation script that "needs to read mail" often only needs to read a specific mailbox — Mail.Read.Shared for that mailbox rather than Mail.Read tenant-wide.
Lifecycle
For each service principal:
- Document its purpose — what app, what owner.
- Document its permissions — what scopes, granted by whom.
- Track its usage — sign-in logs show what it's actually doing.
- Periodic recertification — quarterly review of who still needs which service principals.
- Decommission cleanly — when the app retires, remove its service principal.
For mature tenants, access reviews for workload identities (Microsoft Entra Workload ID Premium) automate this.
Monitoring
Watch service-principal activity:
- Sudden permission grants to existing or new apps.
- Unusual sign-in patterns — service principal signing in from new IPs.
- High-volume operations — service principal suddenly reading thousands of users.
- Failed sign-ins — credentials compromised but not yet abused.
Defender for Cloud Apps has OAuth-app governance specifically for this; Defender XDR correlates service-principal events with broader incident signals.
Common pitfalls
- Client secret committed to code — github-leak scanners find these in seconds.
- Service principal with Global Administrator role — should never happen.
- App with
Directory.ReadWrite.AllandMail.ReadWriteand broad Sites permissions for "convenience" — massive blast radius. - No owner documentation — when something goes wrong, no one to ask.
- Forgotten service principals for apps that retired years ago.
Practical checklist
For every service principal:
- [ ] Owner documented.
- [ ] Purpose documented.
- [ ] Permissions minimised to least-privilege.
- [ ] Credentials are certificate / federated identity (not secret) where possible.
- [ ] Sign-in activity reviewed quarterly.
- [ ] Conditional Access policy applied (Workload ID Premium).
For Microsoft 365 customers, service-principal hygiene is one of the most overlooked but consequential security areas. Get it right; review regularly.