---
title: "Anslut med OAuth"
description: "Auktorisera MCP-klienter och ThunderPhone CLI utan att dela en API-nyckel."
---

OAuth gör det möjligt för en app att ansluta till en ThunderPhone-organisation med de behörigheter du godkänner. Katalogklienter bör använda OAuth som standard. Organisations-API-nycklar är fortfarande tillgängliga för klienter som kräver en manuellt konfigurerad Bearer-token.

## Godkänn en anslutning

Starta anslutningen i din MCP-klient. Logga in på ThunderPhone, kontrollera appnamnet och de begärda behörigheterna, välj en organisation och välj **Godkänn**. Välj **Neka** om du inte startade anslutningen eller inte litar på appen. Appnamn anges av deras utvecklare och är inte ett verifieringsmärke.

Läsbehörigheter ger åtkomst till de angivna uppgifterna, inklusive inspelningar och transkriptioner när `calls:read` begärs. Skrivbehörigheter kan ändra eller ta bort resurser; samtal, kampanjer, telefonköp och distributioner kan medföra kostnader eller påverka produktionen. Din organisationsroll gäller fortfarande.

För en CLI-anslutning öppnar du verifieringslänken som visas i terminalen, jämför den åttateckens kod, väljer din organisation och godkänner. Att bara öppna länken ger inte åtkomst. Koder upphör att gälla efter 15 minuter.

## Koppla från en app

Öppna **Organisation → API-nycklar → Auktoriserade appar** i instrumentpanelen och välj **Återkalla**. Detta återkallar din valda auktorisering för den aktuella organisationen, inklusive dess åtkomst- och uppdateringstoken. Anslut från appen igen om du vill auktorisera den på nytt.

## Identifiering för MCP-klienter

Använd server-URL:en `https://api.thunderphone.com/v1/mcp`. En begäran utan giltig autentisering får `401` med:

```http
WWW-Authenticate: Bearer resource_metadata="https://api.thunderphone.com/.well-known/oauth-protected-resource"
```

Hämta det dokumentet och hämta sedan auktoriseringsserverns metadata på `https://api.thunderphone.com/.well-known/oauth-authorization-server`. Resursmetadata finns även på `/.well-known/oauth-protected-resource/v1/mcp`. Använd de returnerade slutpunkterna i stället för att konstruera dem. Resursidentifieraren är `https://api.thunderphone.com/v1/mcp`.

Servern stöder auktoriseringskod med **S256 PKCE**, roterande uppdateringstoken, offentlig dynamisk klientregistrering, återkallelse och enhetsauktoriseringsflödet. Det finns inga klienthemligheter eller implicita flöden. OpenID-identifiering finns också på `/.well-known/openid-configuration`; den innehåller samma auktoriseringsserverfält samt `subject_types_supported: ["public"]` och userinfo-slutpunkten. ID-token och Client ID Metadata Documents (CIMD) stöds inte.

### Registrera en offentlig klient

Skicka JSON till `POST /v1/oauth/register`:

```json
{
  "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"]
}
```

Spara det returnerade `client_id`. Omdirigeringar måste använda HTTPS eller HTTP på `127.0.0.1` eller `localhost`. Registrera den exakta callback-URI:n, inklusive port och sökväg. Fragment och inbäddade autentiseringsuppgifter avvisas. Valfria `client_uri` och `logo_uri` måste använda HTTPS; ThunderPhone hämtar dem inte under registreringen. Registreringen är hastighetsbegränsad. Registrerade klienter upphör inte att gälla och förblir registrerade när en anslutning återkallas. HTTPS-callbackar omfattar `https://chatgpt.com/connector/oauth/<id>` och `https://chatgpt.com/connector_platform_oauth_redirect`. Varje anslutning kan registrera sin egen klient.

### Auktoriseringskod

Öppna den identifierade auktoriseringsslutpunkten med `client_id`, den exakt registrerade `redirect_uri`, `response_type=code`, ett slumpmässigt `state`, `scope`, `code_challenge`, `code_challenge_method=S256` och `resource=https://api.thunderphone.com/v1/mcp`. Beräkna utmaningen som den opaddade base64url SHA-256-summan av en ny PKCE-verifierare med hög entropi. Kontrollera returnerade `state` och `iss` innan du byter koden. Varje auktoriseringssvar, inklusive avslag och protokollfel, identifierar utfärdaren med `iss`, som exakt matchar den identifierade `issuer`. Fel för en ogiltig klient eller callback returneras lokalt utan omdirigering till den callbacken.

