Open in
Connettiti con OAuth
Autorizza i client MCP e la CLI di ThunderPhone senza condividere una chiave API.
OAuth consente a un'app di connettersi a un'organizzazione ThunderPhone con le autorizzazioni che approvi. I client di directory devono usare OAuth per impostazione predefinita. Le chiavi API dell'organizzazione restano disponibili per i client che richiedono un token Bearer configurato manualmente.
Approva una connessione
Avvia la connessione nel tuo client MCP. Accedi a ThunderPhone, verifica il nome dell'app e le autorizzazioni richieste, scegli un'organizzazione e seleziona Approva. Seleziona Nega se non hai avviato la connessione o non ritieni affidabile l'app. I nomi delle app sono forniti dai relativi sviluppatori e non costituiscono un badge di verifica.
Le autorizzazioni di lettura espongono i dati indicati, incluse registrazioni e trascrizioni quando viene richiesta calls:read. Le autorizzazioni di scrittura possono modificare o eliminare risorse; chiamate, campagne, acquisti di numeri di telefono e distribuzioni possono comportare costi o influire sulla produzione. Il tuo ruolo nell'organizzazione continua ad applicarsi.
Per una connessione CLI, apri il link di verifica mostrato nel terminale, confronta il codice di otto caratteri, seleziona la tua organizzazione e approva. La semplice apertura del link non concede l'accesso. I codici scadono dopo 15 minuti.
Disconnetti un'app
Apri Organizzazione → Chiavi API → App autorizzate nella dashboard e scegli Revoca. Questa operazione revoca l'autorizzazione selezionata per l'organizzazione corrente, inclusi i relativi token di accesso e di aggiornamento. Riconnettiti dall'app se vuoi autorizzarla di nuovo.
Individuazione per client MCP
Usa l'URL del server https://api.thunderphone.com/v1/mcp. Una richiesta senza autenticazione valida riceve 401 con:
WWW-Authenticate: Bearer resource_metadata="https://api.thunderphone.com/.well-known/oauth-protected-resource"Recupera quel documento, quindi recupera i metadati del server di autorizzazione all'indirizzo https://api.thunderphone.com/.well-known/oauth-authorization-server. I metadati della risorsa sono disponibili anche in /.well-known/oauth-protected-resource/v1/mcp. Usa gli endpoint restituiti anziché costruirli manualmente. L'identificatore della risorsa è https://api.thunderphone.com/v1/mcp.
Il server supporta il codice di autorizzazione con S256 PKCE, token di refresh a rotazione, registrazione dinamica di client pubblici, revoca e il grant di autorizzazione del dispositivo. Non sono presenti segreti client né grant impliciti. L'individuazione OpenID è disponibile anche in /.well-known/openid-configuration; include gli stessi campi del server di autorizzazione più subject_types_supported: ["public"] e l'endpoint userinfo. I token ID e i Client ID Metadata Documents (CIMD) non sono supportati.
Registra un client pubblico
Invia JSON a POST /v1/oauth/register:
{
"client_name": "My MCP client",
"redirect_uris": ["http://127.0.0.1:8765/callback"],
"token_endpoint_auth_method": "none",
"grant_types": ["authorization_code", "refresh_token"],
"response_types": ["code"]
}Salva il client_id restituito. I reindirizzamenti devono usare HTTPS oppure HTTP su 127.0.0.1 o localhost. Registra l'URI di callback esatto, inclusi porta e percorso. I frammenti e le credenziali incorporate vengono rifiutati. Gli elementi facoltativi client_uri e logo_uri devono usare HTTPS; ThunderPhone non li recupera durante la registrazione. La registrazione è soggetta a limiti di frequenza. I client registrati non scadono e restano registrati quando una connessione viene revocata. Le callback HTTPS includono https://chatgpt.com/connector/oauth/<id> e https://chatgpt.com/connector_platform_oauth_redirect. Ogni connessione può registrare il proprio client.
Codice di autorizzazione
Apri l'endpoint di autorizzazione individuato con client_id, l'esatto redirect_uri registrato, response_type=code, un state casuale, scope, code_challenge, code_challenge_method=S256 e resource=https://api.thunderphone.com/v1/mcp. Calcola la challenge come digest SHA-256 base64url senza padding di un nuovo verifier PKCE ad alta entropia. Verifica i valori state e iss restituiti prima di scambiare il codice. Ogni risposta di autorizzazione, inclusi rifiuti ed errori di protocollo, identifica l'emittente con iss, che corrisponde esattamente all'issuer individuato. Gli errori relativi a un client o a una callback non validi vengono restituiti localmente senza reindirizzare a tale callback.
Scambia tramite POST /v1/oauth/token usando la codifica dei moduli (è accettato anche JSON):
grant_type=authorization_code
client_id=<your client id>
code=<single-use authorization code>
redirect_uri=<exact registered redirect URI>
code_verifier=<original PKCE verifier>
resource=https://api.thunderphone.com/v1/mcpIl parametro facoltativo resource è accettato sia nelle richieste di autorizzazione sia in quelle di token, inclusi gli scambi di refresh e dispositivo. Se omesso, usa come predefinita la risorsa MCP individuata. Se presente, deve corrispondere esattamente a quella risorsa; altri valori restituiscono invalid_target. I token di accesso riportano tale audience e MCP rifiuta i token con audience mancante o diversa con 401 e una challenge di individuazione.
Le richieste di autorizzazione e i codici scadono dopo 10 minuti. Ogni risposta del token contiene access_token, token_type (Bearer), expires_in (3600 secondi per impostazione predefinita), refresh_token, scope, organization_id e organization_name. Invia i token di accesso solo tramite l'header Authorization: Bearer. Non inserire mai token in URL, log, controllo del codice sorgente o chat.
Aggiorna e revoca
Aggiorna con grant_type=refresh_token, client_id, refresh_token e resource nell'endpoint del token. Salva atomicamente il nuovo token di refresh e smetti di usare quello vecchio. I token di refresh scadono dopo 30 giorni senza un aggiornamento riuscito. Un scope facoltativo può limitare le autorizzazioni concesse. offline_access è sempre incluso e i token di refresh vengono sempre emessi. Una richiesta iniziale senza scope concede solo offline_access, pertanto i client devono richiedere le autorizzazioni necessarie.
Il riutilizzo di un codice e il riutilizzo di un token di refresh ruotato revocano l'intera autorizzazione. Serializza gli aggiornamenti all'interno di un client; ripetere una credenziale scambiata correttamente non è una strategia di nuovo tentativo sicura.
Per disconnettere, invia token e client_id a POST /v1/oauth/revoke. La revoca di uno dei due token revoca la relativa autorizzazione, inclusi tutti i token emessi da essa. Un token sconosciuto restituisce un esito positivo senza rivelare se esiste. Le sessioni del dashboard possono elencare le proprie autorizzazioni con GET /v1/oauth/grants e revocarle con DELETE /v1/oauth/grants/<id>, usando X-ThunderPhone-Org per selezionare l'organizzazione.
Autorizzazione del dispositivo
L'autorizzazione del dispositivo è limitata ai client preregistrati; i client registrati dinamicamente ricevono unauthorized_client. Il client pubblico preregistrato thunderphone-cli supporta l'autorizzazione del dispositivo e l'aggiornamento. Invia client_id=thunderphone-cli e scope a POST /v1/oauth/device/code. Mostra all'utente user_code e verification_uri oppure apri verification_uri_complete.
Interroga l'endpoint del token con grant_type=urn:ietf:params:oauth:grant-type:device_code, client_id e device_code, attendendo almeno l'interval restituito (5 secondi). Continua in caso di authorization_pending. In caso di slow_down, usa il nuovo interval restituito nella risposta, aumentato di 5 secondi, per ogni richiesta successiva. Interrompi in caso di access_denied, expired_token o qualsiasi altro errore. Non approvare mai automaticamente un codice dispositivo.
Il client preregistrato thunderphone-mcp accetta http://127.0.0.1/callback e http://localhost/callback su qualsiasi porta. Schema, host, percorso e query devono corrispondere; lo scambio del token deve usare l'esatto URI di reindirizzamento, inclusa la porta, dell'autorizzazione. I client registrati dinamicamente richiedono una corrispondenza esatta dell'URI di reindirizzamento, inclusa la porta. Registra dinamicamente una callback diversa se ti serve un altro percorso.
Identità dell'account e controlli del dominio del workspace
Richiedi entrambi openid email insieme agli scope operativi necessari al tuo client. Chiama il userinfo_endpoint individuato (GET /v1/oauth/userinfo) con il token di accesso nell'header Bearer. Una risposta riuscita contiene:
{
"sub": "123",
"email": "person@example.com",
"email_verified": true,
"name": "Example User",
"org_id": 456
}sub è l'identificatore utente stabile; org_id è l'organizzazione selezionata durante il consenso. L'endpoint richiede entrambi gli scope di identità e restituisce 403 se ne manca uno. Restituisce 403 con error=access_denied se l'account non dispone di un profilo email verificato, anziché dichiarare attendibile un'email non verificata. I token non validi, scaduti, revocati o con audience errata restituiscono 401. I token di sessione umana e le chiavi API dell'organizzazione non possono chiamare userinfo. Non viene emesso alcun token ID.
Autorizzazioni disponibili
| Famiglia | Ambiti |
|---|---|
| Agenti e importazioni di agenti | agents:read, agents:write |
| Chiamate | calls:read, calls:write |
| Numeri di telefono, chiamanti bloccati e VoIP | numbers:read, numbers:write |
| Knowledge | knowledge:read, knowledge:write |
| Campagne | campaigns:read, campaigns:write |
| Integrazioni, endpoint webhook, server MCP | integrations:read, integrations:write |
| Voci | voices:read |
| Scenari di test, esecuzioni di test, convalida | testing:read, testing:write |
| Fatturazione | billing:read |
| Identità dell'account ed email verificata | openid, email (entrambi obbligatori per userinfo) |
| Connessione persistente | offline_access (sempre incluso) |
GET, HEAD e OPTIONS utilizzano scope di lettura; gli altri metodi utilizzano scope di scrittura. Le modifiche alle voci e alla fatturazione non sono disponibili tramite OAuth; POST /v1/voices/preview utilizza voices:read perché mostra l'anteprima di una voce senza modificarne la configurazione. Gli strumenti MCP applicano lo scope della relativa operazione REST sottostante. I trasferimenti tra organizzazioni vengono negati anche quando l'utente che autorizza appartiene a entrambe le organizzazioni. Altre famiglie API, inclusa la gestione delle chiavi API e le impostazioni degli account umani, non sono disponibili tramite OAuth. Un'autorizzazione mancante per un'operazione REST restituisce 403 con WWW-Authenticate: Bearer error="insufficient_scope", scope="...". I token di accesso non validi o scaduti restituiscono 401.
Segnali di autenticazione degli strumenti MCP
Ogni strumento in tools/list include securitySchemes: [{"type": "oauth2", "scopes": ["agents:read"]}], con lo scope dell'operazione REST di quello strumento. Gli strumenti di documentazione pubblica utilizzano un elenco di scope vuoto e richiedono comunque una connessione autenticata.
A un token valido privo dello scope di uno strumento viene restituito HTTP 200 con un result JSON-RPC contenente isError: true, testo esplicativo in content e _meta["mcp/www_authenticate"]. Quest'ultimo è un array contenente una challenge Bearer con resource_metadata, error="insufficient_scope", error_description e lo scope richiesto. Lo strumento non viene eseguito. Utilizza questa challenge per richiedere un consenso esteso. L'autenticazione mancante o non valida continua a restituire HTTP 401 con WWW-Authenticate; gli errori di scope REST continuano a restituire HTTP 403.
Conservazione delle credenziali
L'API esegue python manage.py oauth_cleanup ogni ora in staging e produzione. Rimuove le richieste di autorizzazione e i codici dispositivo scaduti. I token di accesso scaduti, i codici di autorizzazione e gli hash dei token di aggiornamento vengono eliminati solo dopo la revoca della relativa concessione o quando l'intera famiglia non è più attiva. Gli hash utilizzati vengono conservati finché la famiglia dispone di un token di aggiornamento, codice di autorizzazione, codice dispositivo approvato o token di accesso utilizzabile, così la pulizia non può disabilitare il rilevamento dei replay.