Microsoft Entra ID: Understanding OAuth App Consent and Permissions

Microsoft Entra ID: Understanding OAuth App Consent and Permissions

Recently, Anthropic released a Microsoft 365 connector for Claude, their AI assistant. This connector allows Claude to interact with Microsoft 365 services on behalf of users and organizations. As part of deploying and testing this connector, I started looking more carefully at how OAuth app consent works in Microsoft Entra ID, and I noticed several misconceptions circulating online about how consent actually works, what it means when an admin grants consent, and how to properly scope access afterward.

In this blog post, I want to clarify how app consent works in Microsoft Entra ID, walk through the relevant configuration settings, and demonstrate this using a Microsoft App Consent Demo application I built for this purpose: https://consent.thalpius.com.

Table of Contents

  1. App Registration vs. Enterprise Application
  2. Consent and Permissions: User Consent Settings
  3. Consent and Permissions: Admin Consent Settings
  4. Consent and Permissions: Permission Classifications
  5. Admin Consent Scope: A Common Misconception
  6. Testing with consent.thalpius.com
  7. Conclusion

Disclaimer: This blog post is provided for informational purposes only. While every effort has been made to ensure accuracy, implementation of these features should be performed by qualified administrators in accordance with your organization’s security and change management policies. The author is not responsible for any issues, data loss, or security incidents that may occur from following this guidance. Always test in a non-production environment first and consult official Microsoft documentation before implementing security features in production.

App Registration vs. Enterprise Application

Before diving into consent settings, it is important to understand the distinction between an App Registration and an Enterprise Application in Microsoft Entra ID.

An App Registration is where you define your application. It is the developer-side object. Here you configure things like the application name, redirect URIs, API permissions the application requests, certificates and secrets, and the application manifest. The App Registration lives in the tenant where the application was created. Think of it as the blueprint or definition of the application.

An Enterprise Application, also called a Service Principal, is the tenant-side representation of an application. When an application is consented to, either by a user or an administrator, or manually added by an administrator, an Enterprise Application object is created in your tenant. This is where you manage access control, user assignments, single sign-on settings, and provisioning. Crucially, this is also where the consent granted to the application is recorded.

The relationship is straightforward: one App Registration can have many corresponding Enterprise Applications across different tenants. When a user successfully consents to a third-party application, or when an administrator grants consent or manually adds the application, an Enterprise Application object is created in your tenant to represent that application.

This distinction matters for consent. Consent is recorded on the Enterprise Application, not the App Registration.

The User Consent Settings page in the Microsoft Entra admin center controls whether end users are allowed to grant consent to applications on their own, without involving an administrator. You can find these settings under Enterprise apps > Consent and permissions > User consent settings.

There are three options available:

Do not allow user consent: All application consent requests require administrator approval. Users who attempt to sign into an application that requests permissions will be blocked and will see a prompt asking them to request admin approval. This is the most restrictive and most controlled option.

Allow user consent for apps from verified publishers, for selected permissions, Users can consent to applications, but only if two conditions are met: the requested permissions must be classified as low impact, and the application must either come from a verified publisher or be registered within your own organization. This option provides a balance between usability and security control.

Let Microsoft manage your consent settings (Recommended): Microsoft automatically applies its current recommended consent settings to your tenant, and updates them as its recommendations evolve. Under the current settings, users can consent to any user-consentable delegated permission, except for a specific set of sensitive permissions that Microsoft has explicitly excluded, such as Mail.Read, Files.ReadWrite.All, Calendars.ReadWrite, and similar high-impact scopes. This is also the default for newly created tenants.

The screenshot below shows these three options as they appear in the Microsoft Entra admin center, with the verified publishers option currently selected.

Image 1: The User Consent Settings page in the Microsoft Entra admin center, showing the three available options for controlling end-user consent behavior. The second option, allowing consent for apps from verified publishers or apps registered in this organization for low-impact permissions, is currently selected.

Choosing the right option depends on your organization’s risk appetite. In high-security environments, disabling user consent entirely and requiring administrator approval for all applications is the appropriate choice. For most organizations, restricting user consent to verified publishers with low-impact permissions provides a good default.

The Admin Consent Settings page controls how users can request administrator review and approval for applications they want to use but cannot consent to themselves. You can find these settings under Enterprise Apps > Consent and permissions > Admin consent settings.

Image 2: The Admin Consent Settings page in the Microsoft Entra admin center, showing the Admin Consent Workflow enabled with designated reviewers and the configured reminder interval.

The key feature here is the Admin Consent Workflow. When this is enabled, users who are blocked from consenting to an application are given an option to submit a request for admin approval rather than simply seeing an error. Administrators designated as reviewers are notified and can approve or deny the request from within the Microsoft Entra admin center.

Configuring this workflow is an important companion to restricting user consent. If you restrict user consent without enabling the workflow, users are simply blocked with no path forward. With the workflow enabled, the experience is significantly better: users can explain why they need the application, and administrators have a managed queue to review.

The Admin Consent Workflow settings allow you to:

  • Enable or disable the workflow entirely
  • Designate which users or groups act as admin consent reviewers
  • Configure whether reviewers receive email notifications when new requests are submitted
  • Set a reminder interval for pending requests

