OAuth scope sprawl, Conditional Access
coverage gaps.
30 synthetic Microsoft Graph-consented apps across MS 1P, ISV Tier 1, mid-market, and in-house · 6 detected anomaly patterns · Conditional Access coverage matrix · ed25519-signed hash-chained audit. Buyer-facing operator surface, browser-only, no live data.
App registry — Continental Banking tenant
30 synthetic Entra-registered apps across MS 1P, ISV Tier 1, mid-market SaaS, and in-house custom classifications. 7 are over-permissioned, unused, or have scope-creep, secret-expiry, or CA-policy coverage gaps. Auth type distinguishes app-only (non-user, no MFA — narrower trust boundary required) from delegated (user-context, falls under standard CA policies).
| App | Class | Auth | Highest-risk scope | Total scopes | Consented | Status |
|---|---|---|---|---|---|---|
| SharePoint Online | MS 1P | App-only + Delegated | Sites.FullControl.All | 22 | 2024-08-14 | Current |
| Microsoft Teams | MS 1P | Delegated | User.Read.All | 18 | 2024-08-14 | Scope creep |
| OneDrive for Business | MS 1P | Delegated | Files.ReadWrite.All | 14 | 2024-08-14 | Current |
| Exchange Online | MS 1P | App-only | Mail.ReadWrite | 9 | 2024-08-14 | Current |
| Power BI Service | MS 1P | Delegated | Dataset.Read.All | 8 | 2024-08-14 | Current |
| Power Automate | MS 1P | Delegated | Mail.Send | 11 | 2024-08-14 | Current |
| Azure DevOps | MS 1P | Delegated | User.Read | 4 | 2024-08-14 | Current |
| Defender for Cloud Apps | MS 1P | App-only | AuditLog.Read.All | 6 | 2024-08-14 | Current |
| Salesforce (Cloud Sync) | ISV Tier 1 | Delegated | Mail.Send + Calendars.Read | 7 | 2025-01-22 | Current |
| Slack Enterprise Grid | ISV Tier 1 | App-only | Files.Read.All | 5 | 2025-02-08 | Over-permissioned |
| Atlassian Cloud (Jira+Conf) | ISV Tier 1 | Delegated | User.Read | 3 | 2025-03-12 | Current |
| ServiceNow | ISV Tier 1 | App-only + Delegated | Mail.Send + Sites.Read.All | 6 | 2025-02-19 | Current |
| Datadog (M365 Audit Ingest) | ISV Tier 1 | App-only | AuditLog.Read.All | 4 | 2025-05-30 | Secret expiring |
| Splunk (O365 Audit Connector) | ISV Tier 1 | App-only | AuditLog.Read.All | 4 | 2025-04-08 | Current |
| Workday (Outlook Sync) | ISV Tier 1 | Delegated | Calendars.ReadWrite | 5 | 2025-01-15 | Current |
| Zoom (Calendar Bot) | ISV Tier 1 | Delegated | Calendars.ReadWrite | 3 | 2024-12-04 | Current |
| Box (Files Sync) | ISV Tier 1 | Delegated | Files.ReadWrite.All | 4 | 2025-02-22 | Current |
| DocuSign (Envelope Integration) | ISV Tier 1 | Delegated | Mail.Send + Files.ReadWrite.All | 5 | 2025-03-30 | Current |
| Calendly | Mid-market | Delegated | Calendars.Read | 2 | 2025-04-19 | Current |
| Loom | Mid-market | Delegated | Calendars.Read | 2 | 2024-11-08 | Unused 134d |
| Notion | Mid-market | Delegated | User.Read | 2 | 2025-05-02 | Current |
| Lattice | Mid-market | Delegated | User.ReadBasic.All | 3 | 2025-03-18 | Current |
| Lucidchart | Mid-market | Delegated | User.Read | 2 | 2024-12-12 | Unused 110d |
| PagerDuty | Mid-market | App-only | Mail.Send | 2 | 2024-09-22 | No CA policy |
| Greenhouse | Mid-market | Delegated | Mail.Send + Calendars.ReadWrite | 4 | 2025-02-04 | Current |
| Gong | Mid-market | Delegated | Calendars.Read | 2 | 2025-05-28 | Current |
| ContinentalDataPortal (Custom) | In-house | App-only | Sites.FullControl.All | 8 | 2025-05-29 | OVER-PERM CRIT |
| CB-Trust-Audit-Worker | In-house | App-only | AuditLog.Read.All | 3 | 2025-04-12 | Current |
| ContractsAI-Pilot | In-house | App-only | Files.ReadWrite.All | 5 | 2025-05-15 | No CA policy |
| SalesIntelExtractor | In-house | Delegated | User.Read.All + Mail.Read | 6 | 2025-05-22 | Scope creep |
Anomaly detector — 6 patterns surfaced
Patterns matched across all 30 apps: over-permissioned in-house custom apps, over-permissioned ISVs without DLP, unused-90d dormants, silent scope creep, secret-expiry without alert, Conditional Access coverage gaps. Each anomaly carries a specific regulatory anchor.
ContinentalDataPortal granted Sites.FullControl.All
ContinentalDataPortal is a small internal data-browsing tool that needs Sites.Read.All at most. It was registered with Sites.FullControl.All (app-only) — which means it could create, delete, or modify any SharePoint site in the tenant. Almost certainly an accidental scope grant from the dev registering the app without admin pushback. Reduce to Sites.Read.All within 5 business days.
Slack has Files.Read.All without DLP integration
Slack Enterprise Grid holds Files.Read.All at the tenant level (app-only). The intended use is for the Slack-Outlook calendar integration only. Combined with the lack of a Microsoft Purview DLP policy covering Slack channels, this scope is broader than the business need. Either narrow to Files.Read.Selected + add DLP, or document the wider scope as accepted residual risk in the Decision Card.
Loom + Lucidchart unused for 90+ days
Loom (last used 134 days ago) and Lucidchart (110 days ago) retain delegated calendar/user scopes but are operationally dead. Both were pilots that never expanded. Auto-revoke per CIS Control 5.6 (dormant credential / authorization) — 90-day cap on unused OAuth tokens is the industry baseline.
Microsoft Teams consented User.Read.All — only needs User.Read
Microsoft Teams client originally consented to User.Read only. During a Teams upgrade, a delegated User.Read.All scope was added (likely for the new "People" search panel). This expanded scope is now used by ALL Teams users — including those whose tenant doesn't require it. Pin the scope catalog to baseline + diff per quarterly review.
Datadog M365 audit-ingest client secret expires in 12 days
Datadog client secret used for the M365 audit-log ingest (AuditLog.Read.All app-only) is set to expire in 12 days. Datadog's connector falls back to silent ingestion failure when the secret expires — no alarm fires until audit log freshness lag exceeds 24h. Rotate immediately + update in Datadog connector config.
3 apps not covered by any CA policy
PagerDuty, ContractsAI-Pilot, and SalesIntelExtractor are NOT covered by any Conditional Access policy. That means: any user authenticated to the tenant can trigger these apps from any device, any location, without MFA. Apply the existing "Block legacy auth + require compliant device" policy to all 3 within the week.
Conditional Access coverage matrix
Conditional Access (CA) policies are the runtime enforcement layer over Entra app authorizations. Without a covering CA policy, an app can be used from any device, any location, by any user with a valid session — the consented scope is the ONLY guardrail. The App-coverage gap policy row highlights the 3 apps that need policy attachment within the week.
| Policy | State | Apps in scope | Conditions | Coverage |
|---|---|---|---|---|
| Require MFA for all users | Enabled | All apps | All locations | All apps · 30/30 |
| Block legacy authentication | Enabled | All apps | All locations | All apps · 30/30 |
| Require compliant device | Enabled (Intune) | Office 365 + Microsoft Teams + SharePoint Online | Untrusted networks | Selective · 8 apps |
| Block guest access to high-risk | Enabled | Exchange Online + SharePoint + Defender + ContinentalDataPortal | Guest tenants | Selective · 4 apps |
| Require Entra Verified ID for executives | Pilot | All apps | VP+ executive group | Pilot · 12 users |
| Block from non-allowed countries | Enabled | All apps | US + CA + EU + UK + JP only | Country-allowlist · 30/30 |
| Sign-in risk policy (block high-risk) | Enabled | All apps | Identity Protection signal | Adaptive · 30/30 |
| App-coverage gap policy | Recommended-only | PagerDuty + ContractsAI-Pilot + SalesIntelExtractor | Untrusted networks | 3 apps NOT covered |
Audit chain
Every consent grant, scope-creep detection, unused-revoke, secret-rotation event, CA-policy application, app-only anomaly, delegated-consent revocation, and high-risk-scope flag is emitted as a hash-chained event. Each event signs the prior event's hash, making the log tamper-evident.
Why this surface exists
Microsoft Graph permission scopes are the runtime trust boundary between every SaaS app and the M365 tenant. The runtime ops problem is not granting the scope at consent time — it's the silent drift after consent: unused-but-still-authorized apps, scope creep from in-place upgrades, client secrets expiring without alarm, Conditional Access policies that don't actually cover the apps that ship them. This surface makes that drift visible. The 6 anomaly patterns are the patterns that show up in every real B2B SaaS audit — over-permissioned in-house apps, unused dormants, scope creep, CA coverage gaps, secret-expiry silent-failures, and ISVs holding broader scopes than their use case.
Buyer: Microsoft 365 security teams · Entra admins · IAM teams running OAuth scope reviews · Compliance teams during SOX ITGC or CIS Microsoft 365 benchmark reviews · External auditors during evidence-collection windows.
Regulatory anchors: CIS Microsoft 365 Foundations Benchmark v3 · CIS Controls v8 5.6 + 6.7 + 8.5 · SOX ITGC · NIST 800-53 AC-2 + AC-6 + IA-5 · ISO 27001 A.9.2 + A.9.4 · Microsoft Zero Trust security baseline · Microsoft Purview DLP.
KG Suite tie-back: Every operator decision on this surface emits an audit-stream event (hash-chained, ed25519-signable). Vault-contract data classification follows the Decision Card v0.3 pattern (data_vault_targets + retention_envelope). Incident escalations match the AI Incident Card profile shape. Evidence bundles align with the AI Evidence Format spec.
Static-only doctrine: No backend. No login. No telemetry. All synthetic data is baked into this HTML page as JavaScript constants. Nothing leaves the tab. Frame as readiness / evidence / posture / controls / scaffolding — never "compliant" or "certified" without an externally-attested audit.