Byt på `POST /v1/oauth/token` med formulärkodning (JSON accepteras också):

```text
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/mcp
```

Den valfria parametern `resource` accepteras i både auktoriserings- och tokenbegäranden (inklusive uppdaterings- och enhetsbyten). När den utelämnas används den identifierade MCP-resursen som standard. När den anges måste den exakt matcha den resursen; andra värden returnerar `invalid_target`. Åtkomsttoken har den målgruppen, och MCP avvisar token med saknad eller annan målgrupp med `401` och en identifieringsutmaning.

Auktoriseringsbegäranden och koder upphör att gälla efter 10 minuter. Varje tokensvar innehåller `access_token`, `token_type` (`Bearer`), `expires_in` (3600 sekunder som standard), `refresh_token`, `scope`, `organization_id` och `organization_name`. Skicka endast åtkomsttoken via rubriken `Authorization: Bearer`. Lägg aldrig token i URL:er, loggar, källkodshantering eller chatt.

### Uppdatera och återkalla

Uppdatera med `grant_type=refresh_token`, `client_id`, `refresh_token` och `resource` på tokenslutpunkten. Spara den nya uppdateringstoken atomiskt och sluta använda den gamla. Uppdateringstoken upphör att gälla efter 30 dagar utan en lyckad uppdatering. Ett valfritt `scope` kan begränsa de beviljade behörigheterna. `offline_access` inkluderas alltid och uppdateringstoken utfärdas alltid. En första begäran utan `scope` beviljar endast `offline_access`, så klienter bör begära de behörigheter de behöver.

Återanvändning av kod och återanvändning av roterad uppdateringstoken återkallar hela auktoriseringen. Serialisera uppdateringar inom en klient; att spela upp en autentiseringsuppgift som redan har bytts är inte en säker strategi för nya försök.

För att koppla från skickar du `token` och `client_id` till `POST /v1/oauth/revoke`. Återkallning av endera token återkallar dess auktorisering, inklusive alla token som utfärdats från den. En okänd token returnerar lyckat resultat utan att avslöja om den finns. Dashboard-sessioner kan lista sina egna auktoriseringar på `GET /v1/oauth/grants` och återkalla en på `DELETE /v1/oauth/grants/<id>`, där `X-ThunderPhone-Org` väljer organisationen.

### Enhetsauktorisering

Enhetsauktorisering är begränsad till förregistrerade klienter; dynamiskt registrerade klienter får `unauthorized_client`. Den förregistrerade offentliga klienten `thunderphone-cli` stöder enhetsauktorisering och uppdatering. Skicka `client_id=thunderphone-cli` och `scope` till `POST /v1/oauth/device/code`. Visa `user_code` och `verification_uri` för användaren, eller öppna `verification_uri_complete`.

Polla tokenslutpunkten med `grant_type=urn:ietf:params:oauth:grant-type:device_code`, `client_id` och `device_code`, och vänta minst det returnerade `interval` (5 sekunder). Fortsätt vid `authorization_pending`. Vid `slow_down` använder du det nya `interval` som returneras i svaret (ökat med 5 sekunder) för varje efterföljande begäran. Stoppa vid `access_denied`, `expired_token` eller något annat fel. Godkänn aldrig en enhetskod automatiskt.

Den förregistrerade klienten `thunderphone-mcp` accepterar `http://127.0.0.1/callback` och `http://localhost/callback` på valfri port. Schema, värd, sökväg och fråga måste matcha; tokenbytet måste använda den exakta omdirigerings-URI:n (inklusive port) från auktoriseringen. Dynamiskt registrerade klienter kräver exakt matchning av omdirigerings-URI, inklusive porten. Registrera en annan callback dynamiskt om du behöver en annan sökväg.

### Kontidentitet och kontroll av arbetsytedomän

