Service Connections
ado-aw pipelines use Azure Resource Manager (ARM) service connections to mint Azure DevOps-scoped tokens at runtime. These tokens grant the pipeline controlled access to ADO APIs — separately for the agent (read) and the executor (write).
Why service connections?
Section titled “Why service connections?”The compiled pipeline uses the AzureCLI@2 task to call az account get-access-token --resource 499b84ac-1321-427f-aa17-267ca6975798 — this mints a short-lived ADO token scoped to the service connection’s identity. This keeps credentials short-lived and auditable, and avoids storing long-lived PATs.
| Connection | Used by | Purpose |
|---|---|---|
| Write (required for safe outputs) | Stage 3 — SafeOutputs executor | Create PRs, work items, wiki pages, etc. |
| Read (optional) | Stage 1 — Agent | Query ADO APIs (work items, repos, builds) |
Create the write service connection
Section titled “Create the write service connection”This is the minimum required connection. It powers Stage 3 safe-output execution.
-
Go to your Azure DevOps Project → Project Settings → Service connections
-
Click New service connection → Azure Resource Manager
-
Choose your authentication method:
The simplest option — Azure DevOps creates the app registration and credentials for you.
- Select Service principal (automatic)
- Choose an Azure subscription (the identity needs at least Reader on the subscription — this is only used for
azlogin, not for ADO operations) - Scope to a resource group if preferred
- Name the connection (e.g.
ado-aw-write) — this is the value you’ll use inpermissions.write - Click Save
Azure DevOps creates an Entra ID app registration and configures everything automatically.
Secretless — no client secrets to rotate. Use this if your organization requires manual control.
- Create an App Registration in Entra ID (note the Application ID and Tenant ID)
- In ADO, select Workload Identity federation (manual)
- Fill in the Subscription ID, Service Principal Id (Application ID), and Tenant ID
- Name the connection (e.g.
ado-aw-write) - Click Verify and save
- Copy the generated Issuer and Subject identifier from the connection details
- Back in Azure Portal → App Registration → Certificates & secrets → Federated credentials → Add credential with the Issuer and Subject values
Use if your organization doesn’t support Workload Identity Federation or automatic provisioning.
- Create an App Registration in Entra ID (note the Application ID and Tenant ID)
- In the App Registration → Certificates & secrets → New client secret (copy the value)
- In ADO, select Service principal (manual)
- Fill in the Subscription ID, Service Principal Id, Service principal key (secret), and Tenant ID
- Name the connection (e.g.
ado-aw-write) - Click Verify and save
-
Grant ADO permissions to the service principal. The identity behind the connection needs permission to perform write operations in Azure DevOps:
- Go to Azure DevOps Organization Settings → Users
- Add the service principal (search by its app registration name)
- Set access level to Basic
- Add it to a project-level group with the permissions your safe outputs need — Contributors is sufficient for most use cases (PRs, work items, branches, tags, wiki pages)
-
Reference it in your agent front matter:
permissions:write: ado-aw-write # ← name of the service connection you created
Create the read service connection (optional)
Section titled “Create the read service connection (optional)”If your agent needs to query Azure DevOps APIs (e.g. read work items, list PRs, fetch build results), create a second connection with read-only ADO permissions.
Follow the same steps as above, but:
- Name the connection
ado-aw-read(or similar) - In ADO, grant the service principal Readers group access (or a custom group with only read permissions)
Then reference both in your agent file:
permissions: read: ado-aw-read write: ado-aw-writePermission combinations
Section titled “Permission combinations”| Configuration | Agent can read ADO? | Safe outputs can write? |
|---|---|---|
Both read + write | ✅ | ✅ |
Only read | ✅ | ❌ |
Only write | ❌ | ✅ |
| Neither (default) | ❌ | ❌ |
Authorize the pipeline
Section titled “Authorize the pipeline”On the first run, Azure DevOps will prompt you to authorize the pipeline to use the service connections. You can also pre-authorize:
- In the service connection’s settings, go to Security
- Under Pipeline permissions, click + and add your ado-aw pipeline (or grant access to all pipelines in the project)
Verify your connection works
Section titled “Verify your connection works”To confirm your service connection can mint ADO tokens, create a test pipeline:
trigger: none
pool: vmImage: ubuntu-latest
steps: - task: AzureCLI@2 displayName: "Test ADO token mint" inputs: azureSubscription: 'ado-aw-write' # your connection name scriptType: 'bash' scriptLocation: 'inlineScript' inlineScript: | TOKEN=$(az account get-access-token \ --resource 499b84ac-1321-427f-aa17-267ca6975798 \ --query accessToken -o tsv) if [ -n "$TOKEN" ]; then echo "✅ Successfully minted ADO token (${#TOKEN} chars)" else echo "❌ Failed to mint ADO token" exit 1 fiIf this pipeline succeeds, your connection is correctly configured for ado-aw.
Troubleshooting
Section titled “Troubleshooting”| Symptom | Likely cause |
|---|---|
AzureCLI@2 fails with “service connection not found” | The pipeline isn’t authorized to use the connection — check pipeline permissions in the connection’s Security tab |
| Token mints but safe outputs return 401/403 | The service principal doesn’t have sufficient ADO permissions — verify its group membership in ADO Organization Settings → Users |
| ”AADSTS700024: Client assertion is not within its valid time range” | Federated credential issuer/subject mismatch — regenerate in the App Registration |
| Compilation error: “require write access to ADO, but no write service connection is configured” | Your agent uses write-requiring safe outputs but is missing permissions.write in front matter |