
Register Self-Hosted Azure DevOps Agent using Service Principal
Personal Access Tokens (PAT) are evil, avoid them. Use Service Principal instead.
I have a "slight" dislike for Personal Access Tokens (PATs). My dislike comes from un-manageability of them. In Azure DevOps (ADO), PATs are created by each user, there is no way to create them on the organization or project level. Then worst part is, even if you disable an user in ADO, PATs are still active. So, from security stand point PATs are EVIL.
With version 3.227.1 of Azure Pipeline Agent, we are able to use Service Principal as authentication method.
What did make it a bit harder to use was, it is not documented in any way.
I did figure out 3 ways you can use Service Principal for registering an Agent.
Prerequisites
Method 1 - Service Principal as Authentication Method
./config.sh --auth sp \
--url <org_url> \
--clientid <client_id> \
--tenantid <tenant_id> \
--clientsecret <client_secret> \
--agent <agent_name> \
--pool <agent_pool_name> \
[--replace --unattended --acceptTeeEula]
Where:
org_url
: your Azure DevOps organization urlclient_id
: client ID of the service principaltenant_id
: tenant ID associated with the Entra IDclient_secret
: client secret for the service principalagent_name
: name of the agentagent_pool_name
: name of the agent pool
For Example:
./config.sh --auth sp \
--url https://dev.azure.com/myorg/ \
--clientid f23d714e-259b-46fe-b5b3-7601f03b2090 \
--tenantid 0bf932af-ff5e-4c74-8772-334d3d1b8cf2 \
--clientsecret U2Fsd~GVkX195bnqi10aTpRNDVdappWv2WLwGw5W \
--agent agent01 --pool pool01 \
[--replace --unattended --acceptTeeEula]
Method 2 - Fetch AccessToken with Azure CLI
az login --service-principal --allow-no-subscriptions \
--username <client_id> \
--tenant <tenant_id> \
--password <client_secret>
AZP_TOKEN=$(az account get-access-token \
--resource 499b84ac-1321-427f-aa17-267ca6975798 \
--query "accessToken" --output tsv)
./config.sh --auth pat \
--url <org_url> \
--token $AZP_TOKEN \
--agent <agent_name> --pool <agent_pool_name> \
[--replace --unattended --acceptTeeEula]
org_url
: your Azure DevOps organization urlclient_id
: client ID of the service principaltenant_id
: tenant ID associated with the Entra IDclient_secret
: client secret for the service principalagent_name
: name of the agentagent_pool_name
: name of the agent pool
For Example:
az login --service-principal --allow-no-subscriptions \
--username f23d714e-259b-46fe-b5b3-7601f03b2090 \
--tenant 0bf932af-ff5e-4c74-8772-334d3d1b8cf2 \
--password U2Fsd~GVkX195bnqi10aTpRNDVdappWv2WLwGw5W
AZP_TOKEN=$(az account get-access-token \
--resource 499b84ac-1321-427f-aa17-267ca6975798 \
--query "accessToken" --output tsv)
./config.sh --auth pat \
--url https://dev.azure.com/myorg/ \
--token $AZP_TOKEN \
--agent agent01 --pool pool01 \
[--replace --unattended --acceptTeeEula]
Method 3 - Fetch AccessToken with cURL
AZP_DATA="grant_type=client_credentials&client_id=<client_id>&client_secret=<client_secret>&resource=499b84ac-1321-427f-aa17-267ca6975798/.default"
AZP_TOKEN=$(curl -X POST -d $AZP_DATA https://login.microsoftonline.com/<tenant_id>/oauth2/token | jq -r '.access_token')
./config.sh --auth pat \
--url <org_url> \
--agent agent01 --pool pool01 \
--token $AZP_TOKEN \
[--replace --unattended --acceptTeeEula]
org_url
: your Azure DevOps organization urlclient_id
: client ID of the service principaltenant_id
: tenant ID associated with the Entra IDclient_secret
: client secret for the service principalagent_name
: name of the agentagent_pool_name
: name of the agent pool
For Example:
AZP_DATA="grant_type=client_credentials&client_id=f23d714e-259b-46fe-b5b3-7601f03b2090&client_secret=U2Fsd~GVkX195bnqi10aTpRNDVdappWv2WLwGw5W&resource=499b84ac-1321-427f-aa17-267ca6975798/.default"
AZP_TOKEN=$(curl -X POST -d $AZP_DATA https://login.microsoftonline.com/0bf932af-ff5e-4c74-8772-334d3d1b8cf2/oauth2/token | jq -r '.access_token')
./config.sh --auth pat \
--url https://dev.azure.com/myorg/ \
--agent agent01 --pool pool01 \
--token $AZP_TOKEN \
[--replace --unattended --acceptTeeEula]
Resources
- Get started with Azure DevOps | Microsoft Learn
- Azure Pipelines agents | Microsoft Learn
- Release v3.227.1 · microsoft/azure-pipelines-agent · GitHub
- Service Principal auth by KonstantinTyukalov · Pull Request #4255 · microsoft/azure-pipelines-agent · GitHub
- Register an agent using a service principal | Microsoft Learn