The Hidden Risks of Entra ID Application Ownership (Part 1)
November 20, 2025 •Glenn Van Rymenant
Assigning ownership to your application and service principal objects in Entra ID might seem like good governance, but it introduces significant security and privilege risks.
When assigned ownership, users can manage the credentials and modify high-impact settings on these objects – all without being assigned any administrator roles. These are privileged actions that pose significant risk, whether through intentional misuse or account compromise.
This article highlights the risks and explains why you should avoid assigning ownership to your application and service principal objects in Entra ID.
Risks of ownership on application objects
As a brief recap:
In Entra ID, an application usually consists of two related objects: the application object and the service principal object – ignoring multi-tenant and managed identity scenarios for simplicity.
The application object acts as a blueprint that specifies the application’s configuration, capabilities, and behavior. The service principal object is the representation of that blueprint within a specific tenant – the identity of the application used for most interactions.
When you assign someone as an owner of an Entra ID application object, you give them control over key parts of the app’s configuration, including credentials, permissions, and authentication behavior.
Owners can:
- Manage client credentials (secrets or certificates)
- Manage redirect URIs
- Modify token or claims settings
Adding a client credential allows the owner to authenticate as the application itself using the client credentials grant flow. This means they can obtain access tokens including all the application permissions the application’s service principal is granted consent for in the tenant.
In other words, those permissions operate entirely under the application’s identity, without any interactive user sign-in. That design makes sense for legitimate service-to-service communication, but in the wrong hands, it can also enable privilege escalation or unauthorized access far beyond a user’s normal role.
For example, in the screenshot below, Megan – the marketing manager – is assigned ownership of a highly privileged Entra ID application object that has the Directory.ReadWrite.All application permission consented.

Figure1 : Application object ownership in the Entra admin portal.
Figure 2: A privileged application object with the Directory.ReadWrite.All Microsoft Graph API application permission consented.

Figure3 : Addition of a client secret to the application object in the Entra admin center.
With that ownership in place, Megan – or anyone who compromises her account – could add a new client credential, request an access token, and gain directory-wide access by leveraging that Directory.ReadWrite.All permission. Even though Megan isn’t a Global Administrator, she (and any attacker) effectively has the same level of control through the app’s permissions.
With Megan being a typical business user exposed to common attack vectors, her account is far easier to compromise than a dedicated administrator account – a risk that should not be underestimated.
So, should you simply avoid assigning ownership on application objects with high privilege application permissions consented? Unfortunately, it doesn’t stop there.
Even without high-privilege application permissions consented, assigning ownership on application objects still exposes multiple lateral movement paths as owners can also:
- Manage redirect URIs of the application, redirecting authentication responses – including authorization codes and tokens – to a malicious endpoint.
- Allow less secure authentication flows such as the Device Code flow or Resource Owner Password Credential (ROPC) grant.
- Modify token or claims settings in ways that expose information useful for reconnaissance or privilege escalation, such as group claims.
Each of these actions creates real opportunities for lateral movement, impersonation, and privilege escalation.
Risks of ownership on service principal objects
Ownership of service principal objects also introduces significant risk. Service principal object owners can:
- Disable the application for sign-in.
- Effectively blocking any user from authenticating to the application.
- Remove the assignment requirement.
- Allowing any user in the tenant to access the application (potentially).
- Modify the single sign-on configuration.
- Compromise authentication.
- Modify the provisioning (SCIM) configuration.
- Exposing sensitive data or misconfiguring how users and groups are provisioned.
- View the activity logs (sign-in, audit, ...).
- Providing valuable reconnaissance data.
A lesser-known risk is that service principal owners can also add client credentials directly to the service principal object – effectively the same as adding client credentials to the application object, with the crucial difference that these credentials aren’t visible in the Entra admin portal, making detection less likely.
To mitigate this risk, Microsoft introduced the App Instance Property Lock feature, which prevents modification of sensitive properties (see the screenshot below) on service principal objects and is enabled by default for all applications created after March 2024.
Unfortunately, this feature is managed on the application object and as you could have probably guessed, an application object owner can disable the feature for the application or unlock any of the properties.
This means assigning ownership to service principal objects can be just as risky as granting ownership to application objects. In both cases, a compromised owner account can be leveraged for privilege escalation or lateral movement.

Figure 4: App instance property lock configuration with property dropdown.
Does restricting access to the Entra admin center reduce the risk?
Unfortunately, not really. While blocking (read) access to the Entra admin center using the setting below prevents owners from performing these actions in the admin center, it does not prevent them from performing these actions through other interfaces such as PowerShell modules. Conversely, it also defeats the purpose of assigning ownership in the first place, since owners can no longer manage the objects through the admin center.
Previously, users could still manage application and service principal objects they owned in the Entra admin center (or Azure portal) if they had a direct link to the object. Microsoft has since tightened this behavior, fully blocking access, even when the direct URL is known.

