Una pipeline è un’identità come le altre, solo che non ha un umano dietro. Su AZ-400 la domanda non è “come creo un service principal”, ma “dato questo requisito di isolamento, ciclo di vita e auditabilità, quale identità scelgo e chi paga il costo operativo della rotazione”. La superficie è tripla — Microsoft Entra ID, GitHub, Azure DevOps — con modelli diversi. Diamo per acquisiti i meccanismi di base e concentriamoci sulle decisioni di design e sui trade-off.
Identità di workload in Azure: service principal o managed identity
Il bivio iniziale è credenziale gestita da te contro credenziale gestita dalla piattaforma. Una managed identity è la scelta di default quando il carico gira su una risorsa Azure — macchina virtuale, scale set, cluster Kubernetes, o una piattaforma di hosting applicativo supportata: non esiste alcun segreto da custodire, ruotare o far scadere, eliminando un’intera categoria di incidenti da credenziali trapelate. Il service principal con segreto o certificato resta la risposta quando il chiamante non vive su una risorsa Azure che possa ospitare una managed identity, o quando serve un’app registration Entra ID vera e propria.
Dentro le managed identity il trade-off si sposta sul ciclo di vita. La system-assigned nasce e muore con la risorsa che la ospita, non è condivisibile e porta il nome della risorsa stessa: ottima per un workload contenuto in una singola risorsa, dove l’identità deve sparire insieme all’infrastruttura. La user-assigned è una risorsa Azure autonoma, con ciclo di vita indipendente, associabile a più risorse contemporaneamente. Microsoft la indica come tipo raccomandato per i servizi Microsoft, e in ottica DevOps il motivo è operativo: se ricrei l’infrastruttura a ogni deploy con IaC, una system-assigned costringe a riassegnare i ruoli RBAC dopo ogni ricreazione, mentre la user-assigned conserva le sue assegnazioni. Stesso ragionamento per la pre-autorizzazione: puoi concedere i permessi all’identità prima che la risorsa esista, sbloccando un provisioning in un’unica passata.
C’è un terzo pattern che l’esame ama: la managed identity usata come federated identity credential su un’app Entra ID, quando il workload deve agire come applicazione Entra ID senza segreti né certificati. Il limite documentato è di 20 credenziali federate di questo tipo per app.
GitHub: GitHub App, GITHUB_TOKEN e PAT
Il GITHUB_TOKEN è il punto di partenza, non un ripiego. GitHub lo genera all’inizio di ogni job e i suoi permessi sono limitati al repository che contiene il workflow. Su runner ospitati da GitHub vive al massimo quanto il job (il tetto di esecuzione è di sei ore); su runner self-hosted scade comunque entro 24 ore. Ha anche un comportamento che l’esame ama: gli eventi generati usando il GITHUB_TOKEN non innescano nuovi workflow run, il che previene la ricorsione ma spiega perché un workflow che committa con quel token non fa ripartire la CI. Le eccezioni note sono workflow_dispatch e repository_dispatch. Regola di design: dichiara sempre il blocco permissions al minimo necessario, a livello di workflow o di job.
Quando il token di job non basta — perché serve toccare più repository, o agire quando nessun job è in esecuzione — la scelta corretta è una GitHub App, non un personal access token. La App ha permessi granulari, emette installation token a vita breve, non consuma una postazione, continua a funzionare quando chi l’ha installata lascia l’organizzazione, e ha rate limit che scalano con il numero di repository e di utenti. Il PAT, al contrario, è legato all’identità di una persona: se quella persona cambia ruolo o esce, l’automazione si rompe. Se un PAT è inevitabile, usa la variante fine-grained, che si limita a repository selezionati con permessi granulari e che l’organizzazione può sottoporre ad approvazione e a una policy di durata massima.
Per il ponte fra i due mondi, GitHub Actions verso Azure, la risposta di design è OIDC: il cloud provider emette un token a vita breve valido per un singolo job, e la trust si stringe sulla claim sub, che può vincolare la federazione a uno specifico repository, branch o environment. Nessun segreto cloud replicato nei GitHub secrets.
Azure DevOps: service connection e il costo dei PAT
La service connection è il perimetro di autorizzazione delle pipeline. Per le connessioni Azure Resource Manager Microsoft raccomanda oggi la workload identity federation, in due varianti: app registration (automatic), oppure una user-assigned managed identity esistente — quest’ultima è la strada da imboccare quando non hai il permesso di creare app registration nel tenant. Le opzioni basate su segreto restano solo per retrocompatibilità e casi limite, e le connessioni già create possono essere convertite. Due dettagli operativi che l’esame usa come distrattori: le service connection non utilizzate per 100 giorni vengono disabilitate automaticamente, e concedere l’accesso a tutte le pipeline è esplicitamente sconsigliato — autorizza pipeline per pipeline.
I PAT di Azure DevOps vanno trattati come password. Sono legati all’utente che li ha creati e ne ereditano l’identità, quindi non sono mai “identità di servizio”: se l’utente viene rimosso, il token viene invalidato entro un’ora. Il design corretto è tenerli per richieste una tantum e prototipi, preferire token Entra ID, managed identity o service principal per tutto ciò che gira in modo continuativo, e a livello di governance imporre le policy amministrative che limitano PAT full-scoped, PAT globali su più organizzazioni e durate lunghe. Nota utile: service principal e managed identity non possono creare o gestire PAT, il che chiude la scorciatoia di far generare token a un’automazione.
Permessi umani: gruppi, ruoli, livelli di accesso, progetti e team
In Azure DevOps convivono due assi ortogonali che l’esame confonde di proposito. Il livello di accesso decide quali funzionalità del portale l’utente vede ed è una leva di licensing; il gruppo di sicurezza decide cosa può fare. Stakeholder dà accesso limitato ai progetti privati, è assegnabile a un numero illimitato di utenti senza licenza, permette di vedere work item, partecipare alle discussioni, consultare dashboard e approvare release, ma non dà accesso al codice: se il requisito è “questo referente deve leggere i repository”, la risposta è Basic, non un permesso in più. I gruppi di default di progetto includono tra gli altri Readers, Contributors e Project Administrators, con Project Collection Administrators a livello di organizzazione. Assegna sempre tramite gruppi, popolandoli con gruppi Entra ID, e ricorda le regole di risoluzione: Deny prevale su Allow nella maggior parte dei casi, Not set è un diniego implicito che però lascia passare l’ereditarietà, e nella gerarchia degli oggetti la specificità batte l’ereditarietà.
Progetti e team sono la stessa decisione a scala maggiore. Microsoft raccomanda di partire da un singolo progetto con più team: minimizza la manutenzione amministrativa e offre l’esperienza migliore di collegamento fra oggetti, mentre spostare dati fra progetti fa perdere la storia associata. Un progetto separato si giustifica per requisiti di isolamento degli accessi, processi di work tracking personalizzati per business unit, unità organizzative con propri amministratori, o test di personalizzazioni. Ogni team creato genera automaticamente un gruppo di sicurezza omonimo: è il meccanismo con cui la struttura organizzativa diventa struttura di permessi.
Su GitHub la simmetria è imperfetta e va conosciuta. I permessi si concedono a team dell’organizzazione, ma un outside collaborator non è membro dell’organizzazione: ha accesso a uno o più repository specifici e non può essere aggiunto a un team. Su piano a pagamento, aggiungerlo a un repository privato consuma una licenza. Va bene per il consulente su un singolo repository, non per accessi coerenti su un insieme di repository governato centralmente.
Come cade all’esame
- “Più macchine virtuali ricreate a ogni deploy devono accedere allo stesso Key Vault mantenendo i permessi” → user-assigned managed identity condivisa; la system-assigned costringerebbe a riassegnare RBAC a ogni ricreazione.
- “Un workflow deve aprire pull request su decine di repository dell’organizzazione, senza dipendere da un dipendente” → GitHub App con installation token; non un PAT, che è legato a una persona e si rompe all’offboarding.
- “Il workflow deve solo taggare e commentare nel proprio repository” → GITHUB_TOKEN con blocco
permissionsminimo; non serve altra identità. - “Il deploy da GitHub Actions ad Azure non deve conservare segreti cloud” → OIDC con federazione vincolata su repository ed environment tramite la claim
sub. - “Creare una service connection ARM senza poter registrare applicazioni nel tenant” → workload identity federation su una user-assigned managed identity esistente.
- “Un revisore di business deve vedere board e approvare release, senza costi di licenza” → livello di accesso Stakeholder; se serve anche il codice, allora Basic.
- “Un consulente esterno lavora su un solo repository e non deve vedere il resto dell’organizzazione” → outside collaborator, ricordando che non è inseribile in un team.