Authorization in Entra has changed, and most of that change is not visible in the product UI. The boundaries have always been there; they are just no longer optional side-quests. When you architect an Entra Agent ID, you are not choosing one authorization mechanism. You are composing five of them, each with its own trust surface. Understanding that composition is the difference between a loosely guarded identity and one that respects the principle of least privilege.
Consent is authorization, not authentication. But consent is only the start. After you have granted the app permission to call Microsoft Graph, the hard work is to ensure it calls Graph with the minimum scope it actually needs, at the exact moment it needs it, and only on behalf of the principals you intended. That is what this article addresses.
User assignment as your outermost gate
User assignment is the first boundary you should establish. It is blunt, but it is not optional. When you require user or group assignment to an enterprise application, you are saying: "Only the principals I explicitly list in this Entra app object can even attempt to authenticate to this workload."
For user-facing applications, this is straightforward. You assign Alice and Bob to the app, and only Alice and Bob can sign in.
For an AI agent, user assignment works similarly. You do not assign the agent's identity to an app. Instead, you assign the users who are allowed to delegate to or authenticate to the agent. In other words that assignment controls which users can invoke the agent or have the agent act on their behalf.
Here is the critical part: user assignment gates access at two levels. First, it controls which users can authenticate to the agent itself. Second, and less obvious, it also gates downstream resource access. If a user is not explicitly assigned to a downstream API or resource, the agent cannot access that resource on behalf of that user—even if the agent's identity is assigned to that API. User assignment is not negotiable at any layer of the call chain.
If you do not require assignment, Entra will still respect the OAuth 2.0 consent framework. However, it will allow any user in your tenant (or any user in a federated tenant, if you have configured cross-tenant access) to attempt authentication. The app sees the request, asks for consent, the user grants it (or the admin pre-consents), and the app gets a token. User assignment closes that loophole. It says: "No request reaches this workload unless the requester is already in my approved list—and no downstream resource request on behalf of that user will succeed if the user is not approved there either."
For AI agents deployed at scale across teams or business units, user assignment is your guard rail. Without it, you are depending on the app and downstream APIs to reject requests from unknown principals. The better defense is to never admit an unapproved principal to the conversation in the first place, and to enforce that control consistently across all resources the agent might access.
Important: User assignment requirement works for both Agent Identity Blueprints and individual agent identities. However, there is currently no Entra Admin Center UX that exposes user assignment functionality — only the Microsoft Graph API. For practical user assignment at scale, consider using Access Packages to facilitate and manage user assignments for AI agents. Another limitation worth mentioning is that at time of writing of this article, only Agent Identity Blueprints support custom roles definitions.
Conditional access as authorization policy
Conditional access is a policy engine that controls token acquisition. Unlike app roles or group claims, which are attributes embedded in a token, conditional access is evaluated before the token is issued. If a policy is violated, the agent does not get a token.
Here are concrete examples of conditional access for AI agents:
-
Custom Security Attribute filters: "If the app is tagged with
Agents.Approved:Truethen allow access." The agent cannot acquire a token unless it is tagged as approved. - Risk-based controls: "If Entra's identity protection detects a risky sign-in pattern, require additional verification or deny access." In on-behalf-of type of acces, the user's authentication context and user's offline calculated risks are evaluated (unusual location, impossible travel, leaked credentials, etc.), and access is blocked if that evaluation crosses threshold. In autonomous agent access the agent's risk is evaluated and access is blocked if agent's risk crosses defined threshold.
- Device compliance: "The device must be compliant with Intune policies." If the user is invoking the AI Agents from a device that is not enrolled or is marked non-compliant, the request is blocked.
Conditional access distinguishes two data access patterns that are critical for AI agents:
- Autonomous access: The agent acts on its own behalf (application flow). Conditional access evaluates the agent's context (where it is running, what device it is on, what time it is).
- On-behalf-of (OBO) user access: The agent acts on behalf of a user. Conditional access evaluates the user's context (where the user is, their device, their authentication method), not the agent's context.
Critical limitation: At the time of writing, Conditional Access accounts for the User (subject) and Target (resource), but not the AI Agent (actor) - when the agents accesses data on-behalf-of the user. This means CA policies cannot directly distinguish between two different agents making requests in the same context - the same user is invoking two different agents, and both happen to require a token to access Work IQ, the conditional access sees these requests identically.
See Conditional Access for Agents in Microsoft Entra and Recommended policies for autonomous agents for detailed policy patterns.
The sharp edge is timing. Conditional access gates token acquisition. If your agent acquires a long-lived token and then starts running outside the approved perimeter, the existing token still works. Conditional access is a gate at the door, not a checkpoint at every step. If you need continuous context verification, you need a different mechanism.
App roles as delegated authorization claims
App roles are a mechanism for the application, or the AI agent, to define its own authorization model. You define a set of roles in your app registration (or Agent Identity Blueprint). You assign users, groups, or service principals to those roles. When the principal authenticates, Entra puts the role membership in the roles claim of the ID token (or the access token, depending on how you configure the app).
For a human-facing app, this is straightforward. Your app checks: "Is the user in the Manager role? If yes, show the budget page. If no, hide it." Entra does the assignment; your app does the enforcement.
For an AI agent, the model is the same. You can assign humen to a role defined by the Agent Blueprint. In this case, your AI Agent can take authorization decisions for what funcitonality should be avialable to the user. Or, in case of the autonomous agent, you assign the agent's identity to a role defined by downstream API. Then, when your agent acquires a token on behalf of itself (application flow), that token contains the roles assigned to the service principal. Your APIs can inspect the token and make authorization decisions.
Here is an example. You have an agent that needs to read data from one API and another agent that needs to read and write. You define two app roles in the API app registration: DataReader and DataWriter. You assign the read-only agent's service principal to the DataReader role. You assign the read-write agent to the DataWriter role. When each agent calls your API, your API code checks the roles claim. If the token does not include DataWriter, the write operation fails.
Current UX limitations: The Entra Admin Center does not directly expose a UI for defining roles on Agent Identity Blueprints. Roles can be defined and managed via the app manifest. Role assignment to users and groups can be done via the Microsoft Graph API or, more scalably, via Access Packages.
Important distinction: While the "require user assignment" property exists for Agent Identities, there is no real application scenario where interactive authentication to an Agent happens outside of the Agent Identity Blueprint. The Agent Identity Blueprint is the object that defines the authentication and authorization contract for interactive authentications. The way to add role assignments for an Agent Identity Blueprint is via Access Packages (Add Applications). Requiring explicit role assignment for individual agent identities makes sense in an autonomous agent-to-agent interactions where you want strict controls over the autonomous invokation of AI Agents.
App-only roles: App-only roles are defined on the Blueprint and can be assigned to other agents or clients. When assigned to other workloads, these roles appear in the access token with the Blueprint as the audience (aud claim). This allows fine-grained authorization delegation between agents.
The important detail is that your protected API must be configured to emit roles in the access token. This requires a specific configuration step. Many teams forget it. The app roles exist, the assignment exists, but the token arrives empty because the app registration does not emit roles into tokens meant for APIs.
Also note: app roles are defined per app registration, not globally. If you have two APIs, each needs its own set of roles. There is no central app role store.
Group membership claims as attribute-based gates
Group membership claims are different from app roles. When you emit group claims, Entra places the groups that the principal belongs to directly into the token.
Here is the distinction. App roles are defined by the application and assigned by Entra admins within the scope of that app registration. Group claims are based on the broader Entra directory. The principal is a member of the group regardless of the app. The app just asks: "What groups is this principal a member of?" Entra answers by listing them in the token.
This is useful for attribute-based access control (ABAC). Imagine your organization has groups like Sales-Americas, Sales-EMEA, Engineering, and Finance. You assign users and workload identities to these groups. Your API receives a token, extracts the groups claim, and makes decisions based on group membership. "If the token contains the Sales-Americas group, grant access to the Americas sales data. Otherwise, deny."
The value of group-based authorization is that it decouples application-specific roles from organizational structure. If you need to add a new group or restructure existing groups, you do not need to change app role definitions. You adjust group membership. The group claim mechanism is still sending the data; your API just interprets it differently.
There is a configuration step here too. You must tell Entra to emit group claims into tokens for a specific app. By default, groups are not included. Once enabled, Entra sends the group IDs (and optionally display names, but prefer IDs for immutability).
Important: Overage limits and scope configuration. When you enable group claims, you must configure scope carefully. Entra has fixed limits on how many group claims can fit in a token:
- OIDC (OpenID Connect): 200 groups maximum
- SAML: 150 groups maximum
If a principal belongs to more groups than the limit, Entra sends an "overage claim" instead of individual group IDs. Your API then needs to call Microsoft Graph to fetch the full list. This adds latency and complexity. To avoid overage, emit only "assigned groups" (groups explicitly assigned to the application / blueprint). Be explicit about which groups matter for authorization decisions, and assign only those groups to the target app or agent identity blueprint. This keeps tokens small, predictable, and avoids the overage claim penalty.
See Configure group claims and app roles in tokens for detailed guidance on group claim scope and immutable identifiers.
Access packages as the unified control plane
Access packages are where the other mechanisms converge. An access package is not just governance UI. It is programmable policy choreography. When you assign a principal to an access package, you can configure what happens automatically: group membership additions, app role assignments, Azure role assignments, and so on. All of it coordinated, all of it time-bounded, all of it auditable.
For an AI agent, access packages are a control plane. You define an access package called "Agent-Production-Access". When you assign an agent's service principal to that package, Entra automatically adds the service principal to the groups that the agent needs, assigns the correct app roles to the agent, and even delegated permissions grants (consent) for downstream APIs and MCP Servers. When the access expires, all of it unwinds. The groups are removed. The app roles are stripped, the consent is undone. The agent loses access.
This is different from manually assigning groups and roles one by one or going through admin cosnent workflow. With access packages, you are declaring a coherent policy: "This is what production access means for this type of workload. If the workload is approved, give it everything in this package. If it is denied or if the time expires, take everything away." The access package is a unit of authorization. It is atomic in the sense that you do not pick and choose which parts of it to apply. It is an all-or-nothing proposition.
For enterprises running multiple AI agents, access packages scale the authorization story. You create one access package per authorization context (production, staging, read-only partners, etc.). You assign agents to packages based on their needs. Governance reviews the packages on a schedule and approves or denies. The machinery runs itself.
There is also integration with approval workflows. An access package can require approval before assignment. You can route approvals to a specific manager or group. You can set expiration dates and schedule re-approval. For AI agents running in production, this is the audit trail that compliance teams expect. "Show me who approved this agent to have access to production data and when that approval expires."
Best practices on group emit scope and immutable identifiers
When you enable group claims, you need to decide: should Entra emit all groups the principal is a member of, or only assigned groups?
The answer is clear: use only groups assigned to the application. In a typical enterprise environment, grown over the yers, single user can be member of several thousands of groups. You cannot have a token with six thousand groups in it. And it makes no sense to go over six thousand groups to make authorization decision. Choosing "assigned groups" is tighter and mandatory for production. You explicitly assign the groups relevant for this app to that app. Other groups the principal happens to belong to stay out of the token. This keeps tokens predictable, avoids overage claims, and simplifies authorization logic.
Immutable identifiers are a separate but equally important consideration. Entra can emit group display names or group IDs in the token. Display names are human-readable but fragile. If a group is renamed, the token still carries the old display name until the token expires. Your API might silently fail to recognize the group and deny access. Or worse - someone may create a group with name that they will grant them access to the app. Group IDs are immutable. A group ID never changes, even if the display name changes. For production authorization logic, prefer group IDs. Your API logic becomes:
if token.groups contains "80d61f4e-4c9e-4f8f-9e1f-2e8f3d5c6b7a":
grant access
else:
deny
Not:
if token.groups contains "Sales-Americas":
grant access
else:
deny
The first version survives a group rename. The second does not. For large organizations managing many agents and APIs, using immutable group IDs and assigned-only scope is the only way to keep authorization logic maintainable and reliable at scale.
Composing the authorization stack
These mechanisms do not compete. They stack. Here is a realistic composition:
- Requiring explicit assignment gates whether the principal can even attempt authentication.
- Conditional access policies check location, device, and other context.
- The token arrives with app roles and group claims embedded.
- Your API inspects the token, checks app roles and groups, and makes fine-grained decisions.
- All of this is orchestrated through an access package that defines the coherent policy for a given context (production, partner, read-only, etc.).
Each layer has a different trust surface. User assignment is coarse. Conditional access is context-based. App roles and groups are attribute-based. Access packages are policy-coordinated. Together, they form a defense in depth.
When you are designing authorization for an AI agent, ask yourself:
- Should this agent be able to authenticate at all right now? (User assignment)
- Under what conditions (location, device, time) should token acquisition be allowed? (Conditional access)
- If the token is issued, what roles and group memberships should it carry? (App roles and group claims)
- How is the agent's access provisioned, reviewed, and revoked? (Access packages and lifecycle management)
If you can answer each question with a specific, enforceable policy, you have authorization architecture. If you are relying on the API layer alone to deny requests, you are carrying unnecessary risk.
References
- User assignment to enterprise applications
- Conditional Access for Agents in Microsoft Entra
- Recommended policies for autonomous agents in Microsoft Entra
- How to add app roles in apps
- Understanding the app manifest
- Protected Web API app configuration
- Configure group claims and app roles in tokens
- How to emit SAML claims based on application roles
Top comments (0)