Microsoft Purview vs. Defender for Cloud Apps: Preventing vs. Correcting Data Exposure

Microsoft Purview vs. Defender for Cloud Apps: Preventing vs. Correcting Data Exposure

A finance employee applies a Confidential label to a spreadsheet, works on it for a few days, and then shares it with an external consultant through a link in Teams. Depending on how the tenant is configured, that share attempt is either stopped in real time, or it goes through completely unnoticed until someone reviews it weeks later. Which of those two outcomes happens depends entirely on which Microsoft security tool is doing the watching, and at what point in the document’s lifecycle it gets involved.

This is exactly where Microsoft Purview and Microsoft Defender for Cloud Apps get confused as doing “the same thing” for data protection. They do not. One prevents an action before it happens. The other cleans up after data has already moved. In this post, I will walk through both sides with concrete policy examples, and explain why most mature environments end up running both rather than picking one over the other.

Table of Contents

  1. Two Different Moments of Control
  2. Microsoft Purview DLP: Blocking Data After Classification
  3. Microsoft Defender for Cloud Apps: Revoking Access on Already-Shared Files
  4. Why You Need Both
  5. 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.

Two Different Moments of Control

A question I get regularly: “We have Microsoft Purview, so why do we also need Defender for Cloud Apps for data protection?” The short answer is that they intervene at two different moments in a document’s lifecycle. Purview prevents sensitive data from going down the wrong path in the first place. Defender for Cloud Apps cleans up what has already been shared. Neither one replaces the other; they cover different gaps.

Microsoft Purview DLP: Blocking Data After Classification

Microsoft Purview Data Loss Prevention (DLP) intervenes at the moment a user tries to do something with a document: sending it by email, uploading it to a cloud app, pasting it into a browser, or sharing it outside the organization.

That intervention depends entirely on classification. Before a DLP rule can block anything, Purview first needs to know that a document is sensitive. This is done through:

  • Sensitive information types (SITs): pattern-based detection such as credit card numbers, national identification numbers, or customer IDs
  • Sensitivity labels: applied manually by users or automatically based on content, for example Confidential or Internal
  • Trainable classifiers: machine-learning-based recognition of content types such as contracts or financial statements

Once content is classified as sensitive, a DLP policy can act on it. A common example: a user tries to share a document labeled Confidential with someone outside the organization. The DLP policy recognizes the label and the action is immediate: block, optionally with a business justification override, or block without that option. Every attempt is logged in Activity Explorer, so you can see exactly who tried what and whether the policy intervened.

Image 1: Microsoft Purview DLP rule with a Confidential sensitivity label condition and a block action set to restrict access for people outside the organization

The strength of this approach is that it is preventive, and it applies across the locations Purview has visibility into: endpoints, email, Teams chats, SharePoint/OneDrive, and even prompts sent to Microsoft 365 Copilot and external generative AI tools.

Microsoft Defender for Cloud Apps: Revoking Access on Already-Shared Files

Where Purview DLP is about preventing an action, Defender for Cloud Apps is about correcting a situation that already exists. Think of a document that was shared externally before a label was ever applied, or a file that ended up in a cloud app outside your visibility through a route DLP never inspected.

With a file policy in Defender for Cloud Apps, you can continuously scan for files matching specific conditions, for example an access level of External or Public combined with a sensitivity label or a sensitive information type detected through the Data Classification Service. Once a file matches those conditions, automated governance actions can follow, including:

  • Remove external users: removes all collaborators outside the internal domains configured in your settings
  • Remove public access / remove direct shared link: revokes a shared link or restricts access to named collaborators
  • Make private: removes all shares, leaving access to site administrators only
  • Remove a collaborator: revokes access for one specific person without affecting the rest
Image 2: Defender for Cloud Apps file policy filtering on External or Public access level and a Confidential sensitivity label, with the Remove external users governance action enabled

This works across connected apps such as SharePoint, OneDrive, Google Workspace, and Box, which makes it particularly valuable as a backstop for content that was already shared before it was classified, or for gaps that fall outside Purview DLP’s preventive reach.

Why You Need Both

Microsoft Purview DLP intervenes before or during the action (preventive), triggered by classification detected during an activity, typically blocking sharing, copying, pasting, or uploading, across endpoints, email, Teams, SharePoint/OneDrive, Copilot, and browsers.

Microsoft Defender for Cloud Apps intervenes after the action, on data at rest (corrective), triggered by a continuous scan of files against conditions such as access level and label, typically revoking permissions, undoing sharing, or quarantining/making files private, across connected cloud apps such as SharePoint, OneDrive, Google Workspace, and Box.

This is where the combination earns its value. Purview DLP prevents a large share of risky actions from happening at all. But no preventive layer is airtight: files shared before a label was applied, or content that leaked out through an unmanaged path, will slip through. Defender for Cloud Apps acts as the safety net, continuously scanning what is already out there and revoking access the moment it should not have been granted.

