Blog Post

Core Infrastructure and Security Blog
9 MIN READ

Hunting Local AI Tools on macOS with Microsoft Defender for Endpoint

Vytas_Boyev's avatar
Vytas_Boyev
Icon for Microsoft rankMicrosoft
Jul 14, 2026

AI tooling is moving fast. Developers are running models locally, agents are spinning up local servers, and frameworks are adding new ways to extend the endpoint with skills, tools, and memory. That creates a useful productivity surface, but it also presents new challenges for security and governance teams. 

A set of AI focused detection and protective Defender for Endpoint features are now in preview – Local AI Agent and MCP detection and inventory as well as AI Agent security posture– both announced in detail here on the Microsoft Defender XDR blog . 

Those capabilities are emerging, but defenders still need practical visibility now. The power of Microsoft’s XDR platform provides the capability to look at our endpoint telemetry and gather data from your existing environment today…. MDE already captures enough process, file, and network telemetry to start hunting for this activity with Advanced Hunting KQL. 

Why Focus on macOS? 

Many organizations have developers that have adopted macOS clients as development machines. 

Developers are a population that are positioned to take advantage of and use AI in the course of developing Frontier and next generation apps, agents, and capabilities. Which increases their attack surface while maintaining their attractiveness for targeted supply chain attacks. 

The capability to detect and have visibility on  local AI tool usage, MCP server usage, malicious skill files, or AI-specific abuse patterns such as prompt injection are top of mind topics that I encounter routinely with my customers that I support. 

This post walks through how I’d approach that problem: inventory first, then detect local AI servers, monitor skill/configuration files, and finally look for suspicious behavior that may indicate abuse. Keep in mind that though I am specifically addressing macOS in this post, the techniques can be shifted to Linux and other supported platforms through the power and flexibility of KQL and Advanced Hunting.  

Why local AI on macOS matters 

Most endpoint detection content has historically focused on malware, persistence, credential theft, and command execution. Local AI agents blur those lines. 

An AI agent running on a developer workstation may legitimately: 

  • Spawn shell commands. 
  • Read source files and configuration files. 
  • Write scripts. 
  • Start a local server. 
  • Pull packages or model files. 
  • Maintain memory or context in local markdown files. 

That same behavior can also become risky if the agent is compromised, misconfigured, or influenced by malicious instructions. 

For macOS, two local AI frameworks stand out in the telemetry patterns I reviewed: 

  • Ollama — a local LLM runtime that exposes a local API, commonly on port 11434. 
  • OpenClaw — an autonomous AI agent platform that uses a local gateway, commonly on port 18789. 

Both leave process, filesystem, and network artifacts that MDE can see. 

Start with inventory, not alerts 

Before turning anything into a detection rule, start by understanding where local AI tools already exist. 

The first useful question is simple: Which macOS devices are running AI tooling? 

A reporting query against DeviceProcessEvents can identify known AI-related processes such as ollama, openclaw, node, npx, codex, or claude-code. The important detail is that macOS platform filtering needs to come from DeviceInfo, as it is not present in the other KQL tables we will be using. 

A practical inventory pattern looks like this: 

KQL — macOS AI tool inventory 

DeviceInfo 
| where OSPlatform == "macOS" 
| distinct DeviceId 
| join DeviceProcessEvents on DeviceId 
| where Timestamp > ago(30d) 
| where ( 
    FileName in~ ( 
        "ollama", 
        "openclaw", 
        "ollama_llama_server", 
        "ollama-runner", 
        "mcp-server", 
        "codex", 
        "codex-cli", 
        "claude-code", 
        "npx", 
        "node", 
        "deno" 
    ) 
    or ProcessCommandLine has_any ( 
        "ollama", 
        "openclaw", 
        "ollama_llama_server", 
        "ollama-runner", 
        "mcp-server", 
        "codex", 
        "codex-cli", 
        "claude-code", 
        "npx", 
        "node", 
        "deno" 
    ) 
) 
| summarize 
    FirstSeen = min(Timestamp), 
    LastSeen = max(Timestamp), 
    ExecutionCount = count(), 
    DistinctUsers = dcount(AccountName) 
    by DeviceName, FileName, FolderPath 