Recommended practice: Enable the Admin Consent Workflow and designate at least two reviewers to avoid a single point of failure. Reviewers should have sufficient technical knowledge to evaluate the permissions an application is requesting, not just the ability to approve requests. A helpdesk employee or manager is rarely the right choice. Configure the reminder interval to ensure requests do not go unnoticed.

The Admin Consent Workflow is only effective when combined with restricted user consent settings. If users can consent freely, they will simply bypass the workflow by consenting themselves. The workflow should be treated as the controlled path for application access requests, not an optional addition on top of an already permissive consent configuration.

The Permission classifications page allows you to classify specific API permissions as low, medium, or high impact. You can find this under Enterprise Applications > Consent and permissions > Permission classifications.

Image 3: The Permission Classifications page in the Microsoft Entra admin center, showing the five permissions classified as low impact by default: openid, profile, email, offline_access, and User.Read.

Permission classifications work hand in hand with the User Consent Settings. When you configure user consent to allow consent for verified publishers with selected permissions, the “selected permissions” refers specifically to the permissions you have classified as low impact.

By default, Microsoft pre-classifies a small set of permissions as low impact, typically OpenID Connect scopes like `openid`, `profile`, `email`, `offline_access`, and `User.Read`. These are the five permissions that appear when you click the link labeled “5 permissions classified as low impact” on the User Consent Settings page.

You can extend this list by classifying additional permissions as low impact, which expands what users are allowed to consent to without admin involvement. Equally important, you can use medium and high classifications to signal to administrators which permissions in the consent workflow deserve extra scrutiny.

Use permission classifications thoughtfully. A permission like `Mail.Read` or `Files.ReadWrite.All` should not be classified as low impact, as these provide significant access to organizational data. Stick to authentication and basic profile scopes for low-impact classification.

This is the misconception I see most frequently, and it is an important one to address.

When an administrator grants consent to an application in Microsoft Entra ID, they grant consent for the entire organization. This means every user in the tenant can potentially use the application with the consented permissions. The admin consent is tenant-wide, not scoped to specific users or groups.

Many administrators assume that granting admin consent inherently limits access to themselves or to a small group. It does not. After admin consent is granted, any user who can reach the application’s sign-in URL can authenticate and the application will have the consented permissions for that user’s data.

The correct way to scope access after granting admin consent is through the Enterprise Application’s assignment settings.

To properly scope access:

1. Navigate to the Enterprise Application in the Microsoft Entra admin center.

2. Go to Properties and set “Assignment required?” to Yes. This ensures that only users, or members of groups, explicitly assigned to the application can sign in. Without this, any user in your tenant can access the application.

Image 4: The Properties page of an Enterprise Application in the Microsoft Entra admin center, showing the “Assignment required?” setting configured to “Yes” to restrict access to explicitly assigned users and groups only.

3. Navigate to Users and groups on the Enterprise Application and add the specific users or groups who should have access.

Image 5: The Users and groups page of an Enterprise Application in the Microsoft Entra admin center, showing the users and groups explicitly assigned to scope access after admin consent has been granted.

This combination, admin consent at the tenant level plus assignment-required scoping at the Enterprise Application level, gives you the correct security model. Admin consent covers the permission grant, and the assignment covers who can actually use those permissions.

Skipping the assignment step is a common mistake. An administrator grants consent thinking they have done the necessary security work, but the application remains accessible to the entire organization.

To make these concepts easier to explore hands-on, I have built a test application available at https://consent.thalpius.com.

Image 6: The consent test application at consent.thalpius.com, which can be used to walk through the OAuth consent flow against Microsoft Entra ID and observe the behavior under different consent configurations.
Image 7: The consent test application at consent.thalpius.com, which can be used to walk through the OAuth consent flow against Microsoft Entra ID and observe the behavior under different consent configurations.

This application lets you walk through the OAuth consent flow against Microsoft Entra ID and observe exactly what happens at each stage, from the initial authorization request, through the consent prompt, to the resulting token. You can test the behavior under different user consent settings, observe what the consent prompt looks like for verified versus unverified publishers, and see how permission classifications affect what users are allowed to consent to.

I recommend testing this application in a non-production tenant or a dedicated test tenant where you can freely modify the consent settings described in this post without impacting your organization’s users.

Conclusion

Understanding OAuth app consent in Microsoft Entra ID is fundamental to securing your organization’s identity environment. As applications like the Anthropic Microsoft 365 connector become more common, having a clear understanding of how consent is granted, what it means at the organizational level, and how to properly scope access afterward is essential knowledge for every identity administrator.

The settings described in this post, user consent settings, admin consent workflow, permission classifications, and enterprise application assignment, work together as a complete control framework. Each layer addresses a different aspect of the problem, and skipping any one of them leaves a gap.

Microsoft Entra Agent ID: A Practical Guide to Blueprints and Agent Identities

Microsoft Entra Agent ID: A Practical Guide to Blueprints and Agent Identities

