Skip to main content
Varje begäran vi skickar till din server — webhook-leveranser och anrop till verktygsslutpunkter — innehåller en HMAC-SHA256-signatur i rubriken X-ThunderPhone-Signature. Verifiera den korrekt en gång och använd samma hjälpfunktion i varje hanterare.

Algoritmen

  1. Läs den råa begärandetexten — de exakta byte vi POSTade till dig.
  2. Beräkna hmac_sha256(secret, body).hexdigest().
  3. Jämför i konstant tid med X-ThunderPhone-Signature. (En naiv strängjämförelse läcker tidsinformation.)
Vi signerar exakt de byte vi överför, så verifiering av den råa texten fungerar alltid. Dessa byte är också payloadens kanoniska JSON-serialisering — nycklar sorterade alfabetiskt, kompakta avgränsare (, och : utan mellanslag), UTF-8. Det ger dig ett andra, helt likvärdigt tillvägagångssätt när ditt ramverk bara exponerar parsad JSON: serialisera om kanoniskt och beräkna HMAC för det.
Föredra den råa texten — det är ett steg mindre och immunt mot egenheter vid JSON-talens tur-och-retur-konvertering i vissa språk.

Vilken hemlighet?

Lagra hemligheten i din hemlighetshanterare eller miljövariabel — committa den aldrig.

Referensimplementationer

Alla fyra verifierar den råa begärandetexten:

Frameworkspecifik koppling

Verifiera verktygsanrop

När agenten anropar ett av dina funktionsverktyg direkt (verktyget har en endpoint) innehåller begäran två ThunderPhone-rubriker utöver dina konfigurerade endpoint.headers:
  • X-ThunderPhone-Call-ID — det numeriska ID:t för det aktiva samtalet.
  • X-ThunderPhone-Signature — HMAC-SHA256, med din webhook-hemlighet på organisationsnivå som nyckel, över de exakta bytevärdena i begärans brödtext.
Samma verify()-hjälpfunktion fungerar utan ändringar, med två detaljer:
  1. GET- / DELETE-verktyg har ingen brödtext. Argument skickas som frågeparametrar, och signaturen beräknas över den tomma bytesträngen — alltså verify(b"", sig, secret) (Python) eller verify(Buffer.alloc(0), sig, secret) (Node). Hasha inte frågesträngen.
  2. Organisationer utan en konfigurerad äldre webhook har ingen organisationshemlighet. I det fallet innehåller verktygsanrop endast X-ThunderPhone-Call-ID och ingen signaturrubrik. Konfigurera den äldre webhooken (PUT /v1/webhook) för att få en signeringshemlighet, eller autentisera verktygsanrop med din egen rubrik via endpoint.headers.
Verktygsdirigering i webhook-läge (verktyg utan en endpoint, som levereras till din organisationswebhook som telephony.tool / web.tool) är en vanlig signerad webhook — standardreceptet ovan gäller. Se Funktionsverktyg för båda begärandeformaten.

Vanliga fallgropar

Att parsa brödtexten och dumpa den igen med JSON-bibliotekets standardinställningar (mellanslag efter , / :, nycklar i insättningsordning) ger andra byte och gör att HMAC:en inte fungerar. Verifiera den råa brödtexten — eller, om du måste serialisera om, matcha vår kanoniska form exakt: sorterade nycklar, kompakta avgränsare, UTF-8.
Express-mellanprogrammet express.json() förbrukar brödtextströmmen och du förlorar de råa byten. Använd express.raw() specifikt på webhook-routen, eller buffra den råa brödtexten i ett mellanprogram före detta. Samma sak gäller NestJS / Koa — läs deras dokumentation om “raw body”.
expected === signature i JS eller expected == signature i Python är tidsvariabla jämförelser. Använd crypto.timingSafeEqual respektive hmac.compare_digest. Prestandaskillnaden är obefintlig.
Direkta anrop till verktygsslutpunkter signeras med webhook-hemligheten på organisationsnivå (GET /v1/webhook) — inte med någon hemlighet per slutpunkt från /v1/developer/webhook-endpoints. Återanvänd samma verify() funktion, men se till att du skickar in organisationshemligheten på verktygsrutter.
För verktygsmetoder utan brödtext omfattar signaturen den tomma bytesträngen, vilket ger ett universellt recept: HMAC:a den råa begärandebrödtexten, oavsett vad den innehåller. Att hasha URL:en eller frågesträngen kommer aldrig att matcha.
Att returnera 200 när verifieringen misslyckas gör hanteraren till ett mål för replay-attacker. Svara alltid med annat än 2xx om verifieringen misslyckas.

Nästa steg

Översikt över webhooks

Leveranssemantik, återförsök, käll-IP-adresser.

Webhook-slutpunkter

Hantera flera URL:er, rotera hemligheter.

Funktionsverktyg

De två sökvägarna för verktygsanrop och deras begärandeformat.

Verktygsintegrationer

Bygg en komplett verktygsstödd integration från början till slut.