Figure 5: User setting in Entra ID to restrict access to the Entra admin center for non-admin users (i.e.: users not assigned any administrator roles).
Even with the above Entra admin center restriction in place, owners can still interact with owned objects through other interfaces – which is one of the hidden risks of assigning ownership. Depending on the interface, access can sometimes be restricted by configuring the associated service principal (for example, by requiring assignment).
For instance:
|
Interface |
Service principal displayname |
AppId |
|
Microsoft Graph Explorer (aka.ms/ge) |
Graph Explorer |
de8bc8b5-d9f9-48b1-a8ad-b748da725064 |
|
Microsoft Graph PowerShell SDK |
Microsoft Graph Command Line Tools |
14d82eec-204b-4c2f-b7e8-296a70dab67e |
|
legacy AzureAD (Preview) PowerShell module |
Azure Active Directory PowerShell |
1b730954-1685-4b74-9bfd-dac224a7b894 |
|
Microsoft Graph |
Microsoft Graph |
00000003-0000-0000-c000-000000000000 |
Ideally, from a security perspective, you’d want to:
- Avoid assigning ownership to application and service principal objects.
- Restrict access to the Entra admin center for non-admin users.
- Restrict access to the other interfaces for non-admin users (and admins alike).
- Ensure App Instance Property Lock is enabled for all application objects under your control
Identifying application and service principal ownership with PowerShell
As you cannot directly filter on owned application and service principal objects in the Entra ID admin center, I provided some PowerShell code below that identifies owned application and service principal objects and exports it to a CSV. Alternatively, tools like ENow App Governance Accelerator can quickly identify objects with/without ownership.
# Connect to Microsoft Graph PowerShell
Connect-MgGraph -Scopes Application.Read.All -ContextScope Process
# Function to get all objects from a paged Microsoft Graph endpoint
# This is needed because Get-Mg* cmdlets do not return owners with all properties (only id)
function Get-MgGraphPaged {
param(
[Parameter(Mandatory = $true)][string]$Endpoint
)
$URI = "https://graph.microsoft.com/v1.0/$Endpoint"
$Accumulator = @()
do {
$Response = Invoke-MgGraphRequest -Method GET -Uri $URI -ContentType
'application/json'
if ($null -ne $Response.value) {
$Accumulator += $Response.value
}
else {
$Accumulator += $Response
}
$Next = $Response.'@odata.nextLink'
if (-not $Next) { $Next = $Response.'@odata.nextlink' }
$URI = $Next
} while ($URI)
return $Accumulator
}
# Get all service principal objects with their owners expanded
try {
$ServicePrincipalObjects = Get-MgGraphPaged -Endpoint
"servicePrincipals?`$expand=owners"
Write-Host "Successfully retrieved $($ServicePrincipalObjects.count) service principal objects and their owners"
}
catch {
Throw "Error retrieving service principal objects: $_"
}
# Get all application objects with their owners expanded
try {
$ApplicationObjects = Get-MgGraphPaged -Endpoint
"applications?`$expand=owners"
Write-Host "Successfully retrieved $($ApplicationObjects.count)
application objects and their owners"
}
catch {
Throw "Error retrieving application objects: $_"
}
# Define an array to hold the results
$Results = @()
# Combine both service principals and applications into a single collection for processing
$Combined = @(
$ServicePrincipalObjects |
Where-Object { $_.owners } |
ForEach-Object { [PSCustomObject]@{ Type = 'ServicePrincipal'; Object = $_ } }
$ApplicationObjects |
Where-Object { $_.owners } |
ForEach-Object { [PSCustomObject]@{ Type = 'Application'; Object = $_ } }
)
# Process each object to extract required properties and resolve owner display names
foreach ($Item in $Combined) {
$Object = $Item.Object
if (-not $script:OwnerCache) { $script:OwnerCache = @{} }
$Owners = (@($Object.owners) | ForEach-Object {
$Id = $_.id
$DisplayName = $_.displayName
if ([string]::IsNullOrEmpty($DisplayName)) {
if ($script:OwnerCache.ContainsKey($Id)) {
$DisplayName = $script:OwnerCache[$Id]
}
else {
try {
$Resp = Invoke-MgGraphRequest -Method GET -Uri
"https://graph.microsoft.com/v1.0/directoryObjects/$Id`?$select=displayName" -
ContentType 'application/json'
$DisplayName = $Resp.displayName
}
catch {
$DisplayName = $null
}
if ([string]::IsNullOrEmpty($DisplayName)) { $DisplayName
= $Id }
$script:OwnerCache[$Id] = $DisplayName
}
}
"$DisplayName ($Id)"
}) -join '; '
$Results += [PSCustomObject]@{
ObjectType = $Item.Type
AppId = $Object.appId
ObjectId = $Object.id
DisplayName = $Object.displayName
Owners = $Owners
}
}
# Export results to CSV
$Results | Export-Csv -Path ".\ApplicationOwners_ServicePrincipalOwners.csv" -
NoTypeInformation -Encoding UTF8
Write-Host "Exported $($Results.count) entries to
ApplicationOwners_ServicePrincipalOwners.csv"
What’s next?
In Part 2, we’ll explore safer alternatives to assigning ownership on application and service principal objects in Entra ID. We’ll also look at common scenarios where ownership is assigned today, such as managing credential expiry, and provide practical guidance on how to handle these cases securely.
Bookmark this article or subscribe to the AppGov Score blog to be notified when it’s published.
Stay tuned!
Written by Glenn Van Rymenant
Glenn Van Rymenant is an independent Microsoft 365 consultant and identity security specialist with hands-on experience designing, implementing, and managing secure and compliant Microsoft environments. He focuses on identity and access management and PowerShell automation, with strong expertise across the broader Microsoft 365 platform.