Get the Newsletter
Sign up for our newsletter because we provide best practices, insights and more about SecOps, Security Engineering and more!
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
* I'm putting this out there to get feedback - I'm sure I'm missing something. Please message us if you have any insights on better solving this. - JP
Anthropic's Claude — accessed through claude.ai, the Claude desktop app, Claude Code CLI, or the M365 MCP connector — is showing up across enterprise Mac fleets faster than most security teams can track it. Whether your organization wants to block Claude outright, allow it with guardrails, or simply understand who's using it and what data they're sharing, you need detection controls purpose-built for macOS.
This guide walks through a layered detection strategy using tools most M365 shops already own:
Each section below includes production-ready KQL queries, shell scripts, and policy configurations you can deploy today — along with callouts on macOS-specific gaps where Windows has better coverage as of today.
The most critical finding: Anthropic's M365 MCP connector creates two enterprise applications in your Entra tenant that, once consented, grant Claude delegated read access to mail, files, calendars, and Teams messages. This API-level data path bypasses every endpoint control in the stack, making consent governance arguably more important than blocking the browser. * This is not always bad, especially if you have Claude Teams or Enterprise which provide SAML/SCIM and more granular permissions and control over who can access what in your enviornment.
Four layers, converging into a unified incident queue:
Sentinel free ingest benefit: Sentinel is consumption-based (Azure), not included flat in any M365 license. However, Defender XDR security alerts and incidents (SecurityAlert,SecurityIncident) plusOfficeActivitylogs ingest for free. MDE custom detection alerts from the Claude queries in this guide flow in as free SecurityAlert records. Entra IDAuditLogsandSigninLogsare paid ingestion. Docs →
Upgrade paths from Business Premium: Defender Suite for Business Premium ($10/user/mo) adds MDE P2, MDCA, Defender for Identity, MDO P2, and Entra P2. For Purview capabilities (endpoint DLP, IRM, DSPM for AI), you need the Purview Suite for Business Premium add-on or M365 E5. Docs →
Navigate to Settings → Endpoints → Indicators → URLs/Domains and add claude.ai, anthropic.com, api.anthropic.com, cdn.claude.ai. Set action to Audit, Warn, or Block. Requires Network Protection in block mode and "Custom network indicators" enabled under Advanced features.
macOS caveat: For non-Edge browsers, MDE inspects the TLS ClientHello to extract FQDNs. QUIC and Encrypted Client Hello (ECH) must be disabled in Chrome/Firefox via Intune Settings Catalog profiles (QuicAllowed: false,EncryptedClientHelloEnabled: false), or traffic bypasses inspection.
Network connections to Claude:
DeviceNetworkEvents
| where Timestamp > ago(30d)
| where RemoteUrl has_any ("claude.ai", "anthropic.com", "api.anthropic.com")
| project Timestamp, DeviceName, RemoteUrl, InitiatingProcessFileName, \
InitiatingProcessAccountName, ReportId| order by Timestamp desc
Claude desktop app or Claude Code process execution:
DeviceProcessEvents
| where Timestamp > ago(30d)
| where FileName in~ ("Claude", "claude")
or FolderPath has_any ("/Applications/Claude.app", ".local/bin/claude")
or ProcessCommandLine has "@anthropic-ai/claude-code"
| project Timestamp, DeviceName, FileName, FolderPath, AccountName
| order by Timestamp desc
Usage summary by user (join network + process):
let Net = DeviceNetworkEvents | where Timestamp > ago(30d)
| where RemoteUrl has_any ("claude.ai","anthropic.com","api.anthropic.com")
| summarize Conn=count(), Last=max(Timestamp) by DeviceName, User=InitiatingProcessAccountName;
let Proc = DeviceProcessEvents | where Timestamp > ago(30d)
| where FileName in~ ("Claude","claude") or FolderPath has "/Applications/Claude.app"
| summarize Exec=count(), LastRun=max(Timestamp) by DeviceName, User=AccountName;
Net | join kind=fullouter (Proc) on DeviceName, User
| project DeviceName, User, Conn, Exec, Last, LastRun
Convert any query to a custom detection rule (hourly, severity Medium, MITRE T1567) for automated alerting.
Enable MDE ↔ MDCA integration → Cloud App Catalog → filter "Generative AI" → mark Claude as Unsanctioned. This pushes block indicators to all MDE endpoints automatically. App Governance monitors OAuth apps — create an OAuth policy matching "Claude" or "Anthropic" with "High privilege" → Generate alert.
*.claude.ai and *.anthropic.com are already in the built-in "Generative AI Websites" sensitive service domain group (1,500+ AI sites). Create an endpoint DLP policy targeting Devices: match sensitive info types → set Upload and Paste-to-browser actions to Block/Warn/Audit for the Generative AI group. Also add /Applications/Claude.app/Contents/MacOS/Claude as a restricted app.
macOS gaps: Paste-to-browser: preview on macOS (GA on Windows). Needs MDE client 101.25022.0003+. Chrome/Firefox Purview extensions: Windows-only. Mandate Edge on Mac for full DLP enforcement. Insider Risk Management browser signals: not supported on non-Windows devices — the biggest macOS gap.
DSPM for AI one-click policies: "Detect sensitive info added to AI sites" (audit-mode) and "Block sensitive info from AI sites" (Adaptive Protection integration) are the fastest path to baseline visibility.
Claude desktop app identifiers: bundle ID com.anthropic.claudefordesktop, path /Applications/Claude.app, App Store ID 6473753684.
Discovered Apps refreshes every 7 days. For faster detection, deploy a custom attribute script (runs every 8 hours):
#!/bin/bash
if [ -d "/Applications/Claude.app" ]; then
echo "Installed:$(defaults read /Applications/Claude.app/Contents/Info CFBundleShortVersionString 2>/dev/null)"
else echo "NotInstalled"
fi
For enforcement, deploy a daily removal script:
#!/bin/bash
if [ -d "/Applications/Claude.app" ]; then
pkill -f "Claude" 2>/dev/null; sleep 2
rm -rf "/Applications/Claude.app"
for u in /Users/*/; do
rm -f "${u}Library/Preferences/com.anthropic.claudefordesktop.plist"
rm -rf "${u}Library/Application Support/Claude"
rm -rf "${u}Library/Caches/com.anthropic.claudefordesktop"
done
fi
Chain a compliance policy (restricted apps or custom compliance) to Conditional Access — noncompliant devices lose access to Exchange, SharePoint, and Teams until Claude is removed. Conditional Access requires Entra ID P1 (included in both Business Premium and E3+).
The server app requests Mail.Read, Files.Read.All, Sites.Read.All, Chat.Read, ChannelMessage.Read.All, Calendars.Read, and more as delegated permissions.
Check your tenant: Entra admin center → Enterprise applications → search "Claude" or "MCP".
Set user consent to "Allow for verified publishers, selected permissions" → classify only User.Read and openid as Low impact under Permission classifications. Enable the admin consent workflow with designated reviewers. After installation, set "Assignment required?" = Yes on each Claude enterprise app and add only authorized users.
Detect consent to Claude apps:
let ClaudeIds = dynamic(["08ad6f98-a4f8-4635-bb8d-f1a3044760f0","07c030f6-5743-41b7-ba00-0a6e85f37c17"]);
AuditLogs
| where TimeGenerated > ago(1d)
| where OperationName in ("Consent to application","Add delegated permission grant",
"Add OAuth2PermissionGrant","Add service principal")
| mv-apply t = TargetResources on (
where t.type =~ "ServicePrincipal"
| extend AppName = tostring(t.displayName), AppId = tostring(t.id))
| where AppName has_any ("Claude","Anthropic","MCP") or AppId in (ClaudeIds)
| extend User = tostring(InitiatedBy.user.userPrincipalName)
| project TimeGenerated, OperationName, User, AppName, AppId, ResultDetect active MCP connector usage (sign-ins):
SigninLogs
| where TimeGenerated > ago(30d)
| where AppDisplayName has_any ("Claude","Anthropic","M365 MCP")
or AppId in ("08ad6f98-a4f8-4635-bb8d-f1a3044760f0",
"07c030f6-5743-41b7-ba00-0a6e85f37c17")
| project TimeGenerated, UserPrincipalName, AppDisplayName,
IPAddress, Location, ConditionalAccessStatus
Detect any app granted broad M365 permissions:
AuditLogs | where TimeGenerated > ago(7d)
| where OperationName == "Consent to application"
| mv-expand ModProps = TargetResources[0].modifiedProperties
| extend Prop = tostring(ModProps.displayName), Val = tostring(ModProps.newValue)
| where Prop == "ConsentAction.Permissions"
| where Val has_any ("Mail.Read","Files.Read.All","Sites.Read.All","Chat.Read")
| extend User = tostring(InitiatedBy.user.userPrincipalName),
App = tostring(TargetResources[0].displayName)
| project TimeGenerated, User, App, Val
Also enable Sentinel Content Hub built-in rules: "Rare application consent" and illicit consent grant templates.
M365 E5 covers everything except Sentinel's consumption pricing (and Defender XDR alerts ingest free). Business Premium provides network protection, Intune app inventory, and Entra consent governance — but not advanced hunting, endpoint DLP, MDCA, or IRM. The Defender Suite for Business Premium add-on bridges the gap for MDE P2 and MDCA.
macOS has real gaps: IRM browser signals are absent, paste-to-browser DLP is preview-only, and Chrome/Firefox Purview extensions are Windows-only. Mandate Edge + Network Protection as the foundation for Mac-heavy environments.
The MCP connector is the highest-priority detection surface. Its two app IDs requesting broad delegated permissions bypass all endpoint controls. Consent governance and Sentinel monitoring are the most strategically important controls in the stack.
Blue Cycle is a Microsoft Solution Partner with 6 specializations (4 Security, 2 Modern Work) and a MISA member. We deploy these exact controls for clients.
Book a security assessment , Microsoft Sentinel Health Check, or Copilot Readiness review→
Let’s talk about how Blue Cycle can help with your security operations.
Book an Assessment