Microsoft's latest guidance makes official what many of us in incident response have been saying for over a year: AI agents must be treated as insiders. Not as tools, not as extensions of the user who launched them — as autonomous principals with credentials, permissions, and the ability to act at machine speed with none of the judgment of a human operator. Alongside that framing, Microsoft is rolling out controls that grant agents access per task and dynamically tighten permissions as an agent's computed risk score rises.
This is a direct acknowledgment of the failure mode we've watched unfold across early agentic AI deployments: enterprises handing broadly-scoped OAuth tokens, persistent service principals, and standing mailbox/SharePoint/Teams access to autonomous agents that can be manipulated through prompt injection, poisoned data sources, or compromised tool integrations. An agent with standing read/write access to your M365 tenant is, functionally, an insider with an always-on session — and if it's hijacked, you've handed an adversary a tireless, credentialed operator inside your perimeter.
This post breaks down what Microsoft's model means architecturally, how attackers are actually abusing agent identities today, and — most importantly — the detections and hardening steps your SOC can implement now, before these native controls reach general availability in your tenant.
Technical Analysis: Why Static Permissions Fail for Autonomous Agents
The Core Problem: Standing Privilege for Non-Human Identities
Traditional access models assume a human on the other end of the session. Conditional Access policies evaluate signals like device compliance, MFA strength, and impossible travel — signals that are meaningless for an agent that authenticates with a client secret from a container in an automation pipeline. The result in most deployments we've assessed:
- Over-scoped application permissions. Agents are granted broad Microsoft Graph scopes (
Mail.ReadWrite,Files.ReadWrite.All,Sites.FullControl.All) because scoping them tightly is operationally painful. - Persistent credentials. Client secrets and certificates with 12–24 month validity, stored in environment variables, config files, or — worse — code repositories.
- No session-context evaluation. Once the token is issued, nothing re-evaluates whether the agent should still be doing what it's doing.
- Inheritance of user context. Many agents operate on-behalf-of a user via delegated tokens, silently inheriting everything that user can touch — including things the agent's designers never intended it to access.
What Microsoft Is Changing
Per the announcement, Microsoft's approach introduces two structural shifts:
- Per-task, just-in-time access grants. Instead of standing permission sets, the agent requests access scoped to the discrete task at hand. When the task completes, the grant evaporates. This mirrors just-enough-administration (JEA) and privileged identity management (PIM) principles we've applied to humans for years — now applied to machine principals.
- Dynamic risk scoring with adaptive restriction. The agent accumulates a risk score based on its behavior — the resources it touches, the volume and velocity of its operations, deviation from established patterns. As risk rises, permissions tighten automatically. This is the Continuous Access Evaluation (CAE) philosophy extended from reactive token revocation to proactive privilege constriction.
This is architecturally sound. It converts the agent from a static identity with a fixed blast radius into a continuously-evaluated principal whose blast radius shrinks the moment it behaves anomalously.
How Attackers Abuse Agent Identities Today
From a defender's perspective, the attack chains we see against agentic AI deployments:
- Prompt injection → tool abuse. Attacker-controlled content (email, document, web page) ingested by the agent contains instructions that redirect the agent to use its legitimate tools and tokens maliciously — exfiltrating mailbox contents, enumerating SharePoint, sending internal-phishing email as the user. Critically, every API call the agent makes is technically authorized. Your perimeter controls see nothing wrong.
- Credential theft of the agent principal. The agent's client secret or managed identity token is harvested from the host (environment variables, IMDS endpoints, config files) and replayed from attacker infrastructure. Because the principal is a service account, interactive sign-in detections and MFA-based controls don't fire.
- Consent phishing into agent frameworks. Attackers register malicious apps and drive OAuth consent, then chain the consented app into agent tool pipelines (e.g., malicious MCP servers or plugins) to ride the agent's trusted position.
- Cross-tenant and supply-chain compromise of agent tooling. A compromised plugin, SDK, or orchestration layer turns every agent built on it into a pivot point — the agentic equivalent of a software supply-chain attack.
Exploitation Status
There is no single CVE at the center of this story — this is an architectural and identity-security exposure class, not a patchable flaw. Prompt injection against LLM-driven agents and abuse of over-permissioned service principals are actively observed techniques in real intrusions, and the abuse of non-human identities broadly has been one of the fastest-growing intrusion vectors we've handled in IR engagements over the past year. Treat this as a present-day, actively exploited weakness in how agents are deployed — not a theoretical future risk.
Detection & Response
The detections below target the observable behaviors of rogue or hijacked agents: agent runtimes spawning unexpected child processes on endpoints, anomalous service principal token usage in Entra ID, and privilege/consent manipulation of agent identities. These are built to be high-signal — tune thresholds to your environment, but the core logic should hold in any mature SOC.
SIGMA Rules
---
title: AI Agent Runtime Spawning Shell or Scripting Child Process
id: 3f7a2b91-4c5d-4e8a-b6f1-9a0d2c4e7b11
status: experimental
description: Detects common AI agent host processes (Python, Node, .NET) spawning interactive shells or scripting engines. Hijacked or prompt-injected agents frequently pivot from the runtime to a shell to execute attacker-directed commands. Tune the parent list to your actual agent runtime paths.
references:
- https://www.securityweek.com/microsoft-targets-rogue-ai-agents-with-dynamic-permissions-risk-scoring/
- https://attack.mitre.org/techniques/T1059/
author: Security Arsenal
date: 2026/04/06
tags:
- attack.execution
- attack.t1059
logsource:
category: process_creation
product: windows
detection:
selection_parent:
ParentImage|endswith:
- '\python.exe'
- '\pythonw.exe'
- '\node.exe'
- '\dotnet.exe'
selection_child:
Image|endswith:
- '\cmd.exe'
- '\powershell.exe'
- '\pwsh.exe'
- '\wscript.exe'
- '\cscript.exe'
- '\mshta.exe'
- '\rundll32.exe'
filter_known_agent_hosts:
ParentImage|startswith:
- 'C:\Program Files\'
condition: selection_parent and selection_child and not filter_known_agent_hosts
falsepositives:
- Legitimate agent frameworks executing local automation steps
- Developer workstations running LLM tooling
level: high
---
title: Service Principal Granted High-Value Microsoft Graph Application Permissions
id: 8c1d4e52-7b3a-4f29-a1d6-2e5c8b0f3a44
status: experimental
description: Detects consent grants or app role assignments giving a service principal broad Graph scopes commonly abused by rogue or hijacked AI agents (mail, files, sites, directory). Review every grant of these scopes to non-human identities.
references:
- https://www.securityweek.com/microsoft-targets-rogue-ai-agents-with-dynamic-permissions-risk-scoring/
- https://attack.mitre.org/techniques/T1550/
author: Security Arsenal
date: 2026/04/06
tags:
- attack.persistence
- attack.privilege_escalation
- attack.t1098
logsource:
product: azure
service: auditlogs
detection:
selection_operation:
OperationName:
- 'Consent to application'
- 'Add app role assignment to service principal'
- 'Add delegated permission grant'
selection_scope:
TargetResources|contains:
- 'Mail.ReadWrite'
- 'Mail.Send'
- 'Files.ReadWrite.All'
- 'Sites.FullControl.All'
- 'Directory.ReadWrite.All'
- 'RoleManagement.ReadWrite.Directory'
- 'Application.ReadWrite.All'
condition: selection_operation and selection_scope
falsepositives:
- Approved onboarding of legitimate enterprise agents and automation
level: medium
---
title: Agent Service Principal Authenticating From Unusual Infrastructure
id: b2e9f016-3d84-4c7a-95e2-1f6a0b8d5c77
status: experimental
description: Detects service principal sign-ins from IP ranges or hosting providers inconsistent with expected agent hosting. A stolen agent secret replayed from attacker infrastructure is a primary rogue-agent indicator. Baseline your legitimate agent egress IPs before enabling at high level.
references:
- https://www.securityweek.com/microsoft-targets-rogue-ai-agents-with-dynamic-permissions-risk-scoring/
- https://attack.mitre.org/techniques/T1550.001/
author: Security Arsenal
date: 2026/04/06
tags:
- attack.initial_access
- attack.t1078.004
logsource:
product: azure
service: signinlogs
detection:
selection:
ServicePrincipalName|contains:
- 'agent'
- 'copilot'
- 'bot'
- 'automation'
filter_expected_networks:
IpAddress|startswith:
- '10.'
- '20.x.x.' # replace with your known agent egress ranges
condition: selection and not filter_expected_networks
falsepositives:
- Agents hosted in new cloud regions before baseline update
- Vendor-hosted SaaS agents with rotating egress IPs
level: high
KQL — Microsoft Sentinel / Defender Hunting
This query hunts for anomalous Graph API behavior by non-human identities — the hallmark of a prompt-injected or hijacked agent suddenly operating outside its established pattern (new resources, new geographies, burst API volume). It baselines per-principal behavior over 14 days and flags day-over-day deviation.
// Hunt: Non-human identity (agent/service principal) exhibiting anomalous Graph activity
// Baseline 14 days, flag deviation in resource access, geography, or call volume
let baselineWindow = 14d;
let detectWindow = 1d;
let baseline =
SigninLogs
| where TimeGenerated between (ago(baselineWindow) .. ago(detectWindow))
| where Identity has_any ("agent", "bot", "copilot", "svc-", "automation")
or AppDisplayName has_any ("agent", "bot", "copilot")
| summarize
BaselineIPs = make_set(IPAddress),
BaselineResources = make_set(ResourceDisplayName),
BaselineLocations = make_set(Location),
BaselineCount = count()
by AppId, AppDisplayName;
SigninLogs
| where TimeGenerated >= ago(detectWindow)
| where isnotempty(AppId)
| summarize
RecentIPs = make_set(IPAddress),
RecentResources = make_set(ResourceDisplayName),
RecentLocations = make_set(Location),
RecentCount = count(),
LatestResult = arg_max(TimeGenerated, ResultType, ResultDescription)
by AppId, AppDisplayName
| join kind=inner baseline on AppId
| extend NewIPs = set_difference(RecentIPs, BaselineIPs)
| extend NewResources = set_difference(RecentResources, BaselineResources)
| extend VolumeRatio = round(todouble(RecentCount) / todouble(BaselineCount / baselineWindow * 1d), 2)
| where array_length(NewIPs) > 0
or array_length(NewResources) > 0
or VolumeRatio > 5
| project AppDisplayName, AppId, NewIPs, NewResources, RecentLocations,
BaselineCount, RecentCount, VolumeRatio, TimeGenerated, LatestResult
| order by VolumeRatio desc;
For endpoint-side hunting of agent runtimes pivoting to shells — the local footprint of a hijacked agent executing injected instructions:
// Hunt: AI agent runtimes spawning shells/script engines on endpoints
DeviceProcessEvents
| where TimeGenerated >= ago(7d)
| where InitiatingProcessFileName in~ ("python.exe", "pythonw.exe", "node.exe", "dotnet.exe")
| where FileName in~ ("cmd.exe", "powershell.exe", "pwsh.exe", "wscript.exe", "cscript.exe", "mshta.exe", "rundll32.exe")
| where not(InitiatingProcessFolderPath has "Program Files") // tune to your sanctioned agent install paths
| summarize
SpawnedCommands = make_set(ProcessCommandLine, 25),
FirstSeen = min(TimeGenerated),
LastSeen = max(TimeGenerated),
DeviceCount = dcount(DeviceId)
by InitiatingProcessFolderPath, InitiatingProcessCommandLine, AccountName
| order by LastSeen desc;
Velociraptor VQL
Use this artifact during IR scoping when you suspect an agent host has been manipulated into executing attacker-directed commands. It surfaces scripting shells spawned by agent runtimes, with full command lines for triage.
-- Hunt: Shells and script engines spawned by AI agent runtimes (rogue agent execution)
SELECT Pid,
Ppid,
Name,
Exe,
CommandLine,
Username,
CreateTime,
dict(Name=parent.Name, Exe=parent.Exe, CommandLine=parent.CommandLine) AS Parent
FROM pslist()
LET parent = SELECT Name, Exe, CommandLine FROM pslist(pid=Ppid)
WHERE Name =~ '(?i)(cmd|powershell|pwsh|wscript|cscript|mshta|rundll32)\.exe$'
AND parent.Exe =~ '(?i)(python|pythonw|node|dotnet)\.exe$'
Remediation / Audit Script
This PowerShell audits your tenant for the exact conditions that make agents dangerous: non-human identities holding high-value Graph application permissions, aging credentials, and recent consent grants. Run it with Microsoft Graph PowerShell (Connect-MgGraph -Scopes "Application.Read.All,Directory.Read.All,AuditLog.Read.All").
# Audit service principals (agent identities) for high-risk Graph app permissions and stale credentials
Connect-MgGraph -Scopes "Application.Read.All,Directory.Read.All,AuditLog.Read.All" -NoWelcome
$highRiskScopes = @(
'Mail.ReadWrite','Mail.Send','Files.ReadWrite.All','Sites.FullControl.All',
'Directory.ReadWrite.All','RoleManagement.ReadWrite.Directory','Application.ReadWrite.All',
'User.ReadWrite.All','Group.ReadWrite.All','TeamsActivity.Send'
)
$graphSp = Get-MgServicePrincipal -Filter "appId eq '00000003-0000-0000-c000-000000000000'" |
Select-Object -ExpandProperty AppRoles
$roleLookup = @{}
$graphSp | ForEach-Object { $roleLookup[$_.Id] = $_.Value }
# Enumerate app role assignments across all service principals
$report = foreach ($sp in (Get-MgServicePrincipal -All -Property "Id,DisplayName,AppId,AppRoleAssignments,KeyCredentials,PasswordCredentials,ServicePrincipalType")) {
foreach ($assignment in $sp.AppRoleAssignments) {
$scope = $roleLookup[$assignment.AppRoleId]
if ($highRiskScopes -contains $scope) {
[pscustomobject]@{
ServicePrincipal = $sp.DisplayName
AppId = $sp.AppId
Type = $sp.ServicePrincipalType
GrantedScope = $scope
SecretCount = ($sp.PasswordCredentials | Measure-Object).Count
OldestSecretDays = if ($sp.PasswordCredentials) {
[int]((Get-Date) - ($sp.PasswordCredentials | Sort-Object StartDateTime | Select-Object -First 1).StartDateTime).TotalDays } else { 0 }
CertCount = ($sp.KeyCredentials | Measure-Object).Count
}
}
}
}
$report | Sort-Object ServicePrincipal, GrantedScope | Format-Table -AutoSize
$report | Export-Csv -Path ".\AgentIdentity-RiskyGrants-$(Get-Date -Format yyyyMMdd).csv" -NoTypeInformation
# Flag secrets older than 90 days on any principal holding high-risk grants
Write-Host "`n=== Principals with credentials older than 90 days (rotate immediately) ===" -ForegroundColor Yellow
$report | Where-Object { $_.OldestSecretDays -gt 90 } | Sort-Object OldestSecretDays -Descending | Format-Table -AutoSize
# Pull recent consent grants for triage (last 14 days)
Write-Host "`n=== Recent consent / app role assignment events (last 14 days) ===" -ForegroundColor Yellow
$start = (Get-Date).AddDays(-14).ToString("yyyy-MM-ddTHH:mm:ssZ")
Get-MgAuditLogDirectoryAudit -Filter "activityDateTime ge $start and (activityDisplayName eq 'Consent to application' or activityDisplayName eq 'Add app role assignment to service principal')" -All |
Select-Object ActivityDateTime, ActivityDisplayName,
@{n='InitiatedBy';e={$_.InitiatedBy.App.DisplayName ?? $_.InitiatedBy.User.UserPrincipalName}},
@{n='Target';e={$_.TargetResources[0].DisplayName}} | Format-Table -AutoSize
Review the output line by line. Every principal in the first table that isn't a documented, business-justified agent or automation workload is a containment candidate — disable it first, investigate second.
Remediation and Hardening: Treat Agents Like Insiders Starting Today
You don't need to wait for Microsoft's dynamic permission controls to reach your tenant. The underlying principles can be enforced now:
1. Inventory every agent identity. Enumerate all service principals, managed identities, and app registrations used by agent frameworks, copilots, and orchestration pipelines. You cannot apply risk scoring to identities you don't know exist. The audit script above is your starting point.
2. Collapse standing permissions to task scope. Replace broad Graph scopes with the minimum required per workload. Where the platform supports it, move agents to workload identity federation and short-lived tokens instead of long-lived client secrets. Any secret older than 90 days on a non-human identity should be rotated or eliminated.
3. Enforce Conditional Access for workload identities. Entra ID Conditional Access for workload identities lets you restrict where an agent's token can be used from (named locations/IP ranges). This directly blunts credential-replay attacks — a stolen secret is worthless if it only works from your automation subnet.
4. Route agent API activity into your SIEM now. Ensure SigninLogs (including service principal and managed identity sign-in log types), AuditLogs, and Graph activity via M365 unified audit logging are all streaming into Sentinel or your SIEM of record. The KQL baselining above only works if the telemetry exists. Most tenants we assess are missing at least one of these log types.
5. Build a consent governance gate. Disable user consent to applications (User consent settings → "Do not allow user consent"), and route all app consent through an admin approval workflow with security review. Every new agent tool, plugin, or MCP integration that touches your tenant should pass through this gate.
6. Apply Microsoft's dynamic controls at GA — but verify them. When per-task grants and risk-scored tightening become available in your environment, enable them in audit/report-only mode first. Validate that the risk signals fire on your known red-team scenarios before enforcing, exactly as you would with any new adaptive control.
7. Red-team your agents. Prompt injection, tool-pivot, and credential-theft scenarios against your own agent deployments should be on your next penetration test scope. If your agents are insiders, they deserve insider-threat-grade adversarial testing — before a real adversary provides it for free.
The strategic takeaway: Microsoft's move validates a zero-trust posture for non-human identities. The organizations that get ahead of this will be the ones that stopped treating agents as features and started treating them as principals — with scoped privilege, continuous evaluation, and full telemetry — before the first rogue-agent incident forces the issue.
Related Resources
Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.