how to pass correct scope to app registration to query azure management service

ja 26 Reputation points
2022-12-20T15:43:40.083+00:00

HI Team.
I am trying a simple thing but not able to figure out how to set the correct scopes for a service principal.
I want to start and stop a ML compute using rest API. In order to do so, I would need the right token.

below are the steps I have taken :

  • create a service principal
  • created a Oauth query to get the access token

but I get error that

 {  
    "error": {  
        "code": "InvalidAuthenticationTokenAudience",  
        "message": "The access token has been obtained for wrong audience or resource 'api://{<!-- -->{id}}'. It should exactly match with one of the allowed audiences 'https://management.core.windows.net/','https://management.core.windows.net','https://management.azure.com/','https://management.azure.com'."  
    }  
}  

Now, I am not able to figure out this concept. I have 2 doubts :

  1. how to set this scope at the service principal end (in the portal), I dont see any such option and also I am not able to find the documentation.
  2. how this access works? even if I give some resource level owner access to a service principal, then do I still have to provide access at scope option of app registration?

Please help in coming out of this issue.

Azure Role-based access control
Azure Role-based access control
An Azure service that provides fine-grained access management for Azure resources, enabling you to grant users only the rights they need to perform their jobs.
972 questions
Microsoft Security | Microsoft Entra | Microsoft Entra ID
Microsoft Security | Microsoft Identity Manager
{count} votes

Accepted answer
  1. Alistair Ross 7,466 Reputation points Microsoft Employee
    2022-12-20T17:37:50.977+00:00

    Hello @hj-0155

    There is a lot of documentation regarding credential flow, which can be overwhelming.

    1. Starting here for the REST API overview: https://learn.microsoft.com/en-us/rest/api/azure/
    2. This page for the credential flow https://learn.microsoft.com/en-us/azure/active-directory/develop/permissions-consent-overview#the-default-scope
    3. Finally here for understanding the scopes (delegated permissions) https://learn.microsoft.com/en-us/azure/active-directory/develop/permissions-consent-overview

    Let me try simplify it for you. (I'm using PowerShell for my example, but not using the native cmdlets)

    1. Create your service principal, create a secret for it and assign the relevant permissions to it, in this case at least AzureML Compute Operator
    2. Identify the REST APIs you wish to call. In this case 3. Azure Machine Learning Compute Start 4. Azure Machine Learning Compute Stop
    3. You can see for both of these API calls (as well as all Azure Resource Manager API's) start with "https://management.azure.com". This is the scope for Public Azure (This differs for environments such as Azure Government and China)
    4. Set the constants. For the purpose of this script, it only has one compute I am referencing.

    Constants - Change these to reflect your environment.

    \# Secrets shouldn't be stored in code, but called from a key vault using a managed identity  
    
    $AppRegistrationClientId = "00000000-0000-0000-0000-000000000000" # Change this to your client Id  
    $AppRegistrationTenantId = "00000000-0000-0000-0000-000000000000" # Change this to your client tenant Id  
    $AppRegistrationSecret = "00000000000000000000000000000" # Ideally get this from a key vault instead.  
    
    $ComputeResourceId = "subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/RGName/providers/Microsoft.MachineLearningServices/workspaces/MLWorkspaceName/computes/ComputeName/"  # Change this your Compute. You will most likely build this using another api call  
    
    $Scope = "https://management.azure.com/" # Leave this as is for this script  
    

    8. Get the token and build the header

    # Authentication Token  
    
        $Uri = "https://login.microsoftonline.com/$AppRegistrationTenantId/oauth2/token?api-version=2020-06-01";  
        $Body = @{   
            grant_type    = 'client_credentials';   
            resource      = $Scope;   
            client_id     = $AppRegistrationClientId;   
            client_secret = $AppRegistrationSecret  
        }  
    
    $AuthenticationResponse = Invoke-RestMethod -Method Post -Uri $Uri -Body $Body  
    
    $Headers = @{  
        authorization = "$($AuthenticationResponse.token_type) $($AuthenticationResponse.access_token)"  
        ContentType   = "application/json"  
    }  
    

    1. Now build the request and start / stop the compute via the API

    $Action = "stop?api-version=2022-10-01"

    $Uri = $Scope + $ComputeResourceId + $Action  
    
    Invoke-WebRequest -Method Post -Uri $Uri -Headers $Headers  
    

    Where possible, use a managed identity to perform these actions instead, rather than a service principal, or at least store the credentials securely for the service principal and use the managed identity to retrieve these, rather than the secret stored in your code.

    I hope this helps provide you with the information you need. If it does, please make sure to mark the question as answered so it helps other people in future.

    Kind regards

    Alistair

    0 comments No comments

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.