Azure AD Service Principal for Making Agentless API calls from Releases to Pipeline

85 Views Asked by At

I currently have a Agentless Release pipeline which makes an API call to a AzureDevops pipeline on https://dev.azure.com/myorg/. Currently for authentication, I use a generic service connection with an email address and PAT token

In order to eliminate PAT tokens, I am trying to use a Service Principal ID and secret. I have tried to set connection type to Azure resource manager, choose the appropriate service principal but I was not able to get it working.

Is this method of authentication currently supported by Microsoft and can anyone point me to some information on how auth can be achieved? The error I keep getting is azure devops {"error":{"code":"MissingSubscription","message":"The request did not have a subscription or a valid tenant level resource provider."}} Exception Message:

enter image description here

1

There are 1 best solutions below

1
Bright Ran-MSFT On

When using the Invoke REST API task to call Azure DevOps REST API, it is recommended to use the 'system.AccessToken' (job access token) as authorization instead of a user PAT or a Service Principal access token.

Because the 'system.AccessToken' combines safety and convenience:

  1. The 'system.AccessToken' is dynamically generated by Azure Pipelines for each job at run time. It is generated when a pipeline job starts and revoked when the job ends.

  2. You can control the permissions of 'system.AccessToken' by controlling the permissions of the following identities.

    • Project Collection Build Service ({Organization Name})
    • {Project Name} Build Service ({Organization Name})

For more details, you can see "Job access tokens".


To use the 'system.AccessToken' on the Invoke REST API task to call Azure DevOps REST API, you can do like as below:

  1. Suppose I need to call the API "Runs - Get" to check whether the status of a specified pipeline run is successfully completed.

  2. Go to Project Settings > Service connections, create a Generic service connection like as below. You just need to set the Server URL and Service connection name. MyOrg is the name of Azure DevOps organization, and MyProj is the name of project.

    enter image description here

  3. On the Invoke REST API task, settings like as below.

    enter image description here


If you want to use the Service Principal as authorization, you need to do like as below:

  1. Prerequisites in AAD.

    • Create a Service Principal in your AAD (Microsoft Entra ID), if you do not have one.
    • Create a client secret for the Service Principal.
  2. Prerequisites in Azure DevOps.

    • Go to Organization Settings > Azure Active Directory, ensure the organization has connected to the AAD where the Service Principal was created.
    • Go to Organization Settings > Users, search and add the Service Principal into the organization.
    • Add the Service Principal into a security group so that you can manage the permissions of it through that group in the organization.
  3. Generate the Access Token for the Service Principal. You can run below Bash script to generate the token.

    access_token=$(curl -X POST -H "Content-Type: application/x-www-form-urlencoded" 'https://login.microsoftonline.com/{tenant_ID}/oauth2/v2.0/token' \
    -d 'grant_type=client_credentials&client_id={client_id}&client_secret={client_secret}&scope=499b84ac-1321-427f-aa17-267ca6975798/.default' | jq -r '.access_token')
    echo $access_token
    
    • {tenant_ID} is the Directory (tenant) ID of AAD.
    • {client_id} is the Application (client) ID of the Service Principal.
    • {client_secret} is the value of the client secret for the Service Principal.
  4. Set the value of access_token as a secret variable (i.e., name it sp_access_token) in the pipeline. Then on the Invoke REST API task, use the secret to the Headers like as below.

    {
    "Authorization": "Bearer $(sp_access_token)"
    }
    

NOTE:

The Access Token for the Service Principal has an only 24-hour lifetime as AAD will regularly rotate the token. So, you need to refresh the token at least once every 24 hours. This could cause inconvenience when using the token in pipeline jobs.

So, as stated above, it is recommended to use the 'system.AccessToken'.