Integrare un’API esterna protetta da OAuth in Copilot Studio (ex Power Virtual Agents) è possibile e scalabile: la chiave è un Custom Connector in Power Automate, pubblicato in soluzione, richiamato da un Cloud Flow visibile come azione in Copilot e infine distribuito in Microsoft Teams a livello tenant.
Scenario e problema
L’utente vuole esporre in Copilot Studio un plugin personalizzato capace di interrogare una REST API esterna protetta con OAuth/SSO e renderla disponibile in Microsoft Teams a tutti gli utenti del tenant. I tentativi fatti con le opzioni “AI Plugin → Aggiorna o ottieni dati esterni” e “AI Plugin → Custom flow” rimandano a Power Automate, dove la configurazione OAuth si blocca perché servono parametri che solo un amministratore può fornire. In Copilot Studio l’opzione “Aggiungi API per connettore personalizzato” è inattiva (grigia) e il Cloud Flow appena creato non appare tra le azioni importabili.
Che cosa serve davvero
Serve un percorso guidato che separi autenticazione e autorizzazione dall’uso in Copilot. In altre parole, il Custom Connector deve incapsulare l’handshake OAuth; il Cloud Flow richiama il connettore; Copilot Studio importa il Flow come azione; infine l’app viene distribuita in Teams.
Architettura consigliata
Copilot (Teams)
│ invoca Azione
▼
Copilot Studio ──> Plugin/Azione (Flow)
│
▼
Power Automate Cloud Flow
│
▼
Custom Connector (OAuth 2.0)
│
▼
API esterna protetta (Entra ID / altri IdP)
Perché i tentativi iniziali falliscono
- Autorizzazione mancante: l’applicazione che rappresenta l’API non è stata registrata o approvata da un amministratore (consent admin), quindi non si ottengono Client ID/Secret/Redirect URL e scope.
- Scelta del trigger del Flow: i Flow visibili in Copilot devono essere creati in una Solution, appartenere allo stesso Environment di Copilot Studio e, per l’integrazione nativa, usare il trigger Copilot Studio (ex Power Virtual Agents) con input/output dichiarati.
- Connettore non pubblicato: finché il Custom Connector non è pubblicato e non esiste almeno una Connection valida, l’opzione “Aggiungi API per connettore personalizzato” può restare disabilitata.
- Autenticazione “grezza” nel Flow: usare l’azione HTTP diretta significa dover gestire manualmente OAuth; con il Custom Connector lo fa la piattaforma.
Fasi operative raccomandate
Fase | Cosa fare | Perché/Dettagli |
---|---|---|
1• Recuperare consent admin | Coinvolgere un Global/Cloud App Admin per registrare l’app dell’API in Entra ID (o approvare la tua) e fornire Client ID, Tenant ID, Redirect URL, Scope e—se richiesto—Client Secret o certificato. | Solo un admin può creare l’Enterprise Application, concedere i permessi, impostare redirect, rilasciare i parametri di sicurezza. |
2• Configurare il Custom Connector | In Power Automate → Custom Connectors: seleziona OAuth 2.0 con Authorization Code (abilita PKCE), inserisci i parametri, definisci le operazioni API (verbo, URL, header, body). | Il connettore incapsula l’handshake OAuth: Flow e Copilot non devono più gestire token/refresh. |
3• Test e pubblicazione | Usa la scheda Test → “New connection” per autenticarti (SSO popup). Se tutto ok, pubblica il connettore. | La Connection risultante sarà riutilizzabile da Flow e Copilot. |
4• Creare o aggiornare il Cloud Flow | Nella stessa Solution dell’assistente: crea un Cloud Flow con trigger “Copilot Studio” e aggiungi l’azione del connettore personalizzato. | Così il Flow diventa importabile come Azione in Copilot Studio. |
5• Rendere visibile il Flow in Copilot Studio | In Copilot Studio → Plugin → Azioni → Importa da Power Automate. Seleziona il Flow solution-aware. | Solo i Flow in soluzioni, nello stesso environment e con schema I/O esposto compaiono nell’elenco. |
6• Distribuire in Teams | Copilot Studio → Publish → Channels → Microsoft Teams. Per distribuzione tenant-wide coinvolgi il Teams Admin (caricamento app e policy di Setup). | Tutti gli utenti vedranno l’app Copilot in Teams (desktop e mobile). |
Parametri e impostazioni OAuth utili
- Authorization URL:
https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/authorize
- Token URL:
https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token
- Scope: fornito dal proprietario dell’API (es.
api://<appId>/.default
ouser_impersonation
). - Grant: Authorization Code con PKCE abilitato (consigliato). Se l’API lo consente, per test può essere usato anche client_credentials (solo per scenari senza utente).
- Redirect URL: quello generato dal Custom Connector deve essere aggiunto nell’app registrata su Entra ID; in caso contrario si ottiene redirecturimismatch.
- Segreti e certificati: preferisci certificati a lunga durata e automatizza la rotazione dei segreti.
Prerequisiti organizzativi e di piattaforma
- Ruoli: Global Admin/Cloud App Admin per la registrazione app e consent; Environment Maker per creare connettori/flow; Teams Admin per la distribuzione dell’app.
- Licenze: i Custom Connector sono funzionalità premium di Power Platform; verifica i piani utente o per-flow idonei e la licenza di Copilot Studio per la pubblicazione in canali.
- Governance: DLP (Data Loss Prevention) deve permettere l’uso del connettore e la combinazione con altri connettori coinvolti nel Flow.
- Environment: Copilot, Flow e Custom Connector devono stare nello stesso environment.
Guida passo‑passo dettagliata
Coinvolgere l’amministratore per il consent
- Registrare o individuare l’app dell’API in Entra ID (App registrations).
- Configurare gli scope esposti dall’API (o prendere nota di quelli esistenti).
- Aggiungere tra i Redirect URI quello mostrato dal Custom Connector (lo vedrai quando inizi a configurarlo) e confermare il tipo “Web”.
- Creare un Client Secret (o caricare un certificato) e annotare il valore.
- Se l’API è multi-tenant o usa application permissions, concedere l’admin consent.
Creare il Custom Connector
- Power Automate → Custom connectors → New custom connector.
- Definisci metadati (nome, icona, colore) utili a distinguere il connettore in un ambiente ricco.
- Sicurezza: seleziona OAuth 2.0 → Authorization code e abilita PKCE se disponibile.
- Inserisci: Authorization URL, Token URL, Client ID, Client Secret (se richiesto), Scope, Redirect URL (di sola lettura, da registrare in Entra ID).
- Definisci le operazioni (Actions): per ogni endpoint specifica verbo, URL, querystring, header, body, schema della risposta. Mantieni i nomi autoesplicativi: saranno visibili ai maker.
Esempio di definizione OpenAPI ridotta
{
"swagger": "2.0",
"info": { "title": "Acme API", "version": "1.0" },
"host": "api.acme.tld",
"basePath": "/v1",
"schemes": ["https"],
"securityDefinitions": {
"oauth2": {
"type": "oauth2",
"flow": "accessCode",
"authorizationUrl": "https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/authorize",
"tokenUrl": "https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token",
"scopes": { "api://<appId>/.default": "Accesso API Acme" }
}
},
"paths": {
"/orders": {
"get": {
"summary": "Elenco ordini",
"operationId": "ListOrders",
"parameters": [
{ "name": "top", "in": "query", "type": "integer" },
{ "name": "Authorization", "in": "header", "type": "string", "x-ms-visibility": "internal" }
],
"responses": {
"200": { "description": "OK" },
"401": { "description": "Unauthorized" }
},
"security": [{ "oauth2": ["api://<appId>/.default"] }]
}
}
}
}
Testare e pubblicare il connettore
- Vai alla scheda Test del connettore → New connection.
- Completa l’accesso nel popup SSO; se vedi la schermata di consent, chiedi conferma all’Admin.
- Esegui una chiamata di prova (GET più semplice) e verifica status 200/204.
- Pubblica. D’ora in poi puoi riutilizzare la Connection in Flow e Copilot.
Creare il Cloud Flow nella Solution
- Crea o apri una Solution nello stesso environment di Copilot.
- New → Automation → Cloud flow con trigger Copilot Studio (ex Power Virtual Agents).
- Aggiungi l’azione del Custom Connector e mappa gli input provenienti dal trigger.
- Normalizza l’output con una forma stabile (tipicamente un oggetto con campi
success
,message
,data
). - Salva e attiva il Flow all’interno della Solution.
Esempio di schema output del Flow
{
"success": true,
"message": "Ordini trovati",
"data": [
{ "orderId": "A-1001", "total": 149.90, "status": "Ready" },
{ "orderId": "A-1002", "total": 89.50, "status": "Processing" }
]
}
Importare l’azione in Copilot Studio
- Apri l’assistente in Copilot Studio → Plugin → Azioni → Importa da Power Automate.
- Seleziona il Flow solution-aware con il trigger Copilot Studio e gli I/O definiti.
- Assegna un nome e una descrizione chiara all’azione; Copilot userà questi metadati per suggerire quando invocarla.
- Testa l’azione dal canvas di Copilot: fornisci esempi di prompt e verifica che la risposta del Flow sia presentabile all’utente finale.
Pubblicare in Microsoft Teams
- In Copilot Studio → Publish → Channels → Microsoft Teams.
- Genera/aggiorna il pacchetto dell’app.
- Per disponibilità tenant-wide: il Teams Admin carica l’app nel catalogo organizzativo e la distribuisce con le App Setup Policies (pin automatico, disponibilità a gruppi o a tutti).
Buone pratiche e consigli
- Minimo privilegio: concedi solo gli scope strettamente necessari; evita /.default se include permessi eccessivi.
- PKCE: abilitandolo riduci il rischio di intercettazione del codice di autorizzazione.
- Ambienti separati: Dev/Test/Prod con soluzioni managed per la promozione; usa Environment Variables per endpoint e scope.
- Connection References: nella Solution, mappa chiaramente le connessioni; in export/import verranno richieste le riconnessioni minime.
- Osservabilità: usa Run history dei Flow, Monitor del connettore, e i log di audit del tenant.
- Testing senza admin: se l’API prevede client_credentials, prova in Postman per validare endpoint e payload in attesa dell’admin consent.
- UX conversazionale: traduci risposte grezze dell’API in messaggi chiari; non riversare oggetti JSON illeggibili all’utente.
Perché l’opzione “Aggiungi API per connettore personalizzato” è grigia
L’opzione diventa selezionabile quando:
- Esiste almeno un Custom Connector pubblicato nello stesso environment dell’assistente.
- Hai permessi per usarlo (il connettore non è bloccato da DLP).
- È stata creata almeno una Connection funzionante per quel connettore (o sei in grado di crearla).
Perché il Flow non appare tra le azioni di Copilot
- Non è in Solution: crea/importa il Flow dentro una Solution.
- Trigger errato o assente: usa il trigger Copilot Studio (ex Power Virtual Agents).
- Nessun input/output: definisci almeno un parametro in ingresso o un’uscita nel trigger.
- Environment diverso: Flow e Copilot devono essere nello stesso environment.
- Flow disattivato: assicurati che sia On.
- Connettore non disponibile: DLP o mancanza di Connection possono impedirne l’uso.
Checklist rapida di validazione
- App Entra ID con redirect del connettore registrato e scope corretti.
- Custom Connector con OAuth 2.0 Authorization Code + PKCE abilitato; test OK.
- Connection creata e riutilizzabile.
- Flow in Solution con trigger Copilot Studio e schema I/O definito; stato attivo.
- Azione importata in Copilot Studio e testata con prompt di esempio.
- Pubblicazione su Teams e distribuzione via policy del Teams Admin.
Risoluzione problemi “OAuth”
Errore | Causa probabile | Come risolvere |
---|---|---|
invalid_client | Client ID/Secret errati o scaduti. | Rigenera il segreto, verifica l’app corretta e aggiorna il connettore. |
invalid_scope | Scope inesistente o non esposto dall’API. | Allinea gli scope in Entra ID e nel connettore; chiedi admin consent se richiesto. |
redirecturimismatch | Il Redirect URL del connettore non è presente nell’app registrata. | Aggiungi il Redirect URI nella registrazione e salva. |
access_denied | Utente o app non autorizzati ai permessi richiesti. | Rivedi i ruoli e l’admin consent; verifica Conditional Access. |
Loop di login | Cookie terze parti bloccati o sessioni conflittuali. | Prova InPrivate e consenti i popup; verifica le impostazioni del browser. |
Risoluzione problemi “Flow/Azione”
- Timeout: aumenta il timeout del connettore o spezza l’operazione in due azioni atomiche (es. submit + poll).
- Schema instabile: se l’API può tornare campi opzionali, normalizza con “Compose”/“Select” prima di restituire a Copilot.
- Localizzazione: converti date e numeri in formati adatti agli utenti (es. it-IT).
- Idempotenza: per operazioni POST, invia un idempotency key se supportato.
Esempio di mappatura nel Flow
- Trigger Copilot Studio: parametri
customerId
,sinceDate
. - Azione connettore: GET
/orders?customerId=@{triggerBody()?['customerId']}&since=@{triggerBody()?['sinceDate']}
. - Controllo errori: Configure run after su 4xx/5xx per restituire
success=false
. - Output trigger: restituisci un oggetto con elenco degli ordini e messaggi pronti per la UI.
Modello di risposta leggibile per Copilot
{
"cards": [
{
"title": "Ordine A-1001",
"subtitle": "Ready",
"facts": [
{ "label": "Cliente", "value": "Contoso" },
{ "label": "Totale", "value": "€ 149,90" },
{ "label": "Data", "value": "2025-10-12" }
]
}
],
"summary": "Trovati 2 ordini dopo 2025-10-01"
}
Se formatti così la risposta del Flow, Copilot ha già un riassunto e una struttura presentabile.
Governance, sicurezza e conformità
- DLP: classifica il connettore come Business e assicurati che i connettori combinati nel Flow appartengano allo stesso bucket.
- Segreti: privilegia i certificati; se usi segreti, applica rotazione periodica.
- Conditional Access: se l’API è dietro CA, prevedi eccezioni/controlli specifici per l’app registrata.
- Audit: abilita i log di esecuzione e traccia le richieste lato API (correla con l’aud e il tid del token).
- Export/Import: usa Managed Solutions per trasportare il connettore e il Flow; promuovi Dev→Test→Prod con variabili d’ambiente per endpoint e scope.
Domande frequenti
Posso evitare il Custom Connector e usare solo l’HTTP action?
Tecnicamente sì, ma dovrai gestire manualmente token/refresh, storage sicuro e scadenze: manutenzione elevata e scarsa riusabilità. Il Custom Connector è l’approccio corretto.
Si può fare SSO “trasparente” dall’utente di Teams?
Sì, quando la medesima identità è usata per ottenere i token delegati (Authorization Code). In ogni caso è il Custom Connector a negoziare l’accesso; Copilot non conserva i token.
Perché vedo “Insufficient privileges to complete the operation”?
Gli scope non includono l’operazione richiesta o l’admin consent non è stato concesso all’app. Verifica con l’amministratore.
Esempio completo di messa in produzione
- Admin registra/approva l’app API, definisce gli scope e fornisce Client ID, Tenant ID, Redirect e Secret/Cert.
- Maker crea il Custom Connector con OAuth 2.0 (Auth Code + PKCE), definisce le operazioni, testa e pubblica.
- Viene creata la Connection e validata con una chiamata happy-path.
- In una Solution, si crea il Flow con trigger Copilot Studio, si aggiunge l’azione del connettore e si normalizza la risposta.
- Il Flow viene importato come Azione in Copilot Studio e testato con prompt reali.
- Si pubblica il Copilot e si distribuisce l’app in Teams tramite il Teams Admin con App Setup Policy.
Riepilogo operativo in una frase
Serve innanzitutto l’intervento di un amministratore per registrare/approvare l’applicazione OAuth; con quei dati crei un Custom Connector, lo testi e lo pubblichi, lo usi in un Flow solution‑aware (trigger Copilot Studio) che poi importi come azione in Copilot Studio e, infine, distribuisci l’app in Teams tramite le politiche di distribuzione.
Appendice: suggerimenti rapidi
- Imposta Retry-After e gestisci i 429 dell’API con backoff esponenziale nel Flow.
- Se l’API supporta compressione, aggiungi
Accept-Encoding: gzip
nel connettore per risposte più rapide. - Per audit applicativo, propaga un Correlation-Id (GUID) dal Flow all’API e ritorno.
- Per la privacy, maschera dati sensibili prima di loggarli (PII).
- Documenta nella descrizione del connettore: endpoint, scope, limiti e codici errore comuni.
FAQ lampo
- “Custom flow” vs “Aggiorna o ottieni dati esterni”? Entrambe le voci portano a Power Automate; la differenza la fa il Custom Connector che gestisce OAuth e rende la soluzione multiuso.
- Posso cambiare tenantId in “common”? Solo se la tua API e l’accesso previsto sono multi-tenant; altrimenti usa il tenantId specifico.
- Cosa cambia tra
/.default
e scope nominali?/.default
usa i permessi preconcessi all’app; scope nominali richiedono il consenso esplicito indicato.