> For the complete documentation index, see [llms.txt](https://docs.forestall.io/fsprotect/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.forestall.io/fsprotect/edges/azure/az_owner.md).

# AZ\_OWNER

## Summary

|                               |                                                                                                 |
| ----------------------------- | ----------------------------------------------------------------------------------------------- |
| **FSProtect ACL Alias**       | AZ\_OWNER                                                                                       |
| **Entra ID (Azure AD) Alias** | Owner                                                                                           |
| **Affected Object Types**     | Groups, Applications, Service Principals, Devices                                               |
| **Exploitation Certainty**    | Certain                                                                                         |
| **Graph Permission / Role**   | Object-level owner assignment via Group Owners, Application Owners, or Service Principal Owners |

## Description

`AZ_OWNER` represents the ownership relationship in Microsoft Entra ID (Azure AD) where a principal (user or service principal) has been designated as an **Owner** of an object. Ownership in Entra ID grants significant privileges depending on the object type:

* **Group Owner**: Can add/remove members, modify group properties, and manage group settings. For role-assignable groups, this allows privilege escalation by adding members who inherit directory roles.
* **Application Owner**: Can modify application configurations, add credentials (secrets/certificates), change redirect URIs, and manage API permissions. This can lead to credential theft and unauthorized access.
* **Service Principal Owner**: Can modify the service principal configuration, add credentials, and change authentication settings. Compromising this can allow impersonation of the application.
* **Device Owner**: Can manage device properties and settings.

Ownership is a critical control point that attackers target for privilege escalation and persistence.

## Identification

### PowerShell

#### Comprehensive Owner Enumeration

```powershell
Import-Module Microsoft.Graph.Groups
Import-Module Microsoft.Graph.Applications
Import-Module Microsoft.Graph.Identity.DirectoryManagement

Connect-MgGraph -Scopes "Group.Read.All", "Application.Read.All", "Device.Read.All"

function Get-AllAzureOwnership {
    $allOwnership = [System.Collections.Generic.List[PSCustomObject]]::new()
    
    # Groups - use ExpandProperty to get owners in single call per group batch
    Write-Host "Fetching groups with owners..."
    $groups = Get-MgGroup -All -ExpandProperty "owners"
    foreach ($g in $groups) {
        foreach ($o in $g.Owners) {
            $odataType = $o.AdditionalProperties['@odata.type']
            $ownerType = if ($odataType) { ($odataType -replace '^#microsoft\.graph\.', '') } else { 'Unknown' }
            $allOwnership.Add([PSCustomObject]@{
                TargetType  = "Group"
                TargetName  = $g.DisplayName
                TargetId    = $g.Id
                OwnerName   = $o.AdditionalProperties.displayName
                OwnerType   = $ownerType
                OwnerId     = $o.Id
            })
        }
    }
    Write-Host "Found $($groups.Count) groups"
    
    # Applications - use ExpandProperty to get owners in single call per app batch
    Write-Host "Fetching applications with owners..."
    $apps = Get-MgApplication -All -ExpandProperty "owners"
    foreach ($a in $apps) {
        foreach ($o in $a.Owners) {
            $odataType = $o.AdditionalProperties['@odata.type']
            $ownerType = if ($odataType) { ($odataType -replace '^#microsoft\.graph\.', '') } else { 'Unknown' }
            $allOwnership.Add([PSCustomObject]@{
                TargetType  = "Application"
                TargetName  = $a.DisplayName
                TargetId    = $a.Id
                OwnerName   = $o.AdditionalProperties.displayName
                OwnerType   = $ownerType
                OwnerId     = $o.Id
            })
        }
    }
    Write-Host "Found $($apps.Count) applications"
    
    # Service Principals - use ExpandProperty to get owners in single call per SP batch
    Write-Host "Fetching service principals with owners..."
    $sps = Get-MgServicePrincipal -All -ExpandProperty "owners"
    foreach ($s in $sps) {
        foreach ($o in $s.Owners) {
            $odataType = $o.AdditionalProperties['@odata.type']
            $ownerType = if ($odataType) { ($odataType -replace '^#microsoft\.graph\.', '') } else { 'Unknown' }
            $allOwnership.Add([PSCustomObject]@{
                TargetType  = "ServicePrincipal"
                TargetName  = $s.DisplayName
                TargetId    = $s.Id
                OwnerName   = $o.AdditionalProperties.displayName
                OwnerType   = $ownerType
                OwnerId     = $o.Id
            })
        }
    }
    Write-Host "Found $($sps.Count) service principals"
    
    # Devices - use ExpandProperty for registered owners
    Write-Host "Fetching devices with owners..."
    $devices = Get-MgDevice -All -ExpandProperty "registeredOwners"
    foreach ($d in $devices) {
        foreach ($o in $d.RegisteredOwners) {
            $odataType = $o.AdditionalProperties['@odata.type']
            $ownerType = if ($odataType) { ($odataType -replace '^#microsoft\.graph\.', '') } else { 'Unknown' }
            $allOwnership.Add([PSCustomObject]@{
                TargetType  = "Device"
                TargetName  = $d.DisplayName
                TargetId    = $d.Id
                OwnerName   = $o.AdditionalProperties.displayName
                OwnerType   = $ownerType
                OwnerId     = $o.Id
            })
        }
    }
    Write-Host "Found $($devices.Count) devices"
    
    $allOwnership
}

$ownership = Get-AllAzureOwnership
$ownership | Export-Csv -Path ".\AllAzureOwnership.csv" -NoTypeInformation -Encoding UTF8
Write-Host "Total ownership relationships: $($ownership.Count)"
$ownership | Sort-Object TargetType, TargetName | Format-Table -AutoSize
```

### Azure CLI

```bash
# List owners of a group
az ad group owner list --group "<GroupObjectIdOrName>" --query "[].{displayName:displayName,id:id}"

# List owners of an application
az ad app owner list --id "<AppObjectIdOrAppId>" --query "[].{displayName:displayName,id:id}"

# List owners of a service principal
az ad sp owner list --id "<SPObjectIdOrAppId>" --query "[].{displayName:displayName,id:id}"

# List registered owners of a device (using Graph API)
az rest --method GET --url "https://graph.microsoft.com/v1.0/devices/<DeviceObjectId>/registeredOwners" --query "value[].{displayName:displayName,id:id}"
```

![Azure CLI](/files/owWPHPeR1m5xCengl4v8)

### Azure GUI

#### Group Owners

* Open **Microsoft Entra admin center** -> **Groups** -> select the **target group**.
* Go to **Owners** in the left menu.

  ![Group Owners UI](/files/iPVUMb5Kkllryo2UA3rB)

#### Application Owners

* Open **Microsoft Entra admin center** -> **Applications** -> **App registrations** -> select the **target app**.
* Go to **Owners** in the left menu.

  ![Application Owners UI](/files/4inHyO6Lcb2bNtUipkha)

#### Service Principal Owners

* Open **Microsoft Entra admin center** -> **Applications** -> **Enterprise applications** -> select the **target app**.
* Go to **Owners** in the left menu.

  ![Service Principal Owners UI](/files/BwrBbUE16uEt9XoyzcRY)

#### Device Owners

* Open **Microsoft Entra admin center** -> **Devices** -> **All devices** -> select the **target device**.
* Go to **Registered owners** in the device details.

## Exploitation

> **Related Attack Paths:**
>
> * [AZ\_ADD\_OWNER](https://docs.forestall.io/fsprotect/edges/azure/az_add_owner) - Grants the ability to add owners to objects, which can then be exploited via this edge.
> * [AZ\_ADD\_SECRET](https://docs.forestall.io/fsprotect/edges/azure/az_add_secret) - Application/SP owners can add secrets to impersonate the application.
> * [AZ\_ADD\_MEMBERS](https://docs.forestall.io/fsprotect/edges/azure/az_add_members) - Group owners can add members to groups.
> * [AZ\_MG\_APPLICATION\_READWRITE\_ALL](https://docs.forestall.io/fsprotect/edges/azure/az_mg_application_readwrite_all) - Applications with this permission can modify any app, similar to ownership.
> * [AZ\_MG\_APPROLEASSIGNMENT\_READWRITE\_ALL](https://docs.forestall.io/fsprotect/edges/azure/az_mg_approleassignment_readwrite_all) - After compromising an app via ownership, grant it dangerous permissions.
> * [AZ\_MG\_ROLEMANAGEMENT\_READWRITE\_DIRECTORY](https://docs.forestall.io/fsprotect/edges/azure/az_mg_rolemanagement_readwrite_directory) - Escalate to Global Admin after gaining control of an application.

Ownership exploitation depends on the object type:

| Owner Type                  | Exploitation Method                         | See Edge                                                                           |
| --------------------------- | ------------------------------------------- | ---------------------------------------------------------------------------------- |
| **Group Owner**             | Add members to gain group privileges        | [AZ\_ADD\_MEMBERS](https://docs.forestall.io/fsprotect/edges/azure/az_add_members) |
| **Application Owner**       | Add credentials to impersonate app          | [AZ\_ADD\_SECRET](https://docs.forestall.io/fsprotect/edges/azure/az_add_secret)   |
| **Service Principal Owner** | Add credentials to impersonate SP           | [AZ\_ADD\_SECRET](https://docs.forestall.io/fsprotect/edges/azure/az_add_secret)   |
| **Device Owner**            | Limited - modify properties, disable device | N/A                                                                                |

## Mitigation

* **Minimize the number of owners** for sensitive objects (groups, applications, service principals).
  * Go to **Microsoft Entra ID** -> **Groups** / **App registrations** / **Enterprise applications**.
  * Select the object -> **Owners** -> remove unnecessary owners.
* **Use Privileged Identity Management (PIM)** for just-in-time owner access to sensitive objects.
* **Monitor owner assignments** and alert on unexpected changes.
* **Avoid assigning ownership to regular users** for applications that have sensitive permissions.
* **Implement Access Reviews** for application and group owners:
  * Go to **Identity Governance** -> **Access Reviews** -> **New access review**.
  * Select the target and configure owner reviews.

## Detection

Detect ownership changes in **Audit logs**.

* Go to **Microsoft Entra ID** -> **Audit logs**.
* Filter by activities:
  * **Add owner to group**
  * **Remove owner from group**
  * **Add owner to application**
  * **Remove owner from application**
  * **Add owner to service principal**
  * **Remove owner from service principal**

![Audit logs](/files/TCxY53Op89LsH24aL5kp)

Monitor for suspicious patterns:

* Owner additions to role-assignable groups.
* Owner additions to applications with privileged API permissions.
* Credential additions to applications shortly after owner assignment.
* Ownership changes outside of change management windows.

## References

* <https://learn.microsoft.com/en-us/entra/identity/role-based-access-control/groups-concept>
* <https://learn.microsoft.com/en-us/powershell/module/az.resources/get-azadgroupowner>
* <https://learn.microsoft.com/en-us/powershell/module/az.resources/get-azadapplication>
* <https://learn.microsoft.com/en-us/powershell/module/az.resources/get-azadserviceprincipal>
* <https://learn.microsoft.com/en-us/powershell/module/az.resources/new-azadappcredential>
* <https://learn.microsoft.com/en-us/powershell/module/az.resources/add-azadgroupmember>
* <https://learn.microsoft.com/en-us/cli/azure/ad/group/owner>
* <https://learn.microsoft.com/en-us/cli/azure/ad/app/owner>