Conclusion

Data protection is not a single control, it is a layered model:

  1. Classify first: sensitivity labels and sensitive information types are the foundation both solutions depend on. Neither Purview DLP nor Defender for Cloud Apps has anything to act on without classification.
  2. Microsoft Purview DLP: prevents risky actions on sensitive content at the moment they happen, across endpoints, email, Teams, and browsers.
  3. Microsoft Defender for Cloud Apps: continuously scans already-shared content in connected cloud apps and revokes access when it violates policy.

Prevent where you can, correct where you must. Together, these two layers close the gap that either one would leave open on its own.

Blocking Generative AI with Microsoft Defender for Cloud Apps and Microsoft Defender for Endpoint

Blocking Generative AI with Microsoft Defender for Cloud Apps and Microsoft Defender for Endpoint

Employees are using generative AI tools every day, often without IT or security teams knowing about it. Tools like ChatGPT, Gemini, Deepseek, and dozens of others are freely accessible from any browser on any managed device. While these tools can be productive, they also represent a significant data governance risk. Sensitive information can leave the organization the moment it is pasted into a prompt.

Blocking generative AI is not about being anti-innovation. It is about making a deliberate, governed choice about which tools are trusted, how they handle your data, and what controls exist when they are used. In this blog post, I will walk through a layered approach to governing generative AI in your organization using Microsoft Defender for Cloud Apps, Microsoft Defender for Endpoint, and Microsoft Purview.

Table of Contents

  1. Policy: The Foundation of AI Governance
  2. Blocking Generative AI with Defender for Cloud Apps and Defender for Endpoint
    1. Step 1: Sanction Allowed Applications
    2. Step 2: Create a Block Policy for the Generative AI Category
    3. Step 3: Validate Enforcement via Defender for Endpoint
  3. Data Protection with Microsoft Purview
    1. Sensitivity Labels
    2. Endpoint DLP Policy
  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.

Policy: The Foundation of AI Governance

Policy comes before technical controls. Policy determines what is and what is not permitted within an organization, and is the foundation for staying in control of company data. Without a policy, any technical control you implement lacks a foundation. You cannot enforce a rule you have not defined.

Examples of questions that an AI usage policy should address:

  • Which generative AI tools are sanctioned for use by the organization?
  • Are there restrictions on what data can be used in those tools?
  • What happens when an employee uses an unsanctioned tool?

For the purpose of this blog post, I will use the following example policy:

ToolStatusRationale
Microsoft 365 Copilot✅ AllowedIntegrated with the Microsoft 365 data boundary, governed by tenant controls
Claude (Anthropic)✅ AllowedApproved for specific use cases via organizational account
All other generative AI tools❌ BlockedUnsanctioned, unmanaged, and outside the organization’s data governance framework

This distinction is important. Microsoft Copilot operates within your Microsoft 365 tenant and is subject to the same compliance and data residency controls as the rest of your Microsoft 365 environment. Claude, when accessed via an approved organizational account, can be governed and audited. All other generative AI tools, unless explicitly evaluated and approved, operate outside of your organization’s governance and data protection framework.

Documenting this in a policy gives you the basis to enforce controls technically and to communicate expectations clearly to your employees.

Blocking Generative AI with Microsoft Defender for Cloud Apps and Microsoft Defender for Endpoint

With a policy in place, the next step is enforcement. Microsoft Defender for Cloud Apps (MDA) allows you to discover, classify, and govern cloud application usage across your organization. One of the built-in application categories in MDA is Generative AI, which automatically groups over 1200 known generative AI services like ChatGPT, Gemini, Deepseek, and many others, a list that keeps growing.

The enforcement mechanism on managed endpoints is provided by Microsoft Defender for Endpoint (MDE). When MDE is deployed on a device, it enforces blocking via Network Protection, which operates at the network level. This means that access to unsanctioned generative AI tools is blocked regardless of how the request is made, whether through a browser, PowerShell, or any other HTTP client, without requiring an additional proxy or agent. This integration is one of the reasons this approach is practical for most organizations that are already using Microsoft Defender for Endpoint.

Step 1: Sanction Allowed Applications

Before creating a block policy, mark the applications that are explicitly allowed as Sanctioned in the Microsoft Defender for Cloud Apps app catalog. This ensures they are excluded from any block policy you create.

Location: Microsoft Defender Portal > Cloud Apps > Cloud app catalog

Search for Microsoft Copilot and Claude and set their tag to Sanctioned.

Image 1: The Cloud App Catalog in Microsoft Defender for Cloud Apps, filtered on the Generative AI category showing Sanctioned apps including Microsoft Copilot and Anthropic Claude.

Step 2: Create a Block Policy for the Generative AI Category

Navigate to the Cloud Apps policies section and create a new App discovery policy.