As AI agents become an increasingly important part of modern work, organizations need a way to govern them with the same level of control and consistency applied to human identities. Microsoft Entra Agent ID is the identity platform purpose-built for AI agents. It extends the security and governance capabilities of Microsoft Entra, including Conditional Access, Identity Protection, and audit logs, to the agents running in your tenant.

At its core, Microsoft Entra Agent ID introduces a new identity model built around three key concepts: the Blueprint, the Blueprint Identity, and the Agent Identity. Understanding how these fit together is essential before deploying or governing agents at scale.

Table of Contents

  1. Classic Agents vs. Modern Agents
  2. What is an Agent Identity Blueprint?
  3. What is a Blueprint Identity?
  4. What is an Agent Identity?
  5. What is an Agent User?
  6. How It All Fits Together

Disclaimer: This blog post is provided for informational purposes only. While every effort has been made to ensure accuracy, implementation of these features should be performed by qualified administrators in accordance with your organization’s security and change management policies. The author is not responsible for any issues, data loss, or security incidents that may occur from following this guidance. Always test in a non-production environment first and consult official Microsoft documentation before implementing security features in production.

Classic Agents vs. Modern Agents

Before diving into the concepts, it is worth understanding the distinction between classic and modern agents, as both may exist in your tenant simultaneously.

Classic agents are AI agents created as standard service principals or app registrations, for example, agents built in Copilot Studio before the Microsoft Entra Agent ID platform was enabled. They appear in the Microsoft Entra Agent Registry with ‘Has Agent ID: No’. Classic agents cannot be protected by Microsoft Entra Agent ID security features such as Identity Protection for Agents or Conditional Access for Agents.

Modern agents are agents created through the Microsoft Entra Agent ID platform, each backed by an Agent Identity Blueprint. They have a proper Agent ID, full audit trail, and support the complete set of governance capabilities.

Microsoft has indicated a migration tool is planned to help convert classic agents to modern agents. In the meantime, it is worth auditing your tenant to understand which agents fall into which category.

Image 1: The overview shows a clear breakdown of agent types in the tenant. Modern agents appear as ‘Agent identities’, while classic agents show up as ‘Agents with service principals’ or ‘Agents with no identities’, the latter being agents registered in the Agent Registry without an associated Entra Agent ID.

What is an Agent Identity Blueprint?

An Agent Identity Blueprint is an object in Microsoft Entra ID that serves as a template for creating agent identities. It establishes the foundation for how agents are created, authenticated, and managed within an organization. All modern agent identities in a Microsoft Entra ID tenant are created from an agent identity blueprint.

A blueprint serves four purposes:

Template: Blueprints record shared characteristics so that all agent identities created using the blueprint have a consistent configuration. Organizations can deploy many instances of an AI agent, each pursuing a different goal and requiring a different level of access, yet they all share a common foundation.

Identity: A blueprint is not just an information store. It is also a special identity type within a Microsoft Entra ID tenant. A blueprint can perform exactly one operation in the tenant: provision or deprovision agent identities.

Credential container: Agent identities do not have credentials of their own. Instead, the credentials used to authenticate are configured on the blueprint. When an AI agent wants to perform an operation, the blueprint’s credentials are used to request an access token from Entra ID.

Management container: Identity administrators can apply policies and settings to a blueprint that takes effect for all agent identities created from it. Examples include Conditional Access policies and OAuth permissions granted at the blueprint level.

Technically, a blueprint consists of two parts: the blueprint application, which defines the configuration, and a Blueprint Principal, the service principal that makes the blueprint visible and usable within the tenant. This is conceptually similar to the relationship between an App Registration and an Enterprise Application.

Image 2: The blueprint detail page in the Microsoft Entra admin center, showing the linked agent identity, description, and management tabs including access, owners, sponsors, and audit logs.

What is a Blueprint Identity?

An Agent Identity Blueprint Principal is an object in Microsoft Entra Agent ID that represents the presence of an agent identity blueprint within a specific tenant. When an agent identity blueprint is added to a tenant, Microsoft Entra creates a corresponding principal object.

The principal has two important roles:

Token Issuance: When the blueprint is used to acquire tokens within a tenant, the resulting token’s object ID claim references the blueprint principal. This ensures that any authentication or authorization performed by the blueprint is traceable to its principal object in the tenant.

Audit Logging: Actions performed by the blueprint, such as creating agent identities, are recorded in audit logs as being executed by the blueprint principal.

This is what gives you visibility and accountability. Every action taken by the blueprint shows up in the Microsoft Entra audit logs under the principal’s identity.

What is an Agent Identity?

An Agent Identity is a new identity type in Microsoft Entra ID, built on the service principal model but purpose-built for AI agents. It represents an identity that the agent identity blueprint created and is authorized to impersonate. It does not have credentials of its own, the agent identity blueprint acquires tokens on behalf of the agent identity, provided the user or tenant admin consented to the corresponding scopes.

Each agent identity has the following key properties:

  • A unique object ID generated by Microsoft Entra
  • A display name visible in experiences like the Entra admin center and the Azure portal
  • A sponsor, the human user or group accountable for the agent (required)
  • An owner, the person responsible for operational management of the agent (recommended)

The platform supports two primary patterns for how agents operate:

Interactive agents sign in a user and act in response to user prompts, often via a chat interface. They act on behalf of the signed-in user using delegated permissions, and the tokens issued to them are called user tokens.

Autonomous agents perform actions using their own identity, often running in the background and making autonomous decisions. They use app-only tokens (also called agent tokens) and operate without user involvement.

Image 3: The agent identity detail page in the Microsoft Entra admin center, showing the sponsor, the parent blueprint, and direct links to Conditional Access policies and access packages for governance.

What is an Agent User?

An Agent User is an optional secondary account for scenarios where a system strictly requires a Microsoft Entra user object for authentication. Think of it as a digital worker, an account that behaves like a user, but is owned and controlled by an agent identity.

An agent user is a standard user account decorated as an AI agent, with a strict 1:1 relationship to its parent agent identity. It cannot have passwords or passkeys, cannot be assigned privileged administrator roles, and cannot perform interactive sign-ins. Authentication happens exclusively through the parent agent identity’s credentials.

Agent users are relevant when an agent needs to interact with systems that only accept user tokens, for example, accessing a mailbox or joining a Teams meeting as a participant.

How It All Fits Together

To summarize the relationship between these concepts:

An Agent Identity Blueprint is the template, it defines the configuration, holds the credentials, and can create agent identities. A Blueprint Principal is the tenant-specific instance of that blueprint, visible in the Microsoft Entra portal and responsible for token issuance and audit logging. An Agent Identity is a single AI agent created from the blueprint, with its own object ID and governance properties. An Agent User is an optional user account linked 1:1 to an agent identity for systems that require user authentication.

One blueprint can back many agent identities, each representing a different instance or deployment of the same type of agent. This 1:N relationship is what makes blueprints powerful for organizations running agents at scale.

Image 4: The relationship between the Agent Identity Blueprint, Blueprint Principal, Agent Identities, and the optional Agent User. One blueprint can back multiple agent identities, establishing a 1:N relationship.

One of the most powerful aspects of this model is the way Conditional Access policies integrate with blueprints. Because a blueprint acts as a management container for all agent identities created from it, a single Conditional Access policy applied to the blueprint automatically takes effect for every agent identity it produced. This means you can enforce access controls, such as blocking authentication from outside trusted networks or requiring compliant devices, across an entire fleet of agents in one place, without having to configure policies per individual agent identity.

Microsoft Orphaned Agents Identities: The hidden identity debt in your Entra tenant

Microsoft Orphaned Agents Identities: The hidden identity debt in your Entra tenant

In my previous post, I covered agents without an Owner or Sponsor, identities with no one accountable for them. This blog post covers a related but distinct problem: agents that have lost their parent Blueprint entirely.

Microsoft Entra supports two types of agents. Classic agents are Service Principals with no parent Blueprint. They were created before the Agent Identity platform existed, or in Microsoft Copilot Studio without the modern Agent Identity setting enabled. Modern agents are Agent Identities, each created from an Agent Identity Blueprint that holds the credentials, defines the configuration, and enables token exchange.

When a Blueprint is deleted, the modern Agent Identities it created are not automatically removed. They remain in the tenant. This blog post explains what happens to those agents, why it matters, and how to find and remove them.

Table of Contents

  1. Why orphaned agents are a security risk
  2. Finding Orphaned Agents
    1. Step 1 – Retrieve all Agent Identities and their Blueprint ID
    2. Step 2 – Retrieve all active Blueprint Principals
    3. Step 3 – Cross-reference to find orphaned Agent Identities
    4. Step 4 – Find orphaned Agent Users
  3. Recommendation
    1. Remove an orphaned Agent Identity
    2. Remove an orphaned Agent User
  4. Conclusion

Disclaimer: This blog post is provided for informational purposes only. While every effort has been made to ensure accuracy, implementation of these features should be performed by qualified administrators in accordance with your organization’s security and change management policies. The author is not responsible for any issues, data loss, or security incidents that may occur from following this guidance. Always test in a non-production environment first and consult official Microsoft documentation before implementing security features in production.

Why orphaned agents are a security risk

When a Blueprint is deleted, two types of orphaned objects remain:

Orphaned Agent Identities remain in the tenant as abandoned identities. They can no longer authenticate, without the Blueprint there is no token exchange possible. However, they retain all permissions that were assigned to them. Any Graph API permissions, Azure RBAC roles, or Microsoft Entra directory roles assigned to the agent remain intact. These are unclaimed permission assignments with no active owner, no Blueprint, and no accountability.

Orphaned Agent Users are the more dangerous remnant. When an agent was paired with an Agent User, that user object remains in the tenant after the Blueprint is deleted. It is not shown as disabled or deleted in the Entra portal, it appears as a normal user account with no indication that it belongs to a deleted agent. Although it cannot authenticate, it may still hold group memberships, licenses, or resource access that nobody owns or reviews. Without a Sponsor and without any flag marking it as orphaned, it exists completely outside your governance process.

The combination creates identity debt: objects with permissions attached that exist outside any governance process, with no one responsible for cleaning them up.

Finding Orphaned Agents

Microsoft does not automatically flag orphaned Agent Identities or Agent Users. Detection requires querying the tenant and identifying objects whose parent Blueprint no longer exists.