| sort by LastSeen desc 
 

This gives you a baseline. Once you know what normal looks like, you can start asking more interesting questions: 

  • Which devices are running AI tools for the first time? 
  • Which users are adopting them? 
  • Which tools are approved? 
  • Which tools appeared without a change request or expected rollout? 

That baseline becomes the foundation for alerting. 

Detect first-time AI tool usage 

A good first alert is “new AI tool on a macOS device.” 

The key is to compare recent activity against historical activity by both device and tool name. If a Mac has already run OpenClaw but suddenly starts running Ollama, that should still be considered a new tool introduction. 

KQL — first-time AI tool usage on macOS 

DeviceProcessEvents 
| where Timestamp > ago(1d) 
| where FileName in~ ("ollama", "openclaw") 
    or ProcessCommandLine has_any ("ollama", "openclaw", "openclaw.mjs") 
| join kind=leftanti ( 
    DeviceProcessEvents 
    | where Timestamp between (ago(30d)..ago(1d)) 
    | where FileName in~ ("ollama", "openclaw") 
        or ProcessCommandLine has_any ("ollama", "openclaw", "openclaw.mjs") 
    | distinct DeviceId, FileName, ProcessCommandLine 
) on DeviceId, FileName, ProcessCommandLine 
| summarize 
    FirstSeen = min(Timestamp), 
    LastSeen = max(Timestamp), 
    Count = count() 
    by DeviceName, FileName, ProcessCommandLine, AccountName
| sort by LastSeen desc 

 

This may be a good daily custom detection candidate, especially in environments where AI tooling needs to be explicitly approved. 

Watch for local AI servers 

Local AI frameworks often expose services on localhost. That makes network telemetry useful even when the tool is only listening locally. 

Known ports worth watching: 

Tool 

Port 

Purpose 

Ollama 

11434 

Local HTTP API 

OpenClaw 

18789 

Local WebSocket gateway 

A targeted detection for those ports is straightforward: 

KQL — local AI server listener detection 

DeviceInfo 
| where OSPlatform == "macOS" 
| distinct DeviceId 
|join DeviceNetworkEvents on DeviceId 
| where Timestamp > ago(1d) 
| where ActionType == "ListeningConnectionCreated" 
| where LocalPort in (18789, 11434) 
| project 
    Timestamp, 
    DeviceName, 
    LocalIP, 
    Port = LocalPort, 
    ProcessName = InitiatingProcessFileName, 
    CommandLine = InitiatingProcessCommandLine, 
    User = InitiatingProcessAccountName 
| sort by Timestamp desc 

For broader hunting, enumerate localhost listeners and exclude known system services. This helps find new or less common MCP servers before they show up in a curated indicator list. 

Monitor AI skill and context files 

The next detection surface is the filesystem. 

AI agent frameworks increasingly use markdown-based instruction and context files. Examples include: 

  • SKILL.md 
  • SKILLS.md 
  • SOUL.md 
  • MEMORY.md 
  • AGENTS.md 

These files are powerful because they influence how the agent behaves. A malicious skill file can embed instructions, reference scripts, deliver payloads, or create persistence. 

A weekly reporting query can monitor creation and modification of these files: 

KQL — AI skill and context file monitoring 

DeviceInfo 
| where OSPlatform == "macOS" 
| distinct DeviceId 
|join DeviceFileEvents on DeviceId  
| where Timestamp > ago(7d) 
| where ActionType in ("FileCreated", "FileModified") 
| where tolower(FileName) in ( 
    "skill.md", 
    "skills.md", 
    "soul.md", 
    "memory.md", 
    "agents.md" 
) 
| project 
    Timestamp, 
    DeviceName, 
    FileName, 
    FolderPath, 
    ActionType, 

For alerting, I would focus on suspicious creators: curl, wget, python, bash, scp, or browser-downloaded files with FileOriginUrl populated. 

