Quando un servizio esterno — una Azure Function, un job schedulato, un middleware di integrazione — deve leggere o scrivere dati in Dataverse senza che nessun utente sia collegato, non puoi usare le credenziali di una persona. Serve un’identità non presidiata (unattended), governata centralmente e disaccoppiata dagli account umani. La combinazione corretta su Power Platform è: app registration in Microsoft Entra ID + flusso OAuth 2.0 client credentials + application user in Dataverse.
App registration in Microsoft Entra ID
Il primo passo è registrare un’applicazione in Microsoft Entra ID. La registrazione genera due valori chiave:
- Application (client) ID — l’identificativo pubblico dell’app.
- Directory (tenant) ID — il tenant che ospita l’identità.
Alla app assegni una credenziale per provare la propria identità: un client secret oppure un certificate. In scenario associate la scelta pesa: il client secret è più semplice ma ha una scadenza (max consigliato 24 mesi, spesso 6-12) e va custodito; il certificate è più robusto, adatto a produzione, e sfrutta chiavi asimmetriche senza trasmettere un segreto condiviso.
Per accedere a Dataverse non servono API permissions Graph elaborate: l’autorizzazione effettiva sui dati viene assegnata dentro Dataverse tramite il security role, non solo nel consenso Entra.
Flusso OAuth 2.0 client credentials
Il client credentials grant è il flusso pensato per la comunicazione server-to-server senza interazione utente. L’app chiama l’endpoint token di Entra presentando client ID + secret/certificate e richiedendo un token per lo scope Dataverse:
POST https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token
scope = https://<org>.crm4.dynamics.com/.default
Entra restituisce un access token (JWT) che l’app allega alle chiamate alla Web API di Dataverse. Il token identifica l’application user, non una persona: audit, ownership dei record e privilegi seguono quell’identità applicativa.
Application user in Dataverse
Un access token valido non basta: Dataverse deve conoscere quell’app come utente. Nel Power Platform admin center → ambiente → Application users crei un application user collegandolo tramite l’Application (client) ID della app registration. Il sistema abbina l’identità Entra a un utente non interattivo dell’ambiente.
All’application user assegni uno o più security role. Il principio guida è il least privilege: crea un ruolo custom con solo i privilegi (create/read/write/append) sulle specifiche tables che l’integrazione tocca, allo scope minimo necessario (spesso Organization perché un’app non ha una business unit “sua” né gerarchia manageriale). Non riusare mai System Administrator per comodità.
Application user vs credenziali utente
| Aspetto | Application user | Credenziali utente |
|---|---|---|
| Licenza | Non consuma licenza utente | Richiede licenza |
| Interattività | Non interattivo, ideale unattended | Pensato per l’uso umano |
| Sicurezza | Nessuna password rotabile dall’utente | Password/MFA legati alla persona |
| Continuità | Sopravvive a offboarding | Si rompe se l’utente viene disabilitato |
Usare un account persona per un’integrazione headless è un anti-pattern: se quell’utente lascia l’azienda o gli scade la password, l’integrazione muore, e l’audit trail attribuisce operazioni automatiche a una persona reale.
Gestione di secret e certificati
La credenziale è il punto debole. Best practice:
- Non incorporare mai il secret nel codice o in repository. Conservalo in Azure Key Vault e leggilo a runtime, meglio ancora via managed identity dove possibile.
- Preferisci certificate over secret per i carichi di produzione.
- Il client secret ha una scadenza: pianifica il rinnovo (rotation) prima della data, con overlap fra vecchia e nuova credenziale per evitare downtime. Un secret scaduto è la causa n.1 di integrazioni che smettono di funzionare “all’improvviso”.
Trappole tipiche d’esame
- Scenario: un’app service-to-service deve scrivere in Dataverse senza utenti. → Risposta: app registration in Entra ID + application user con security role, non un account utente licenziato.
- Scenario: quale OAuth flow per un daemon non presidiato? → Risposta: client credentials, non authorization code né device code (quelli richiedono interazione utente).
- Scenario: l’application user deve solo leggere/scrivere due tabelle. → Risposta: security role custom least-privilege allo scope Organization, mai System Administrator.
- Scenario: l’integrazione funzionava, ora restituisce 401. → Risposta: verifica il client secret scaduto e ruotalo; considera il passaggio a certificate.
- Scenario: dove custodire la credenziale della app? → Risposta: Azure Key Vault (o managed identity), mai hardcoded nel codice o nei file di config versionati.