Note: Due to a known preview limitation, users assigned the Global Reader role receive a 403 Unauthorized response on the microsoft.graph.agentIdentity endpoint. Use an account with Agent ID Administrator rights to run these scripts.

Step 1 – Retrieve all Agent Identities and their Blueprint ID

Connect-MgGraph -Scopes "AgentIdentity.Read.All"

$agents = Invoke-MgGraphRequest -Method GET `
    -Uri "https://graph.microsoft.com/beta/servicePrincipals/microsoft.graph.agentIdentity" `
    -OutputType PSObject

if ($agents.value.Count -eq 0) {
    Write-Host "No Agent Identities found." -ForegroundColor Yellow
} else {
    Write-Host "Found $($agents.value.Count) Agent Identity/Identities. Continue with Step 2." -ForegroundColor Green
    $agents.value | Select-Object displayName, id, agentIdentityBlueprintId
}
Image 1: Retrieving Agent Identities and their Blueprint ID

Step 2 – Retrieve all active Blueprint Principals

Connect-MgGraph -Scopes "AgentIdentityBlueprintPrincipal.Read.All"

$blueprints = Invoke-MgGraphRequest -Method GET `
    -Uri "https://graph.microsoft.com/beta/servicePrincipals/microsoft.graph.agentIdentityBlueprintPrincipal" `
    -OutputType PSObject

$activeBlueprintIds = $blueprints.value | Select-Object -ExpandProperty appId

if ($activeBlueprintIds.Count -eq 0) {
    Write-Host "No active Blueprints found." -ForegroundColor Yellow
} else {
    Write-Host "Found $($activeBlueprintIds.Count) active Blueprint(s). Continue with Step 3." -ForegroundColor Green
}

Step 3 – Cross-reference to find orphaned Agent Identities

Connect-MgGraph -Scopes "AgentIdentity.Read.All", "AgentIdentityBlueprintPrincipal.Read.All"

$agents = Invoke-MgGraphRequest -Method GET `
    -Uri "https://graph.microsoft.com/beta/servicePrincipals/microsoft.graph.agentIdentity" `
    -OutputType PSObject

$blueprints = Invoke-MgGraphRequest -Method GET `
    -Uri "https://graph.microsoft.com/beta/servicePrincipals/microsoft.graph.agentIdentityBlueprintPrincipal" `
    -OutputType PSObject

$activeBlueprintIds = $blueprints.value | Select-Object -ExpandProperty appId
$orphanedAgents = @()

foreach ($agent in $agents.value) {
    if ($activeBlueprintIds -notcontains $agent.agentIdentityBlueprintId) {
        $orphanedAgents += $agent
        Write-Host "Orphaned Agent Identity: $($agent.displayName) | ID: $($agent.id) | Blueprint: $($agent.agentIdentityBlueprintId)" -ForegroundColor Red
    }
}

if ($orphanedAgents.Count -eq 0) {
    Write-Host "No orphaned Agent Identities found. Continue with Step 4." -ForegroundColor Green
}
Image 2: Finding orphaned Agent Identities

Step 4 – Find orphaned Agent Users

Connect-MgGraph -Scopes "User.Read.All", "AgentIdentity.Read.All"

$agentUsers = Invoke-MgGraphRequest -Method GET `
    -Uri "https://graph.microsoft.com/beta/users?`$filter=isof('microsoft.graph.agentUser')" `
    -Headers @{ "ConsistencyLevel" = "eventual" } `
    -OutputType PSObject

$orphanedUsers = @()

foreach ($user in $agentUsers.value) {
    $parentAgent = $null
    try {
        $parentAgent = Invoke-MgGraphRequest -Method GET `
            -Uri "https://graph.microsoft.com/beta/servicePrincipals/$($user.identityParentId)" `
            -OutputType PSObject
    } catch {}

    if (-not $parentAgent) {
        $orphanedUsers += $user
        Write-Host "Orphaned Agent User: $($user.displayName) | UPN: $($user.userPrincipalName) | Parent ID: $($user.identityParentId)" -ForegroundColor Red
    }
}

if ($orphanedUsers.Count -eq 0) {
    Write-Host "No orphaned Agent Users found." -ForegroundColor Green
}

Disconnect-MgGraph
Image 3: Finding orphaned Agent Users

Recommendation

Orphaned agents cannot authenticate, but they should not remain in the tenant. The recommended action for any orphaned object is removal.

Remove an orphaned Agent Identity

Connect-MgGraph -Scopes "AgentIdentity.ReadWrite.All"

$agentId = "<Agent-Object-ID>"

Invoke-MgGraphRequest -Method DELETE `
    -Uri "https://graph.microsoft.com/beta/servicePrincipals/$agentId"

Write-Host "Orphaned Agent Identity removed." -ForegroundColor Green

Disconnect-MgGraph

Remove an orphaned Agent User

Connect-MgGraph -Scopes "User.ReadWrite.All"

$userId = "<Agent-User-Object-ID>"

