Open in
Hubungkan dengan OAuth
Otorisasi klien MCP dan CLI ThunderPhone tanpa membagikan kunci API.
OAuth memungkinkan aplikasi terhubung ke satu organisasi ThunderPhone dengan izin yang Anda setujui. Klien direktori sebaiknya menggunakan OAuth secara default. Kunci API organisasi tetap tersedia untuk klien yang memerlukan token Bearer yang dikonfigurasi secara manual.
Setujui koneksi
Mulai koneksi di klien MCP Anda. Masuk ke ThunderPhone, periksa nama aplikasi dan izin yang diminta, pilih organisasi, lalu pilih Setujui. Pilih Tolak jika Anda tidak memulai koneksi atau tidak memercayai aplikasi tersebut. Nama aplikasi diberikan oleh pengembangnya dan bukan lencana verifikasi.
Izin baca mengekspos data yang disebutkan, termasuk rekaman dan transkrip saat calls:read diminta. Izin tulis dapat mengubah atau menghapus sumber daya; panggilan, kampanye, pembelian nomor telepon, dan deployment dapat menimbulkan biaya atau memengaruhi produksi. Peran organisasi Anda tetap berlaku.
Untuk koneksi CLI, buka tautan verifikasi yang ditampilkan di terminal Anda, bandingkan kode delapan karakter, pilih organisasi Anda, lalu setujui. Hanya membuka tautan tidak memberikan akses. Kode kedaluwarsa setelah 15 menit.
Putuskan koneksi aplikasi
Buka Organisasi → Kunci API → Aplikasi terotorisasi di dashboard dan pilih Cabut. Tindakan ini mencabut otorisasi yang Anda pilih untuk organisasi saat ini, termasuk token akses dan token refresh-nya. Hubungkan kembali dari aplikasi jika Anda ingin mengotorisasinya lagi.
Penemuan untuk klien MCP
Gunakan URL server https://api.thunderphone.com/v1/mcp. Permintaan tanpa autentikasi yang valid menerima 401 dengan:
WWW-Authenticate: Bearer resource_metadata="https://api.thunderphone.com/.well-known/oauth-protected-resource"Ambil dokumen tersebut, lalu ambil metadata server otorisasi di https://api.thunderphone.com/.well-known/oauth-authorization-server. Metadata resource juga tersedia di /.well-known/oauth-protected-resource/v1/mcp. Gunakan endpoint yang dikembalikan alih-alih menyusunnya sendiri. Pengidentifikasi resource adalah https://api.thunderphone.com/v1/mcp.
Server mendukung kode otorisasi dengan S256 PKCE, refresh token bergilir, registrasi klien dinamis publik, pencabutan, dan grant otorisasi perangkat. Tidak ada client secret atau implicit grant. Penemuan OpenID juga tersedia di /.well-known/openid-configuration; penemuan ini mencakup field server otorisasi yang sama ditambah subject_types_supported: ["public"] dan endpoint userinfo. Token ID dan Dokumen Metadata Client ID (CIMD) tidak didukung.
Daftarkan klien publik
Kirim JSON ke 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"]
}Simpan client_id yang dikembalikan. Redirect harus menggunakan HTTPS, atau HTTP pada 127.0.0.1 atau localhost. Daftarkan URI callback yang tepat, termasuk port dan jalurnya. Fragmen dan kredensial yang disematkan ditolak. client_uri dan logo_uri opsional harus menggunakan HTTPS; ThunderPhone tidak mengambilnya selama pendaftaran. Pendaftaran dibatasi laju permintaannya. Klien terdaftar tidak kedaluwarsa dan tetap terdaftar saat koneksi dicabut. Callback HTTPS mencakup https://chatgpt.com/connector/oauth/<id> dan https://chatgpt.com/connector_platform_oauth_redirect. Setiap koneksi dapat mendaftarkan kliennya sendiri.
Kode otorisasi
Buka endpoint otorisasi yang ditemukan dengan client_id, redirect_uri terdaftar yang tepat, response_type=code, state acak, scope, code_challenge, code_challenge_method=S256, dan resource=https://api.thunderphone.com/v1/mcp. Hitung challenge sebagai digest SHA-256 base64url tanpa padding dari verifier PKCE baru dengan entropi tinggi. Periksa state dan iss yang dikembalikan sebelum menukar kode. Setiap respons otorisasi, termasuk penolakan dan kesalahan protokol, mengidentifikasi issuer dengan iss, yang harus sama persis dengan issuer yang ditemukan. Kesalahan untuk klien atau callback yang tidak valid dikembalikan secara lokal tanpa mengarahkan ulang ke callback tersebut.
Tukar pada POST /v1/oauth/token menggunakan pengodean formulir (JSON juga diterima):
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/mcpParameter resource opsional diterima pada permintaan otorisasi maupun token (termasuk pertukaran refresh dan perangkat). Jika dihilangkan, nilainya secara default adalah resource MCP yang ditemukan. Jika ada, nilainya harus sama persis dengan resource tersebut; nilai lain mengembalikan invalid_target. Access token membawa audiens tersebut, dan MCP menolak token dengan audiens yang tidak ada atau berbeda dengan 401 dan challenge penemuan.
Permintaan otorisasi dan kode kedaluwarsa setelah 10 menit. Setiap respons token berisi access_token, token_type (Bearer), expires_in (3600 detik secara default), refresh_token, scope, organization_id, dan organization_name. Kirim access token hanya melalui header Authorization: Bearer. Jangan pernah menaruh token dalam URL, log, source control, atau chat.
Refresh dan cabut
Lakukan refresh dengan grant_type=refresh_token, client_id, refresh_token, dan resource pada endpoint token. Simpan refresh token baru secara atomik dan berhenti menggunakan token lama. Refresh token kedaluwarsa setelah 30 hari tanpa refresh yang berhasil. scope opsional dapat mempersempit izin yang diberikan. offline_access selalu disertakan dan refresh token selalu diterbitkan. Permintaan awal tanpa scope hanya memberikan offline_access, sehingga klien harus meminta izin yang diperlukan.
Penggunaan ulang kode dan penggunaan ulang refresh token yang telah digilir mencabut seluruh otorisasi. Serialkan refresh dalam satu klien; memutar ulang kredensial yang berhasil ditukar bukan strategi percobaan ulang yang aman.
Untuk memutuskan koneksi, kirim token dan client_id ke POST /v1/oauth/revoke. Mencabut salah satu token akan mencabut otorisasinya, termasuk semua token yang diterbitkan darinya. Token yang tidak dikenal mengembalikan keberhasilan tanpa mengungkapkan apakah token tersebut ada. Sesi Dasbor dapat mencantumkan otorisasi miliknya sendiri pada GET /v1/oauth/grants dan mencabut satu otorisasi pada DELETE /v1/oauth/grants/<id>, dengan X-ThunderPhone-Org memilih organisasi.
Otorisasi perangkat
Otorisasi perangkat dibatasi untuk klien yang telah terdaftar sebelumnya; klien yang didaftarkan secara dinamis menerima unauthorized_client. Klien publik yang telah terdaftar sebelumnya, thunderphone-cli, mendukung otorisasi perangkat dan refresh. Kirim client_id=thunderphone-cli dan scope ke POST /v1/oauth/device/code. Tampilkan user_code dan verification_uri kepada pengguna, atau buka verification_uri_complete.
Poll endpoint token dengan grant_type=urn:ietf:params:oauth:grant-type:device_code, client_id, dan device_code, dengan menunggu setidaknya interval yang dikembalikan (5 detik). Lanjutkan pada authorization_pending. Pada slow_down, gunakan interval baru yang dikembalikan dalam respons (bertambah 5 detik) untuk setiap permintaan berikutnya. Berhenti pada access_denied, expired_token, atau kesalahan lainnya. Jangan pernah menyetujui kode perangkat secara otomatis.
Klien thunderphone-mcp yang telah terdaftar sebelumnya menerima http://127.0.0.1/callback dan http://localhost/callback pada port apa pun. Skema, host, jalur, dan query harus cocok; pertukaran token harus menggunakan URI redirect yang tepat (termasuk port) dari otorisasi. Klien yang didaftarkan secara dinamis memerlukan pencocokan URI redirect yang tepat, termasuk port. Daftarkan callback lain secara dinamis jika Anda memerlukan jalur lain.
Identitas akun dan pemeriksaan domain ruang kerja
Minta openid email bersama scope operasi yang dibutuhkan klien Anda. Panggil userinfo_endpoint yang ditemukan (GET /v1/oauth/userinfo) dengan access token dalam header Bearer. Respons yang berhasil berisi:
{
"sub": "123",
"email": "person@example.com",
"email_verified": true,
"name": "Example User",
"org_id": 456
}sub adalah pengidentifikasi pengguna yang stabil; org_id adalah organisasi yang dipilih selama persetujuan. Endpoint memerlukan kedua scope identitas dan mengembalikan 403 jika salah satunya tidak ada. Endpoint mengembalikan 403 dengan error=access_denied jika akun tidak memiliki profil email terverifikasi, alih-alih menyatakan bahwa email yang belum diverifikasi dapat dipercaya. Token yang tidak valid, kedaluwarsa, dicabut, atau memiliki audiens yang salah mengembalikan 401. Token sesi manusia dan API key organisasi tidak dapat memanggil userinfo. Tidak ada token ID yang diterbitkan.
Izin yang tersedia
| Keluarga | Cakupan |
|---|---|
| Agen dan impor agen | agents:read, agents:write |
| Panggilan | calls:read, calls:write |
| Nomor telepon, penelepon yang diblokir, dan VoIP | numbers:read, numbers:write |
| Pengetahuan | knowledge:read, knowledge:write |
| Kampanye | campaigns:read, campaigns:write |
| Integrasi, endpoint webhook, server MCP | integrations:read, integrations:write |
| Suara | voices:read |
| Skenario pengujian, proses pengujian, validasi | testing:read, testing:write |
| Penagihan | billing:read |
| Identitas akun dan email terverifikasi | openid, email (keduanya diperlukan untuk userinfo) |
| Koneksi persisten | offline_access (selalu disertakan) |
GET, HEAD, dan OPTIONS menggunakan cakupan baca; metode lainnya menggunakan cakupan tulis. Mutasi suara dan penagihan tidak tersedia melalui OAuth; POST /v1/voices/preview menggunakan voices:read karena melakukan pratinjau suara tanpa mengubah konfigurasinya. Alat MCP menerapkan cakupan operasi REST yang mendasarinya. Transfer lintas organisasi ditolak bahkan ketika pengguna yang memberikan otorisasi tergabung dalam kedua organisasi. Keluarga API lainnya, termasuk pengelolaan API key dan pengaturan akun manusia, tidak tersedia melalui OAuth. Izin yang tidak ada pada operasi REST menghasilkan 403 dengan WWW-Authenticate: Bearer error="insufficient_scope", scope="...". Token akses yang tidak valid atau kedaluwarsa menghasilkan 401.
Sinyal autentikasi alat MCP
Setiap alat di tools/list menyertakan securitySchemes: [{"type": "oauth2", "scopes": ["agents:read"]}], dengan cakupan operasi REST alat tersebut. Alat dokumentasi publik menggunakan daftar cakupan kosong dan tetap memerlukan koneksi terautentikasi.
Token valid yang tidak memiliki cakupan alat menerima HTTP 200 dengan result JSON-RPC yang berisi isError: true, teks penjelasan dalam content, dan _meta["mcp/www_authenticate"]. Yang terakhir adalah array yang berisi tantangan Bearer dengan resource_metadata, error="insufficient_scope", error_description, dan scope yang diperlukan. Alat tidak dijalankan. Gunakan tantangan ini untuk meminta persetujuan yang diperluas. Autentikasi yang tidak ada atau tidak valid tetap menghasilkan HTTP 401 dengan WWW-Authenticate; kegagalan cakupan REST tetap menghasilkan HTTP 403.
Retensi kredensial
API menjalankan python manage.py oauth_cleanup setiap jam di staging dan produksi. Proses ini menghapus permintaan otorisasi dan kode perangkat yang kedaluwarsa. Token akses, kode otorisasi, dan hash token refresh yang kedaluwarsa hanya dipangkas setelah grant-nya dicabut atau seluruh keluarganya tidak lagi aktif. Hash yang telah digunakan dipertahankan selama keluarga tersebut memiliki token refresh, kode otorisasi, kode perangkat yang disetujui, atau token akses yang dapat digunakan, sehingga pembersihan tidak dapat menonaktifkan deteksi pemutaran ulang.