DeviceInfo 
| where OSPlatform == "macOS" 
|distinct DeviceId 
|join DeviceFileEvents on DeviceId 
| where Timestamp > ago(1d) 
| where ActionType == "FileCreated" 
| where tolower(FileName) in ("skill.md", "skills.md", "soul.md") 
| where InitiatingProcessFileName in ("curl", "wget", "python", "python3","bash", "sh", "zsh", "nscurl", "scp") or isnotempty(FileOriginUrl) 
| project Timestamp, DeviceName, FileName, FolderPath,FileOriginUrl, FileSize, InitiatingProcessFileName, InitiatingProcessCommandLine 

The signal is not “a skill file exists.” The signal is “a skill file appeared or modified in an unusual way.” 

Look for prompt injection side effects 

Prompt injection is hard to detect directly from endpoint telemetry because MDE does not see the prompt content inside encrypted sessions or local model interactions. 

But endpoint telemetry can show the downstream effects. 

If an AI agent is manipulated into doing something unsafe, you may see it: 

  • Spawn a shell. 
  • Run osascript. 
  • Invoke launchctl. 
  • Access the macOS Keychain via security. 
  • Use curl, wget, or scp. 
  • Read sensitive paths such as .ssh, .env, or credential files. 
  • Make unexpected external network connections. 

A useful behavioral detection is AI-related parent processes spawning sensitive child commands: 

KQL — AI parent process spawning sensitive child commands 

DeviceInfo 
| where OSPlatform == "macOS" 
| distinct DeviceId 
|join DeviceProcessEvents on DeviceId 
| where Timestamp > ago(1d) 
| where tolower(InitiatingProcessFileName) in ("ollama", "openclaw", "node", "npx", "deno") 
    or InitiatingProcessCommandLine has_any ("openclaw", "ollama", "openclaw.mjs") 
| where FileName in~ ( 
    "sh", 
    "bash", 
    "zsh", 
    "python", 
    "python3", 
    "curl", 
    "wget", 
    "scp", 
    "osascript", 
    "launchctl", 
    "security", 
    "dscl" 
) 
| project 
    Timestamp, 
    DeviceName, 
    ParentProcess = InitiatingProcessFileName, 
    ParentCmdLine = InitiatingProcessCommandLine, 
    ChildProcess = FileName, 
    ChildCmdLine = ProcessCommandLine, 
    User = AccountName 
| sort by Timestamp desc 

This may not be suitable for use as an alert, as developers using AI coding assistants will legitimately run shell commands. The goal is not to block all shell execution. The goal is to identify suspicious combinations: encoded payloads, persistence commands, credential access, unexpected network transfer, or sensitive file access. 

Don’t skip external network checks 

Local inference should mostly stay local. Ollama may contact external services for model downloads or registry activity, and agents may call approved cloud AI APIs depending on configuration. But unexpected public destinations from local AI processes are worth reviewing. 

Start with a narrow allowlist and expand based on your environment: 

KQL — external network connections from local AI processes 

DeviceInfo 
| where OSPlatform == "macOS" 
| distinct DeviceId 
|join DeviceNetworkEvents on DeviceId 
| where Timestamp > ago(1d) 
| where ActionType in ("ConnectionSuccess", "ConnectionAttempt") 
| where InitiatingProcessFileName in~ ("ollama", "openclaw", "node") 
    or InitiatingProcessCommandLine has_any ("openclaw", "ollama") 
| where RemoteIPType == "Public" 
| where RemoteUrl !endswith "ollama.com" 
    and RemoteUrl !endswith "openclaw.ai" 
    and RemoteUrl !endswith "anthropic.com" 
    and RemoteUrl !endswith "openai.com" 
| project 
    Timestamp, 
    DeviceName, 
    RemoteIP, 
    RemoteUrl, 
    RemotePort, 
    ProcessName = InitiatingProcessFileName, 
    CommandLine = InitiatingProcessCommandLine 
| sort by Timestamp desc 