Invoke-MgGraphRequest -Method DELETE `
    -Uri "https://graph.microsoft.com/beta/users/$userId"

Write-Host "Orphaned Agent User removed." -ForegroundColor Green

Disconnect-MgGraph

Before removing any object, verify the permissions assigned to it. An orphaned Agent Identity may hold Graph API permissions or Azure RBAC roles that require separate cleanup. Removing the identity does not automatically revoke role assignments in Azure.

Process control: When decommissioning an agent, always delete Agent Identities and Agent Users before deleting the Blueprint. Deleting the Blueprint first creates the orphaned state described in this post.

Detective control: Run the detection scripts on a recurring schedule via Azure Automation. Any orphaned object found triggers an alert for immediate remediation.

Conclusion

Deleting a Blueprint does not clean up what it created. Agent Identities and Agent Users remain in the tenant, invisible as a risk, retaining permissions with no one accountable for them. Microsoft requires manual removal, there is no automatic cleanup.

The correct decommissioning order matters: remove Agent Users first, then Agent Identities, then the Blueprint. Reversing that order creates the orphaned state this post describes.

The detection scripts give you visibility into what already exists. The process control prevents the problem from recurring.

Recommended action: Run the detection scripts against your tenant. Remove any orphaned Agent Identities and Agent Users found. Then update your agent decommissioning process to follow the correct deletion order.

Microsoft Ownerless Agents: The silent risk in your Entra tenant

Microsoft Ownerless Agents: The silent risk in your Entra tenant

AI agents are being deployed faster than they are being governed. Every agent created in Microsoft Copilot Studio or Microsoft Foundry becomes an identity in Microsoft Entra ID. Depending on how and when the agent was created, this is either a classic Service Principal or a modern Agent Identity, each with different governance and security implications.

Unlike user accounts, agents do not have a manager. There is no automatic assignment of accountability when an agent is created. Unless explicitly configured, an agent can exist in your tenant with no one responsible for it.

An ownerless agent means:

  • No one is managing its credentials or secret rotation
  • No one reviews whether its permissions are still appropriate
  • No one notices when it behaves anomalously
  • No one decommissions it when the project ends

The agent continues to run, and continues to have access, indefinitely. This blog post explains what ownerless and sponsorless agents are, why they are a security risk, and how to detect and remediate them in your Microsoft Entra tenant.

Table of Contents

  1. Owner vs. Sponsor, What is the difference?
  2. Finding Ownerless and Sponsor-less Agents
  3. Recommendation
  4. Conclusion

Disclaimer: This blog post is provided for informational purposes only. While every effort has been made to ensure accuracy, implementation of these features should be performed by qualified administrators in accordance with your organization’s security and change management policies. The author is not responsible for any issues, data loss, or security incidents that may occur from following this guidance. Always test in a non-production environment first and consult official Microsoft documentation before implementing security features in production.

Owner vs. Sponsor, What is the difference?

Microsoft Entra Agent Identities support two distinct accountability roles:

Owner is the technical administrator responsible for operational management, setup, configuration, and credential management. The Owner is assigned to the Agent Identity Blueprint, think of the Owner as the person who keeps the blueprint and its credentials correctly configured. Because all Agent Identities inherit their configuration from the Blueprint, managing the Owner at Blueprint level covers all Agent Identities created from it.

Sponsor is the business representative accountable for the agent’s purpose and lifecycle. The Sponsor is the person who can answer: “Why does this agent exist, and is it still needed?”

Both roles are optional at creation time. Both are critical for governance. Without a Sponsor, no one can request or approve Access Packages on behalf of the agent. Without an Owner, credentials go unmanaged and anomalies go unnoticed.

Finding Ownerless and Sponsor-less Agents

Via the Entra portal: Navigate to Entra ID > Agent ID (Preview) > All agent Identities (Preview). The overview shows all agents in your tenant. Add the Agent Blueprint ID column to distinguish modern agents (with a Blueprint ID) from classic agents (Service Principals).

For modern agents, inspect the details of each agent to verify whether an Owner and Sponsor are assigned.

Image 1: Setting an Owner or Sponsor using the Entra portal

At the time of writing, the Microsoft Entra portal allows an Owner to be assigned directly to an Agent Identity. However, Microsoft documentation recommends assigning the Owner to the Agent Identity Blueprint, as all Agent Identities inherit their configuration from it.

Via Microsoft Graph API: For scale, use PowerShell to query all Agent Identities and report on missing Owners and Sponsors. Find all Agent Identities without a Sponsor and all Blueprints without an Owner:

Connect-MgGraph -Scopes "AgentIdentity.Read.All", "AgentIdentityBlueprint.Read.All"

$findings = @()

# Check Agent Identities without a Sponsor
$agents = Invoke-MgGraphRequest -Method GET `
    -Uri "https://graph.microsoft.com/beta/servicePrincipals/microsoft.graph.agentIdentity" `
    -OutputType PSObject

foreach ($agent in $agents.value) {
    $sponsors = Invoke-MgGraphRequest -Method GET `
        -Uri "https://graph.microsoft.com/beta/servicePrincipals/$($agent.id)/sponsors" `
        -OutputType PSObject

    if ($sponsors.value.Count -eq 0) {
        $findings += $agent
        Write-Host "No Sponsor: $($agent.displayName) | ID: $($agent.id)" -ForegroundColor Red
    }
}

# Check Blueprints without an Owner
$blueprints = Invoke-MgGraphRequest -Method GET `
    -Uri "https://graph.microsoft.com/beta/applications/microsoft.graph.agentIdentityBlueprint" `
    -OutputType PSObject

foreach ($blueprint in $blueprints.value) {
    $owners = Invoke-MgGraphRequest -Method GET `
        -Uri "https://graph.microsoft.com/beta/applications/$($blueprint.id)/owners" `
        -OutputType PSObject

    if ($owners.value.Count -eq 0) {
        $findings += $blueprint
        Write-Host "No Owner: $($blueprint.displayName) | ID: $($blueprint.id)" -ForegroundColor Red
    }
}

if ($findings.Count -eq 0) {
    Write-Host "No issues found. All Agent Identities have a Sponsor and all Blueprints have an Owner." -ForegroundColor Green
}

Disconnect-MgGraph

Recommendation

Owner and Sponsor assignment cannot be technically enforced at creation time, Microsoft does not provide a native policy to make these fields mandatory. The most effective approach is a combination of two controls.

Process control: Require Owner and Sponsor assignment as part of your internal agent publishing or deployment process. For Microsoft Copilot Studio this means a mandatory approval step before production publishing. For Microsoft Foundry this means including Owner binding on the Blueprint and Sponsor binding on the Agent Identity in your provisioning script. Both controls only work if everyone follows the process, direct creation via the portal or Graph API bypasses them entirely.

Detective control: Run the detection script on a recurring schedule via Azure Automation. Any agent found without an Owner or Sponsor triggers an alert for immediate remediation.

Neither control alone is sufficient. The process prevents the gap from occurring; the detection script catches what the process misses.

Script 1 – Assign an Owner to a Blueprint:

Connect-MgGraph -Scopes "AgentIdentityBlueprint.ReadWrite.All"

$blueprintId = "<Blueprint-App-ID>"
$ownerUserId = "<Owner-User-ID>"

$existingOwners = Invoke-MgGraphRequest -Method GET `
    -Uri "https://graph.microsoft.com/beta/applications/$blueprintId/owners" `
    -OutputType PSObject

$alreadyOwner = $existingOwners.value | Where-Object { $_.id -eq $ownerUserId }

if ($alreadyOwner) {
    Write-Host "Owner already assigned to Blueprint, skipping." -ForegroundColor Yellow
} else {
    $ownerBody = @{
        "@odata.id" = "https://graph.microsoft.com/beta/users/$ownerUserId"
    } | ConvertTo-Json

    Invoke-MgGraphRequest -Method POST `
        -Uri "https://graph.microsoft.com/beta/applications/$blueprintId/owners/`$ref" `
        -Body $ownerBody `
        -ContentType "application/json"

    Write-Host "Owner assigned to Blueprint successfully." -ForegroundColor Green
}

