Search code examples
azureazure-devopsazure-active-directoryazure-cli

azure cli to add scope to app registration


I have a powershell script that runs az cli to add a scope to an existing app registration.

param (
    [Parameter(Mandatory = $true)]
    [string]$serviceAppRegAppId
)

$uuid = [guid]::NewGuid()
$api = @{
    acceptMappedClaims = $null
    knownClientApplications = @()
    oauth2PermissionScopes = @(
        @{
            adminConsentDescription = "admin description"
            adminConsentDisplayName = "admin name"
            isEnabled = $true
            id = "$uuid"
            type = "User"
            userConsentDescription = "user description"
            userConsentDisplayName = "user name"
            value = "amx.read"
        }
    )
    preAuthorizedApplications = @()
    requestedAccessTokenVersion = "2"
} | ConvertTo-Json

write-host "api=$api"

$appRegName = az ad app show --id $serviceAppRegAppId --query displayName
$appRegNameWithoutQuotes = $appRegName.Trim('"')

write-host "Going to add scope to app reg:$appRegNameWithoutQuotes"

# Update app registration with App ID URL and api object
az ad app update `
    --id $serviceAppRegAppId `
    --identifier-uris "api://$appRegNameWithoutQuotes" `
    --set api="$api"

If I run this directly from VS Code it works fine. However, when run from an Azure DevOps pipeline and AzurePowerShell@5 task, I get the following error:

Going to add scope to app reg:apreg-gis-maps-prod-001

ERROR: Property api in payload has a value that does not match schema

Can anyone see which property of the api object it could be complaining about? Also why would this work from vs code terminal but not from Azure DevOps?

Following Jesse's advice, I ran az ad app show which gave:

{
   "api":{
      "acceptMappedClaims":null,
      "knownClientApplications":[
         
      ],
      "oauth2PermissionScopes":[
         {
            "adminConsentDescription":"Read amx data",
            "adminConsentDisplayName":"Read amx data",
            "id":"ff9d6262-eb63-4c94-bdfa-0a33372c87bc",
            "isEnabled":true,
            "type":"Admin",
            "userConsentDescription":"Read amx data",
            "userConsentDisplayName":"Read amx data",
            "value":"amx.read"
         }
      ],
      "preAuthorizedApplications":[
         
      ],
      "requestedAccessTokenVersion":2
   }
}

I saved this to a file named from-azure.json, then ran the following:

$json = Get-Content -Raw -Path "from-azure.json"
$apiConfig = $json | ConvertFrom-Json

# Expand the knownClientApplications property
$apiConfig.api.knownClientApplications = $apiConfig.api.knownClientApplications | Select-Object -ExpandProperty value
$apiConfig.api.oauth2PermissionScopes = $apiConfig.api.oauth2PermissionScopes | Select-Object -ExpandProperty value
$apiConfig.api.preAuthorizedApplications = $apiConfig.api.preAuthorizedApplications | Select-Object -ExpandProperty value

# Output the custom PowerShell object
$apiConfig

The output was as follows:

@{acceptMappedClaims=; knownClientApplications=; oauth2PermissionScopes=amx.read; preAuthorizedApplications=; requestedAccessTokenVersion=2}

This seems incomplete?


Solution

  • My problem was a lack of understanding of how the az command works against Azure. It submits a http Patch request to the Azure api that presents the collection of oauth2PermissionScopes. If any of these scopes currently exist in an active state, they must first be disabled or an error will be raised.