Begär både `openid email` tillsammans med de åtgärdsomfattningar som din klient behöver. Anropa den identifierade `userinfo_endpoint` (`GET /v1/oauth/userinfo`) med åtkomsttoken i Bearer-rubriken. Ett lyckat svar innehåller:

```json
{
  "sub": "123",
  "email": "person@example.com",
  "email_verified": true,
  "name": "Example User",
  "org_id": 456
}
```

`sub` är den stabila användaridentifieraren; `org_id` är organisationen som valdes vid samtycke. Slutpunkten kräver båda identitetsomfattningarna och returnerar `403` om någon av dem saknas. Den returnerar `403` med `error=access_denied` om kontot saknar en verifierad e-postprofil, i stället för att hävda att en overifierad e-postadress är betrodd. Ogiltiga, utgångna, återkallade eller token med fel målgrupp returnerar `401`. Token för mänskliga sessioner och organisations-API-nycklar kan inte anropa userinfo. Ingen ID-token utfärdas.

## Tillgängliga behörigheter

| Familj | Omfattningar |
| --- | --- |
| Agenter och agentimporter | `agents:read`, `agents:write` |
| Samtal | `calls:read`, `calls:write` |
| Telefonnummer, blockerade uppringare och VoIP | `numbers:read`, `numbers:write` |
| Kunskap | `knowledge:read`, `knowledge:write` |
| Kampanjer | `campaigns:read`, `campaigns:write` |
| Integrationer, webhook-slutpunkter, MCP-servrar | `integrations:read`, `integrations:write` |
| Röster | `voices:read` |
| Testscenarier, testkörningar, validering | `testing:read`, `testing:write` |
| Fakturering | `billing:read` |
| Kontoidentitet och verifierad e-post | `openid`, `email` (båda krävs för userinfo) |
| Beständig anslutning | `offline_access` (ingår alltid) |

GET, HEAD och OPTIONS använder läsbehörigheter; andra metoder använder skrivbehörigheter. Ändringar av röster och fakturering är inte tillgängliga via OAuth; `POST /v1/voices/preview` använder `voices:read` eftersom det förhandsgranskar en röst utan att ändra dess konfiguration. MCP-verktyg tillämpar behörighetsomfånget för sin underliggande REST-åtgärd. Överföringar mellan organisationer nekas även när användaren som godkänner tillhör båda organisationerna. Andra API-områden, inklusive hantering av API-nycklar och personliga kontoinställningar, är inte tillgängliga via OAuth. En saknad behörighet för en REST-åtgärd returnerar `403` med `WWW-Authenticate: Bearer error="insufficient_scope", scope="..."`. Ogiltiga eller utgångna åtkomsttoken returnerar `401`.


### MCP-verktygens autentiseringssignaler

Varje verktyg i `tools/list` innehåller `securitySchemes: [{"type": "oauth2", "scopes": ["agents:read"]}]`, med behörighetsomfånget för verktygets REST-åtgärd. Offentliga dokumentationsverktyg använder en tom lista med omfång och kräver fortfarande en autentiserad anslutning.

En giltig token som saknar ett verktygs behörighetsomfång får HTTP `200` med ett JSON-RPC-`result` som innehåller `isError: true`, förklarande text i `content` och `_meta["mcp/www_authenticate"]`. Den senare är en array som innehåller en Bearer-utmaning med `resource_metadata`, `error="insufficient_scope"`, `error_description` och det obligatoriska `scope`. Verktyget körs inte. Använd denna utmaning för att begära utökat samtycke. Saknad eller ogiltig autentisering fortsätter att returnera HTTP `401` med `WWW-Authenticate`; REST-omfångsfel fortsätter att returnera HTTP `403`.

## Lagring av autentiseringsuppgifter

API:t kör `python manage.py oauth_cleanup` varje timme i staging och produktion. Det tar bort utgångna auktoriseringsbegäranden och enhetskoder. Utgångna åtkomsttoken, auktoriseringskoder och hashar för uppdateringstoken rensas först efter att deras behörighetsgivning har återkallats eller hela familjen har upphört. Använda hashar behålls medan familjen har en användbar uppdateringstoken, auktoriseringskod, godkänd enhetskod eller åtkomsttoken, så att rensningen inte kan inaktivera återspelningsdetektering.
