I've spent the last couple of posts walking through how Microsoft Entra Agent ID slots into PIM and access packages, giving autonomous agents short-lived, scoped permissions instead of the standing "do anything" service accounts most of us inherited from a decade of "just give it Contributor and move on." That covers what an agent can do once it has a token. This post is about the step before that: what decides whether the agent gets a token at all.
That's where Conditional Access for agents comes in. It's Microsoft's
extension of the same policy engine that's been gatekeeping human sign-ins for years, now
wired up to evaluate agent identities and agent's user accounts as well. Microsoft's reference page covers the whole
model, and the version with ?tabs=custom-security-attributes in the URL is the
one worth bookmarking. It points at the targeting method that actually scales once you've got
more than a handful of agents running around your tenant.
Why this needed its own page in the docs
Conditional Access is the if-this-then-that engine sitting in front of every token issuance in Microsoft Entra ID. It looks at signals (who's asking, from what device, from where, with how much session risk) and either lets the request through, blocks it, or asks for more proof before handing over an access token.
Until recently, "who's asking" meant a human user or a registered application. Now it also means an agent identity (an autonomous identity created under an agent identity blueprint) or an agent's user account (a directory account linked to an agent that behaves like any other licensed user, complete with a mailbox, a calendar, and group memberships). If you're deploying agents that touch SharePoint, Microsoft Graph, MCP servers, or your own internal APIs, this is the layer that decides whether that touch ever happens.
Before you build anything, check the licensing reality, because it's easy to assume this is bundled in with something you already own:
- Microsoft Entra ID P1 or P2, the same baseline Conditional Access has always required for users
- A Microsoft Agent 365 license assigned per user whose agents you want to govern this way. Microsoft's own wording is that enforcement of this licensing requirement is "coming soon," which I'd read as "the door isn't locked yet, but don't plan around it staying open"
- Microsoft Entra Internet Access, if you also want network-level controls applied to agent traffic on top of the identity-based ones
Note: a fair amount of what's described here (agent-specific risk detections, the "Agent execution environments" condition, "All agent users" targeting) is explicitly marked preview in Microsoft's documentation. Treat what follows as the current shape of the feature, not a frozen spec, and re-check the docs before you roll a policy out tenant-wide.
Subjects, audiences, and why the distinction matters here
To use a corporate resource (a SharePoint site, an MCP server, an internal API), a user or agent first asks Microsoft Entra ID for an access token. If a Conditional Access policy applies, Entra checks its requirements before issuing that token. Pass the checks and you get a token; fail them and you don't. The token then goes to the resource, which checks its claims and decides what you're allowed to do.
Two terms carry the whole model, and they're worth being precise about because agents make the distinction visible in a way human sign-ins usually don't:
- Subject: the identity actually receiving the token. In an on-behalf-of flow this is the user (while the agent is still identified as the calling app). In an application-only flow it's the agent identity itself. In an agent's user account flow, it's that account.
- Audience: the resource the token is good for. Every token has exactly one audience, and that resource has to be registered as an enterprise application (service principal) in your tenant. An agent that needs to call three different MCP servers needs three separate tokens, each scoped to its own audience and permission set.
Conditional Access evaluates both sides, who's asking and what they're asking for, every time Entra issues or refreshes a token. Some resources also support Continuous Access Evaluation, which can yank access in near real time when something changes mid-session (a user gets disabled, risk gets flagged, that sort of thing).
The three ways an agent shows up at your door
Which Conditional Access controls even apply to an agent depends entirely on how it's asking for access. Microsoft documents three patterns, and they map to genuinely different policy targets. Get this part wrong and you'll write a policy that silently never fires.
| Pattern | Token subject | CA policy targets | Typical example |
|---|---|---|---|
| On-behalf-of (delegated) | The signed-in user | Users and groups, exactly like a normal sign-in policy | An assistive agent reading and drafting replies in your mailbox |
| Application-only (autonomous / client credentials) | The agent identity itself | All agent identities, or specifically selected agent identities | A scheduled agent that compiles a daily report with nobody watching |
| Agent's user account ("digital worker") | The agent's own directory user account | All agent users (preview), or specifically selected agent users (preview) | An "AI teammate" with its own mailbox, calendar, and Teams presence |
The on-behalf-of (OBO) flow is the one most people picture first: a user signs in to an agent application, and the agent then reaches downstream resources using that user's identity and delegated permissions: the agent reading your inbox is reading it on your behalf. Because the agent can't simply hand over the user's original token (it was minted for a different audience), it exchanges tokens with Entra to get one scoped to the actual target resource, and that exchange is itself evaluated by Conditional Access. Since the user is the subject here, you write policy against users and groups, the same way you always have.
Application-only access is the opposite end: no user in the loop, the agent authenticates as itself using credentials from its agent identity blueprint. This covers autonomous agents running on a schedule or reacting to events, agents that call backend services users were never meant to reach directly, and public-facing agents that don't carry user context forward. Because the token subject is the agent identity, not a person, your policy targets either all agent identities or a specific list of them.
Agent's user accounts sit in between: an admin provisions a real directory account, links it to the agent, assigns it Microsoft 365 licenses, drops it into security groups and administrative units. It's a "digital worker" that participates in collaborative workflows the same way a human teammate does. The token subject is that account, so policy is evaluated against the agent user account, not the agent identity behind it. If those accounts run on managed endpoints (think Windows 365 Cloud PCs for Agents) you can also reach for the Agent execution environments (preview) condition to apply device-compliance and compliant-network requirements on top.
Picking how you target agents in a policy
Once you know which pattern you're dealing with, the next question is mechanical: how do you actually point a policy at "the right agents" without hand-picking them one at a time and then forgetting to update the list six months from now? Microsoft gives you two ways to do this at scale, and they solve different problems.
| Targeting method | What it covers | Best fit when… | Watch out for |
|---|---|---|---|
| Agent identity blueprint | Every agent identity derived from that blueprint, including ones created later | A whole project or product line shares one blueprint and should share one access story | Doesn't reach the agent's user account layer, only the agent identity itself |
| Custom security attributes | Any agent (or resource) carrying a matching attribute value, regardless of which blueprint it came from | You need to classify agents by business meaning (risk tier, data sensitivity, department, environment) that cuts across blueprints | Requires its own delegated admin roles; Global Administrator does not manage these by default |
Targeting a blueprint is the simpler of the two: apply a policy once, and it automatically covers every agent identity spawned from that blueprint, present and future. It's a clean fit when a project's agents, including ones that talk to each other through agent-to-agent (A2A) flows, were all built from the same template and genuinely should be governed as one unit. The catch: it only reaches agent identities, not the agent's user accounts that might also be associated with that project.
Custom security attributes solve a different problem: the one that shows up
once you've got more agents than blueprints, or agents from the same blueprint that need
different treatment. Custom security attributes let you tag agent identities
(and resources) with business-specific labels, say RiskTier: High or
DataScope: CustomerPII, and then write Conditional Access policies that target
those labels rather than individual objects. Tag a new agent the same way and it inherits the
policy automatically; nobody has to remember to add it to a list.
Setting up attribute-driven Conditional Access
This is the part the ?tabs=custom-security-attributes view of Microsoft's docs
walks through, and it's worth running in a test tenant before you touch anything that matters.
The shape of it is: define an attribute, assign it to your agents, then reference it in a
policy. Here's roughly what that looks like with Microsoft Graph PowerShell.
Step 1: define the attribute set and the attribute itself (one-time setup, requires the Attribute Definition Administrator role):
Connect-MgGraph -Scopes "CustomSecAttributeDefinition.ReadWrite.All"
# An attribute set groups related attributes together: think of it as a namespace
New-MgDirectoryAttributeSet -Id "AgentGovernance" `
-Description "Attributes used to classify and target AI agent identities" `
-MaxAttributesPerSet 25
# The attribute itself: a closed set of allowed values keeps policy targeting predictable
New-MgDirectoryCustomSecurityAttributeDefinition -AttributeSet "AgentGovernance" `
-Name "AgentRiskTier" `
-Description "Risk classification used to scope Conditional Access policies for agents" `
-Type "String" `
-Status "Available" `
-UsePreDefinedValuesOnly `
-AllowedValues @("Low", "Medium", "High")
Step 2: tag the agent identity (requires the Attribute Assignment Administrator role; agent identities are service principals under the hood, so the same cmdlets you'd use for any enterprise application apply):
Connect-MgGraph -Scopes "CustomSecAttributeAssignment.ReadWrite.All"
$agent = Get-MgServicePrincipal -Filter "displayName eq 'Customer-Insights-Agent'"
$params = @{
customSecurityAttributes = @{
AgentGovernance = @{
"@odata.type" = "#Microsoft.DirectoryServices.CustomSecurityAttributeValue"
AgentRiskTier = "High"
}
}
}
Update-MgServicePrincipal -ServicePrincipalId $agent.Id -BodyParameter $params
# Confirm it stuck
(Get-MgServicePrincipal -ServicePrincipalId $agent.Id -Property "customSecurityAttributes").CustomSecurityAttributes.AdditionalProperties
Step 3: point a Conditional Access policy at the attribute. In the Entra
admin center, create (or edit) a policy under Protection > Conditional Access,
and in the assignment conditions choose to target agent identities by custom security
attribute rather than by name, selecting your attribute set, attribute, operator, and value
(for example, AgentGovernance.AgentRiskTier equals High). Every agent carrying
that tag now falls under the policy, including ones tagged after the policy was created.
Practical tip: use UsePreDefinedValuesOnly with a fixed list
of allowed values rather than free text. Free-text attributes invite typos
("hihg" instead of "High"), and a typo in a tag silently breaks
policy targeting. The agent just won't match, with no error to tell you why.
Where Conditional Access quietly stops applying
Worth knowing up front, because each of these is the kind of thing that causes a confused "but I have a policy for this" conversation later:
- Policies don't apply when an agent identity blueprint acquires a token for Microsoft Graph purely to create an agent identity or agent's user account. Blueprints can't act independently beyond that creation step; the actual work is always carried out by the resulting agent identity.
- Token exchanges at the
AAD Token Exchange Endpoint: Publicendpoint (resource IDfb60f99c-7a34-4190-8149-302f77469936) sit outside policy scope, but tokens scoped to that endpoint can't call Microsoft Graph either, so the agent flow stays protected at the next hop. - If Security defaults are enabled on the tenant, Conditional Access for agents (like Conditional Access generally) doesn't apply.
- Conditional Access only ever protects resources that go through Microsoft Entra ID's token pipeline. An agent calling something with a bare API key skips that pipeline entirely: no token, no policy evaluation, no coverage. If your agents authenticate with API keys anywhere, that's a gap this feature cannot close for you.
- Several combinations simply aren't supported yet: policies that target "all users" don't pick up agent's user accounts, you can't scope a policy to agent's user accounts by group membership, and a policy aimed at agent identities (whether directly or via a blueprint) won't reach across to the linked agent's user account.
Checking your work in sign-in logs
Once a policy is live, the honest way to know whether it's doing what you think is the
sign-in logs, not the policy report-only summary but the actual log entries. Filter for
agentType to isolate agent-specific sign-ins, and from there you can see exactly
which policies were evaluated, which ones applied, and which controls were satisfied or
failed for a given request. That's also where you'll catch the quiet failure mode of
attribute-based targeting: an agent that should be in scope but isn't, usually because of a
missing or mistyped attribute assignment rather than a problem with the policy itself.
Where to go from here
- Confirm licensing first: Entra ID P1/P2 plus Agent 365 per governed user, and Entra Internet Access if network controls are part of the plan.
- Inventory your agents by access pattern (OBO, application-only, agent's user account) before writing a single policy. The pattern decides what you can even target.
- Stand up an attribute set and a small, closed list of values for agent classification, and tag a handful of agents in a test tenant before going wider.
- Build the first policy in report-only mode, watch the sign-in logs filtered on
agentType, and only then switch it to enforce. - Revisit this regularly. Risk detections, agent execution environment conditions, and "All agent users" targeting are all marked preview, and preview features move.
References
- Conditional Access for agents
- What is Microsoft Entra Agent ID
- Manage agent identities in your organization
- Configure policies for autonomous agent access
- Conditional Access for agents operating on-behalf-of a user
- Agent's user accounts
- Custom security attributes overview
- Manage custom security attributes for an application (Microsoft Graph PowerShell)
- Microsoft Entra Agent ID sign-in and audit logs