Disconnect-MgGraph

Script 2 – Assign a Sponsor to an Agent Identity:

Connect-MgGraph -Scopes "AgentIdentity.ReadWrite.All"

$agentId       = "<Agent-Object-ID>"
$sponsorUserId = "<Sponsor-User-ID>"

$existingSponsors = Invoke-MgGraphRequest -Method GET `
    -Uri "https://graph.microsoft.com/beta/servicePrincipals/$agentId/sponsors" `
    -OutputType PSObject

$alreadySponsor = $existingSponsors.value | Where-Object { $_.id -eq $sponsorUserId }

if ($alreadySponsor) {
    Write-Host "Sponsor already assigned to Agent Identity, skipping." -ForegroundColor Yellow
} else {
    $sponsorBody = @{
        "@odata.id" = "https://graph.microsoft.com/beta/users/$sponsorUserId"
    } | ConvertTo-Json

    Invoke-MgGraphRequest -Method POST `
        -Uri "https://graph.microsoft.com/beta/servicePrincipals/$agentId/sponsors/`$ref" `
        -Body $sponsorBody `
        -ContentType "application/json"

    Write-Host "Sponsor assigned to Agent Identity successfully." -ForegroundColor Green
}

Disconnect-MgGraph

Conclusion

A Blueprint without an Owner or an Agent Identity without a Sponsor is an identity without accountability. It can accumulate permissions, run indefinitely, and operate completely outside your governance framework, not because someone made a bad decision, but because no one made any decision at all.

Microsoft makes Owner and Sponsor optional at creation time. That default is a governance risk. The detection script gives you visibility today. The process control reduces the gap tomorrow, but only if consistently followed. Schedule the script to run on a recurring basis so exceptions are caught before they become incidents.

Recommended action: Run the detection script against your tenant. For every agent without an Owner or Sponsor, assign one before the end of the week. Then build the assignment into your agent deployment process so it never happens again.

Microsoft 365 Copilot: Why self-service trials are a security risk

Microsoft 365 Copilot: Why self-service trials are a security risk

Every day, employees across your organization are just a few clicks away from activating Microsoft 365 Copilot, without involving IT, without security review, and without completing any required training. By default, Microsoft enables self-service trials and purchases directly in the Microsoft 365 admin portal, meaning a motivated user can have Microsoft 365 Copilot running within minutes, whether through a free trial or a personal credit card purchase.

Table of Contents

  1. Microsoft 365 Admin Center: Self-service trials and purchases
  2. The Security Risks
  3. Recommendation
  4. Conclusion

Disclaimer: This blog post is provided for informational purposes only. While every effort has been made to ensure accuracy, implementation of these features should be performed by qualified administrators in accordance with your organization’s security and change management policies. The author is not responsible for any issues, data loss, or security incidents that may occur from following this guidance. Always test in a non-production environment first and consult official Microsoft documentation before implementing security features in production.

Microsoft 365 Admin Center: Self-service trials and purchases

Microsoft enables self-service capabilities in the admin-portal for new products by default. This means users in your organization can independently sign up for trials or purchase Microsoft 365 services, including Microsoft Copilot-related products, without IT approval. While this accelerates adoption, it creates significant governance challenges for security teams.

For Copilot specifically, a short training is often required to ensure safe and responsible usage. When users independently activate a trial, they typically bypass this onboarding process, meaning they may start using Copilot without understanding data sensitivity, prompt risks, or organizational policies. This creates a direct security risk: users could inadvertently expose confidential information or misuse AI capabilities before governance controls are in place.

Self-service encompasses two distinct scenarios:

Self-Service Trials: Users can start free trials of Microsoft products. Some trials require no payment method and simply expire after the trial period. Others require a credit card and automatically convert to paid subscriptions if not canceled.

Self-Service Purchases: Users can purchase Microsoft products using their personal credit card. The individual user becomes the billing contact, but the organization retains ownership of all data created during the subscription.

The Security Risks

When users can independently acquire Microsoft 365 Copilot licenses or related AI services, several security concerns emerge:

  1. Shadow AI Deployment: Copilot capabilities may be active in your environment without security review, data classification, or proper governance frameworks, and without users completing the training required for safe and responsible usage.
  2. Uncontrolled Data Access: Self-service users gain access to organizational data through Microsoft Copilot without assessment of their data handling requirements.
  3. License Sprawl: Multiple uncoordinated purchases create license management complexity and possible increase costs.
  4. Compliance Gaps: Departmental purchases may bypass required compliance checks, audit trails, or data residency requirements.
  5. Support Challenges: Users may not understand enterprise support processes, leading to shadow IT support requests.

Recommendation

Location: Microsoft 365 Admin Center > Settings > Org settings > Services > Self-service trials and purchases

The Self-service trials and purchases page displays all products eligible for self-service in your organization. For each product, you can configure one of three options:

  1. Allow: Users can both start trials AND purchase the product
  2. Allow for trials only: Users can start trials but cannot make purchases (requires admin approval to convert)
  3. Do not allow: Both trials and purchases are blocked entirely

Microsoft manages self-service controls on a per-product basis. There is no single switch to disable all self-service capabilities tenant-wide. You must configure each product individually.

For Microsoft 365 Copilot and related AI services, the recommended security posture is: Do not allow

This configuration:

  • Blocks users from buying Microsoft 365 Copilot without IT approval
  • Prevents individual purchases that bypass security review
  • Ensures all Microsoft 365 Copilot deployments follow your organization’s AI governance framework
  • Maintains centralized license management and cost control

When self-service purchase is enabled, users attempting to acquire Microsoft 365 Copilot proceed directly to the checkout flow. 

image 1: User purchasing a Microsoft Copilot license

When self-service purchase is disabled, users attempting to acquire Microsoft 365 Copilot encounter a blocking message during the checkout flow. 

Image 2: User blocked from purchasing a Microsoft Copilot license

Conclusion

The Self-service trials and purchases setting is your first line of defense in controlling not just Microsoft 365 Copilot adoption, but all self-service capable products within your organization. By configuring this setting to “Do not allow“, you prevent users from independently acquiring licenses with their personal credit cards, a scenario that creates shadow IT deployments outside your security governance framework.

Organizations must evaluate their tolerance for self-service purchases across the entire Microsoft product portfolio. Products like Power BI Pro, Power Apps, Visio, and dozens of other services are also eligible for self-service purchase. Each product represents a potential governance gap where users can bypass procurement processes, introduce unvetted tools, and create compliance risks.

Microsoft enables this capability by default for new products, requiring proactive configuration rather than reactive management. Without centralized control, users can purchase access within minutes, immediately gaining access to organizational data and creating integration points that may conflict with security policies, data classification requirements, or compliance frameworks.

This single setting, applied strategically across your product portfolio, transforms software acquisition from an uncontrolled user-driven process into a managed IT initiative where every license assignment follows your organization’s governance policies, data protection requirements, and security standards.

Recommended action: Navigate to Microsoft 365 Admin Center > Settings > Org settings > Self-service trials and purchases. Review the complete list of products available for self-service purchase and determine which products align with your organization’s risk tolerance. At minimum, set Microsoft 365 Copilot to “Do not allow” today. Consider extending this control to other high-risk or high-cost products based on your organization’s procurement and governance requirements.