Una service connection è l'identità con cui una pipeline di Azure DevOps entra in Azure. Questa procedura ne crea due: una automatica, dove l'identità la crea Azure DevOps, e una a mano. Nessuna delle due contiene una password.
Occorre: un account Azure con una sottoscrizione attiva e il ruolo Owner su di essa, un'organizzazione di Azure DevOps con un progetto e un repository, l'interfaccia a riga di comando di Azure con l'accesso già fatto (az login), un browser.
Durata: circa trenta minuti.
Costo: zero. Gruppi di risorse, etichette e registrazioni di applicazioni non si pagano, e le esecuzioni della pipeline rientrano nei 1.800 minuti gratuiti al mese.
Il portale delle schermate è in inglese: i nomi dei comandi sono riportati come appaiono a schermo.
La connessione automatica
1. Prepara due gruppi di risorse
az group create -n rg-guide-devops-01 -l italynorth
az group create -n rg-guide-devops-02 -l italynorthIl primo è quello che la pipeline potrà usare. Il secondo serve a dimostrare che non lo può toccare.
2. Apri il modulo
Nel progetto di Azure DevOps: Project settings > Service connections > New service connection. Scegli Azure Resource Manager e premi Next.

3. Scegli l'identità e limita l'ambito
- Identity type: App registration (automatic)
- Credential: Workload identity federation
- Scope level: Subscription
- Subscription: la tua
- Resource group:
rg-guide-devops-01 - Service Connection Name:
sc-guide-auto

Il campo Resource group è facoltativo: lasciandolo vuoto la connessione prende il ruolo su tutta la sottoscrizione, compilandolo lo prende su quel solo gruppo.
In fondo al modulo, sotto Security, lascia Grant access permission to all pipelines deselezionato. Premi Save.
4. La connessione è pronta
L'elenco riporta il nome, il tipo e il metodo di autenticazione: Workload identity federation (Automatic).

Cosa ha creato Azure DevOps al posto tuo
5. La registrazione dell'applicazione e la credenziale federata
Nel portale di Azure: Microsoft Entra ID > App registrations. La voce nuova si chiama <organizzazione>-<progetto>-<identificativo della connessione>. Aprila, poi Certificates & secrets > Federated credentials, e apri l'unica riga.

Dentro non c'è nessuna password. Ci sono due valori:
Issuer https://login.microsoftonline.com/<identificativo del tenant>/v2.0
Value /eid1/c/pub/t/.../a/.../sc/<id organizzazione>/<id connessione>Gli stessi valori si leggono da riga di comando:
az ad app federated-credential list --id <identificativo applicazione> -o json6. Il ruolo, solo sul gruppo di risorse
Nel portale, il gruppo rg-guide-devops-01 > Access control (IAM) > Role assignments, filtrando per il nome del progetto.

Una riga sola: Contributor, con ambito This resource. Sul secondo gruppo non c'è niente.
La prova: una pipeline
7. Il file
Metti questo file nel repository, con il nome azure-pipelines.yml:
trigger: none
pool:
vmImage: ubuntu-latest
steps:
- task: AzureCLI@2
displayName: Chi sono
inputs:
azureSubscription: sc-guide-auto
scriptType: bash
scriptLocation: inlineScript
inlineScript: |
az account show --query "{identita:user.name, tipo:user.type}" -o yaml
- task: AzureCLI@2
displayName: Legge il gruppo autorizzato
inputs:
azureSubscription: sc-guide-auto
scriptType: bash
scriptLocation: inlineScript
inlineScript: |
az group show -n rg-guide-devops-01 --query "{nome:name, regione:location}" -o yaml
- task: AzureCLI@2
displayName: Scrive un'etichetta sul gruppo autorizzato
inputs:
azureSubscription: sc-guide-auto
scriptType: bash
scriptLocation: inlineScript
inlineScript: |
az group update -n rg-guide-devops-01 --tags guida=service-connection --query tags -o yaml
- task: AzureCLI@2
displayName: Prova il gruppo non autorizzato
continueOnError: true
condition: always()
inputs:
azureSubscription: sc-guide-auto
scriptType: bash
scriptLocation: inlineScript
inlineScript: |
az group show -n rg-guide-devops-02 --query name -o tsvIl nome della connessione si scrive in azureSubscription: il campo vuole il nome della service connection, non quello della sottoscrizione. L'ultimo passo ha continueOnError: true perché deve fallire.
8. Crea la pipeline
Pipelines > New pipeline > Azure Repos Git > il repository > Existing Azure Pipelines YAML file > /azure-pipelines.yml > Continue > Run.
9. La prima esecuzione si ferma e chiede il permesso