For alerting, consider thresholding on multiple distinct remote URLs from the same AI process over 24 hours. That helps separate one-off legitimate activity from suspicious multi-destination behavior. 

KQL — OpenClaw LaunchAgent Plist Creation (Last 24 Hours) 

This catches plist files appearing in ~/Library/LaunchAgents (or /Library/LaunchAgents) that reference OpenClaw by name or were created by an OpenClaw-related process. A matching result indicates that a persistent auto-start configuration has been installed for the AI gateway — which should be validated against approved deployment records. 

 

DeviceFileEvents 
| where Timestamp > ago(1d) 
| where ActionType in ("FileCreated", "FileModified") 
| where FolderPath has "LaunchAgents" and FileName endswith ".plist" 
| where FileName has "openclaw" 
    or InitiatingProcessFileName in~ ("openclaw", "node") 
    or InitiatingProcessCommandLine has "openclaw" 
| where DeviceId in ( 
    DeviceInfo | where OSPlatform == "macOS" | distinct DeviceId 
) 
| project 
    Timestamp, 
    DeviceName, 
    FileName, 
    FolderPath, 
    InitiatingProcessFileName, 
    InitiatingProcessCommandLine, 
    User = InitiatingProcessAccountName 

 

 

Recommended deployment model 

I would not deploy every query as an alert on day one. A better operational model is: 

Use case 

Cadence 

Deployment 

AI process inventory 

Weekly 

Reporting dashboard 

First-time AI tool per device 

Daily 

Custom detection 

Known AI server ports 

Daily 

Custom detection 

OpenClaw LaunchAgent persistence 

Daily 

Custom detection 

Skill/context file monitoring 

Weekly 

Reporting dashboard 

Suspicious skill creation 

Daily 

Custom detection 

AI process spawning system commands 

Daily 

Custom detection after tuning 

AI external network connections 

Daily 

Custom detection after tuning 

Broad localhost listener discovery 

Weekly 

Threat hunt 

The most reliable detections are inventory deltas, known listening ports, persistence artifacts, and suspicious skill creation. The highest-noise detections are behavioral heuristics, especially shell execution and external network activity. 

Practical limitations 

A few MDE/macOS realities matter: 

  • MDE does not decrypt TLS traffic. 
  • DeviceProcessEvents does not include OSPlatform, so use DeviceInfo to scope macOS devices. These queries can be used as a base to expand hunting into other OS platforms with minimal modification of the KQL. 
  • A positive SKILL.md hit still requires content review. 
  • DeviceFileEvents shows file metadata, not file contents. 

That means these queries should be part of a broader defense-in-depth strategy, not the entire program. 

Pair them with: 

  • MDM and other controls restricting unsigned or unapproved AI apps- which may be problematic in a developer centric environment. 
  • Network monitoring for known local AI ports. 
  • Review processes for third-party skills. 
  • Proxy/firewall correlation for suspicious external traffic. 
  • Version-controlled detection content so query changes can be audited and rolled back. 

Final thought 

Local AI tools are becoming part of the endpoint reality. You can get a head start on understanding your org’s AI usage with KQL and Advanced hunting, especially on developer-heavy macOS fleets.  Agent visibility in the XDR portal is in flight and arriving soon.

In the interim can start now with the telemetry we already have: processes, files, ports, and network connections. Build a baseline. Alert on meaningful change. Tune the noisy heuristics. Review skill files like executable content, because in practice that is what they can become. 

Other artifacts that you can hunt for AI are the Defender for Cloud Apps leveraging the governance capability for monitoring or sanctioning and unsanctioning apps – which in this case -  monitor the AI related apps.  

This is not necessarily about blocking AI usage by default. It is about giving defenders enough visibility to distinguish normal local AI adoption from risky or compromised behavior. 

 

Addendum: 

I’ve created a Sentinel Workbook that incorporates these queries. Available at https://github.com/vboyev-MSFT/Microsoft-Sentinel-Workbooks  

 

 

 

 

Published Jul 14, 2026
Version 1.0
No CommentsBe the first to comment