2025-08-05
Microsoft Graph App-Only Consent Explained

Ever set up a background job, hit “admin consent,” and hoped for the best? We unpack the full lifecycle for Microsoft Graph app-only access—app registration, permissions selection, admin consent flow, token acquisition, and ongoing monitoring—so your automations stay secure, reliable, and audit-ready.
Who This Is For
-
Azure AD / Entra ID admins and security engineers
-
M365 platform owners and SharePoint/Exchange/Teams admins
-
Developers building unattended services, Azure Functions, Logic Apps, or integrations
-
Compliance, audit, and governance teams
The Consent Gap (What Tutorials Skip)
-
Delegated vs Application: App-only = no user context; scopes apply tenant-wide once consented.
-
One-time consent, long-term impact: Broad roles (e.g.,
Sites.ReadWrite.All) persist until explicitly revoked. -
Policy changes break apps: Consent settings or Conditional Access tweaks can silently kill token acquisition.
-
Audit visibility is thin unless you intentionally log/review enterprise app permissions.
Least-Privilege First (Permission Selection)
-
Prefer narrow resource scopes over
*.ReadWrite.Allwhere possible. -
Examples to scrutinize:
-
Directory: Prefer
User.Read.All(basic profile) beforeDirectory.Read.All. -
SharePoint: Try site-scoped access patterns or app catalogs before
Sites.ReadWrite.All. -
Mail/Calendars: Use
Mail.Read/Calendars.Readunless write is truly required.
-
-
No “future-proofing” by over-scoping. Add scopes only when a feature demands it.
Registering the App the Right Way (Step-by-Step)
-
Register app in Entra ID → record Application (client) ID and Tenant ID.
-
Authentication: Choose client credential method:
-
Certificate (recommended) stored/rotated via Key Vault, or
-
Client secret (short lifetime + rotation policy), or
-
Managed identity (best in Azure-hosted workloads).
-
-
API permissions → Application tab → add minimal Graph scopes only.
-
Grant admin consent intentionally (document who/why/when).
-
Enterprise Apps: lock down assignment required, owners, and sign-in/audit logging.
Admin Consent, Policies, and Controls
-
Only privileged admins can grant application permissions.
-
Treat admin consent as risk acceptance: record purpose, data touched, expiry/renewal date.
-
Align with Tenant Restrictions, Permission Grant Policies, and Conditional Access for service principals.
Tokens in the Wild (How Auth Actually Fails)
-
Common breakages: expired secrets/certs, wrong resource (
.defaultscope), missing role, tenant mismatch. -
Harden token flow:
-
Use certificate creds or managed identity over long-lived secrets.
-
Rotate secrets/certs well before expiry (Key Vault reminders + automation).
-
Retry with backoff and surface 401/403 telemetry with correlation IDs.
-
Cache tokens per run—but never across tenants or beyond safe lifetimes.
-
Monitoring & Audit (Make It Audit-Ready)
-
Dashboards/alerts for: token failures, consent changes, new permissions added, inactive apps.
-
Quarterly reviews: enumerate enterprise apps, permissions, and last-used timestamps; remove stale registrations.
-
Log: who granted consent, date/time, justification, data domains impacted.
-
Key Vault: enable expiring-credential alerts and certificate auto-rotation where possible.
Minimal Permission Patterns (Starter Matrix)
-
User inventory/reporting →
User.Read.All -
Teams usage analytics →
Reports.Read.All -
Mailbox read-only export →
Mail.Read -
Calendar sync (read) →
Calendars.Read -
SharePoint read (broad) →
Sites.Read.All(avoidReadWriteunless mandatory) -
Profile sync to HR →
User.Read.All(+ specific write scopes only if truly required)
Rule of thumb: if the scope ends with
.ReadWrite.All, stop and re-evaluate. If you must, isolate the app, document the justification, and add extra monitoring.
Common Errors & Fast Fixes
-
invalid_client/invalid_grant→ expired secret/cert; rotate in Key Vault and redeploy. -
insufficient privileges to complete the operation→ missing Application permission or admin consent not granted in this tenant. -
403 on SharePoint with app-only → scope too broad or site-level access not aligned; verify site permissions/app catalog approach.
-
Intermittent 401s → Conditional Access or consent policy change; check sign-in and audit logs for the service principal.
Security & Compliance Guardrails
-
Segregate duties: different owners for app registration, consent approval, and ops.
-
Tag enterprise apps with data classification (e.g., touches HR, Finance, PHI).
-
PIM for consent granters; require ticket/change record for new scopes.
-
Purge unused apps and disable legacy auth endpoints.
-
Document data flows for each app; keep a one-page record per integration.
Quick FAQ
-
Do app-only permissions inherit user ACLs? No—app-only acts independently of user context.
-
Can a regular user grant app-only scopes? No—admin consent required.
-
Are tokens auto-expired with access revocation? Tokens expire quickly, but granted permissions persist until revoked.
-
Best auth choice? Managed identity (in Azure) or certificates + Key Vault; avoid long-lived secrets.
Action Plan (90-Minute Hardening Sprint)
-
Inventory enterprise apps + Graph application permissions.
-
Flag
*.ReadWrite.AllandDirectory.*apps for review. -
Rotate any secret expiring in <30 days; move to cert/managed identity where possible.
-
Enable alerts for consent changes and Key Vault expiry.
-
Write a one-pager per app: purpose, data touched, scopes, owner, rotation date.
-
Schedule quarterly review with SecOps + app owners.
Host: Mirko Peters