Premi View, poi Permit, e conferma: «Granting permission here will permit the use of Service connection 'sc-guide-auto' for all waiting and future runs of this pipeline.»
10. L'esito
L'esecuzione dura 41 secondi. Nel registro, le righe che contano:
Chi sono
az login --service-principal -u *** --tenant 4813d8ed-... --federated-token ***
identita: ***
tipo: servicePrincipal
Legge il gruppo autorizzato
nome: rg-guide-devops-01
regione: italynorth
Scrive un'etichetta sul gruppo autorizzato
guida: service-connection
Prova il gruppo non autorizzato
ERROR: (AuthorizationFailed) The client '***' with object id '15bb16b7-...' does not have
authorization to perform action 'Microsoft.Resources/subscriptions/resourcegroups/read'
over scope '/subscriptions/.../resourcegroups/rg-guide-devops-02' or the scope is invalid.L'agente entra con --federated-token. L'identità è coperta dagli asterischi anche nel registro.
La stessa connessione a mano, con un ruolo mirato
11. Crea l'applicazione da riga di comando
Dalla Cloud Shell del portale, oppure da un terminale con az login già fatto:
az ad app create --display-name sc-guide-manual --sign-in-audience AzureADMyOrg
az ad sp create --id <identificativo applicazione>Il primo comando restituisce l'appId, il secondo crea il service principal.
12. Compila il modulo manuale
New service connection > Azure Resource Manager, poi:
- Identity type: App registration or managed identity (manual)
- Credential: Workload identity federation
- Service Connection Name:
sc-guide-manual - Directory (tenant) ID: l'identificativo del tenant
Premi Next. Azure DevOps salva la connessione come bozza e mostra i due valori da registrare in Azure.

Compila gli altri campi:
- Subscription ID: l'identificativo della sottoscrizione
- Subscription name: il nome della sottoscrizione
- Application (client) ID: l'
appIddel passo 11
Lascia la finestra aperta.
13. Registra la credenziale e assegna il ruolo
Con Issuer e Subject identifier copiati dal modulo:
az ad app federated-credential create --id <identificativo applicazione> --parameters '{
"name": "sc-guide-manual",
"issuer": "<Issuer copiato dal modulo>",
"subject": "<Subject identifier copiato dal modulo>",
"audiences": ["api://AzureADTokenExchange"]
}'
az role assignment create --assignee <identificativo applicazione> --role Reader --scope /subscriptions/<identificativo sottoscrizione>/resourceGroups/rg-guide-devops-01Il ruolo è Reader, su un solo gruppo. Torna nel modulo e premi Verify and save.
14. Riesegui la pipeline
Cambia una riga nel file, azureSubscription: sc-guide-manual, e fai ripartire la pipeline.
Legge il gruppo autorizzato
nome: rg-guide-devops-01
regione: italynorth
Scrive un'etichetta sul gruppo autorizzato
ERROR: (AuthorizationFailed) The client '***' with object id 'e1fad9c5-...' does not have
authorization to perform action 'Microsoft.Resources/subscriptions/resourcegroups/write'
over scope '/subscriptions/.../resourcegroups/rg-guide-devops-01' or the scope is invalid.Legge, e si ferma sul passo che scrive.
Pulire
az group delete -n rg-guide-devops-01 --yes --no-wait
az group delete -n rg-guide-devops-02 --yes --no-wait
az ad app delete --id <identificativo applicazione manuale>Le due connessioni si cancellano dal progetto, da Project settings > Service connections. La registrazione creata dalla modalità automatica se ne va insieme alla connessione.
Nomi dei comandi, schermate e tempi rilevati su Azure DevOps e sul portale di Azure il 6 novembre 2026, regione Italy North, con l'interfaccia a riga di comando di Azure 2.91.0 e l'attività AzureCLI@2 versione 2.282.3.