Provisioning App Registrations in Entra ID with Azure CLI

Florian CAILLAUD
Published by Florian CAILLAUD
Category : Azure / DevOps / Entra Id Non classé
22/01/2025

Introduction

 

To secure an application or an API, it is often necessary to define roles that client applications must have permissions for.

In Entra ID, this involves:

  • A Server App Registration representing the application or API, with a scope and roles.
  • A Client App Registration representing the consumer, with a ClientID, ClientSecret, and permissions on the Server App Registration roles.

Setting up these elements can become time-consuming depending on the number of applications/APIs or clients. This article demonstrates how to address this issue by automating the creation of these components using Azure CLI.

 

Creating the Server App Registration

 

Here, we first check if the Server App Registration already exists; if not, we create it and retrieve its application ID (aka client ID).

 

$appServerName = "AppRegServer" 
$appServerURI = "api://myapp.or.myapi" 

$appServerId = az ad app list --display-name "$appServerName" --query [].appId --output tsv --only-show-errors 

if (!$appServerId) { 
    $appServerId = az ad app create --display-name $appServerName --identifier-uris $appServerURI --homepage $appServerURI --query 'appId' --output tsv --only-show-errors 

    Write-Host "The App Registration Server '$appServerName' was created (appId: $appServerId)" 
} 
else { 
    Write-Host "The App Registration Server '$appServerName' already exists (appId: $appServerId)" 
}

 

Creating Roles

 

Next, we check if the desired role already exists; if not, it is created within the Server App Registration.

 

$role = "reader" 
$roleId = (New-Guid).ToString() 

if (!(az ad app show --id $appServerId --query "appRoles[?value=='$role']" -o tsv --only-show-errors)) 
{ 
    $appRoles = "[{`"value`": `"$role`",`"displayName`": `"$role`",`"description`": `"myDesc`",`"id`": `"$roleId`",`"allowedMemberTypes`": [`"Application`"]}]" 
    az ad app update --id $appServerId --app-roles $appRoles --only-show-errors 
    Write-Host "The role '$role' was created" 
} 
else{ 
    Write-Host "The role '$role' already exists" 
}

 

Creating the Client App Registration

 

Next, the Client App Registration is created if it does not already exist:

 

$appClientName = "AppRegClient" 

$appClient = az ad app list --display-name $appClientName --output json --only-show-errors | ConvertFrom-Json 
if ($appClient.Count -eq 0) 
{ 
    $appClient = az ad app create --display-name $appClientName --output json --only-show-errors | ConvertFrom-Json 
    Write-Host "The App Registration Client '$appClientName' was created (appId: $($appClient.appId))" 
} 
else { 
    Write-Host "The App Registration Client '$appClientName' already exists (appId: $($appClient.appId))" 
}

 

Creating and Saving the Secret

 

To use the Client App Registration, a valid client secret is required:

 

$keyVaultName = "myKeyVault" 
$startDate = Get-Date 
$endDate = $startDate.AddYears(1).ToString("yyyy-MM-ddTHH:mm:ssZ") 

$appSecret = az ad app credential reset --id $appClient.objectId --append --end-date $endDate --query password --output tsv --only-show-errors 
$kvSecret = az keyvault secret set --vault-name $keyVaultName --name "${appClientName}-clientSecret" --value $appSecret --expires $endDate --only-show-errors | ConvertFrom-Json 

Write-Host "Secret create (or update) for the Client App Registration (key vault : $KeyVaultName, secret name: $($kvSecret.name))"

 

Here, the secret is stored in an Azure Key Vault for safekeeping or for client access, though this step is optional.

 

Adding/Granting Permissions

 

Finally, the Client App Registration is granted permissions on the Server App Registration role:

 

az ad app permission add --id $appClient.appId --api $appServerId --api-permissions "$roleId=Role" --only-show-errors
Write-Host "Permission '$role' added to the App Registration Client"

 

Adding the permission alone is insufficient; an Entra ID admin must grant the permission to make it effective.

 

AppRegPermissionNotGranted

 

If you already have the necessary rights, you can simply run the following command:

 

az ad app permission grant --id $appClient.appId --api $appServerId --only-show-errors

 

Conclusion

 

By aggregating these Azure CLI commands with slight customization, you can provision App Registrations on the fly as needed. These commands can be executed during the deployment of an application or API, or as part of a workflow to onboard new clients. In many contexts, this can save a lot of manual configurations !