Location: Microsoft Defender Portal > Cloud Apps > Policies > Policy Management > Create Policy > App discovery policy

Configure the policy as follows:

  • Policy name: Block Unsanctioned Generative AI
  • Category filter: Generative AI
  • Action: Tag app as Unsanctioned

This policy targets the entire Generative AI category while excluding the applications you have explicitly sanctioned in the previous step.

Image 2: Creating an App Discovery Policy in Microsoft Defender for Cloud Apps targeting the Generative AI category with the governance action to tag apps as Unsanctioned.

Step 3: Validate Enforcement via Microsoft Defender for Endpoint

Once an app is tagged as Unsanctioned, Microsoft Defender for Endpoint enforces the block via Network Protection on managed devices. When a user attempts to access a blocked generative AI service, the connection is blocked at the network level and the user sees a notification that the site is blocked by their organization.

Image 3: Microsoft Defender for Endpoint blocking access to deepseek.com

You can review blocked access attempts in the Microsoft Defender for Cloud Apps activity log and in the Microsoft Defender for Endpoint device timeline, giving you full visibility into which users attempted to access which tools and when.

Data Protection with Microsoft Purview

Blocking unsanctioned tools addresses the governance problem at the application level. But what about data being used in the tools that are allowed? Even within sanctioned tools, not all data should be treated equally.

Consider the following scenario: a user has a document classified as Confidential containing financial projections or personal data. Within Microsoft Copilot, this is acceptable because Copilot operates inside your Microsoft 365 tenant boundary. The data does not leave your environment. However, if that same user copies the content and pastes it into Claude, the data is now being sent to an external third-party service, even if Claude is an approved tool.

Microsoft Purview allows you to create controls that distinguish between these scenarios at the data level.

Sensitivity Labels

Microsoft Purview Information Protection uses sensitivity labels to classify content. Labels can be applied manually by users or automatically based on content inspection. Common examples include:

  • Public: No restrictions
  • Internal: For internal use only
  • Confidential: Sensitive data, restricted sharing
  • Highly Confidential: Strictly limited access

When a document or piece of content carries a sensitivity label, that label travels with the content and can be used to enforce policy wherever the content goes.

Note: This assumes sensitivity labels are already configured and published in your organization.

Endpoint DLP Policy

Microsoft Purview Data Loss Prevention (DLP) allows you to create policies that detect when labeled content is being handled in a way that violates your policy, such as being pasted into a browser-based application.

Location: Microsoft Purview Portal > Solutions > Data loss prevention > Policies > Create policy > Enterprise applications & devices

For the scenario described above, you create a custom Endpoint DLP policy with the following logic:

  • Condition: Content contains a sensitivity label of Confidential or Highly Confidential
  • Action: Audit or restrict activities on devices
    • Enable Upload to a restricted cloud service domain or access from an unallowed browsers > Block
    • Click Choose different restrictions for sensitive service domains > add Claude AI domain group > Block
    • Copilot is not added to the sensitive service domain group and is therefore not restricted

This means a user can work with Confidential content in Microsoft Copilot without restriction, but will be blocked from pasting that same content into Claude.

Image 4: Microsoft Copilot successfully reading the Mario_Internal_Secrets document and responding to the question “How do I warp to world 8?”, demonstrating that Confidential content is accessible within the Microsoft 365 boundary.
Image 5: Microsoft Purview blocking the upload of the Mario_Internal_Secrets document to Claude, “Your organization prevents you from uploading the file to this location. To protect the sensitive info in this file, your organization prevents you from uploading it to unapproved locations.”

The DLP policy generates an alert in the Microsoft Purview compliance portal and can be configured to notify the user, notify an administrator, or require the user to provide a business justification before overriding the block, depending on your organization’s risk tolerance.

This creates a data-aware enforcement layer on top of the application-level controls you configured in Microsoft Defender for Cloud Apps. Even for approved tools, sensitive data is protected.

Conclusion

Generative AI is not going away. Employees will continue to look for ways to use these tools, and many of those tools are genuinely useful. The goal is not to block everything, but to make deliberate choices about which tools are trusted, enforce those choices technically, and add a data protection layer to ensure sensitive information does not end up where it should not be.

The approach described in this blog post follows a three-layer model:

  1. Policy: Define which tools are allowed and under what conditions
  2. Microsoft Defender for Cloud Apps + Microsoft Defender for Endpoint: Tag unsanctioned generative AI tools in the Microsoft Defender for Cloud Apps catalog. Microsoft Defender for Endpoint enforces the block via Network Protection.
  3. Microsoft Purview DLP: Enforce data-level controls so that sensitive content cannot be used in external tools, even when those tools are technically allowed.

Each layer addresses a different risk. Together, they give you a practical and enforceable governance framework for generative AI that does not require you to choose between productivity and security.

Start with policy. Enforce at the app level. Protect at the data level.

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.