Developments in Digital
Developments in Digital

Retrieving Azure service principal role assignments

When cleaning up unused service principals within Azure, it's useful to be able to determine how they are currently used.

In order to retrieve role assignments of the service principal associated with an app registration, we need to perform the following:

  • Use the Microsoft Azure Active Directory Graph API to retrieve a service principal id from an app registration id
  • Use the Azure REST API to retrieve the subscription role assignments for the service principal id

Firstly, to retreive a service principal id from an app registration id, you can use client credentials to retrieve an access token that can access the Graph API. You can then use the following cmdlet to return service principal details for the specified application id:

function Get-ServicePrincipal {
    param(
        [Parameter(Mandatory = $true)][string] $AccessToken,
        [Parameter(Mandatory = $true)][string] $ApplicationId
    )

    $uri = "https://graph.microsoft.com/beta/servicePrincipals"
    $uri += "?`$filter=appId eq '$ApplicationId'"

    $headers = @{
        'Content-Type'  = 'application/json'
        'Authorization' = 'Bearer ' + $accessToken
    }

    $response = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers
    $servicePrincipal = $response.value    
    
    return @{
        Id = $servicePrincipal.id;
        AppId = $servicePrincipal.appId;
        AppDisplayName = $servicePrincipal.appDisplayName;
    }    
}

Once you have the service principal identifier, you can use the following cmdlet to retrieve a collection of all role assignments for that service principal in the specified subscription id:

function Get-ServicePrincipalRoleAssignment {
    param(
        [Parameter(Mandatory = $true)][string] $AccessToken,
        [Parameter(Mandatory = $true)][string] $SubscriptionId,
        [Parameter(Mandatory = $true)][string] $ServicePrincipalId
    )
    
    $uri = "https://management.azure.com/subscriptions/$($SubscriptionId)/providers/Microsoft.Authorization/roleAssignments"
    $uri += '?$filter='
    $uri += "$([System.Web.HttpUtility]::UrlEncode("principalId eq '$ServicePrincipalId'"))"
    $uri += "&api-version=2015-07-01"

    $headers = @{
        'Content-Type'  = 'application/json'
        'Authorization' = 'Bearer ' + $accessToken
    }

    $response = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers

    $assignments = @()

    foreach ($assignment in $response.value) {
        $assignments += @{
            Id = $assignment.Id
        }
    }

    return $assignments
}