X-ThunderPhone-Signature. Implementa correttamente la verifica una volta e
integra lo stesso helper in ogni handler.
L’algoritmo
- Leggi il corpo raw della richiesta — gli esatti byte che ti abbiamo inviato tramite POST.
- Calcola
hmac_sha256(secret, body).hexdigest(). - Confrontalo in tempo costante con
X-ThunderPhone-Signature. (Un confronto ingenuo tra stringhe espone informazioni di timing.)
, e : senza spazi), UTF-8. Questo ti offre una seconda procedura,
del tutto equivalente, quando il framework espone solo JSON già analizzato:
serializzalo nuovamente in modo canonico e calcola l’HMAC su quello.
Quale secret?
Conserva il secret nel tuo gestore di segreti o in una variabile d’ambiente — non eseguire mai il commit.
Implementazioni di riferimento
Tutte e quattro verificano il corpo raw della richiesta:Configurazione specifica per framework
Verifica delle chiamate degli strumenti
Quando l’agente richiama direttamente uno dei tuoi strumenti funzione (lo strumento dispone di unendpoint), la richiesta include due intestazioni ThunderPhone oltre
alle endpoint.headers configurate:
X-ThunderPhone-Call-ID— l’ID numerico della chiamata in corso.X-ThunderPhone-Signature— HMAC-SHA256, con chiave costituita dal tuo segreto webhook a livello di organizzazione, calcolato sui byte esatti del corpo della richiesta.
verify() funziona senza modifiche, con due particolarità:
- Gli strumenti
GET/DELETEnon hanno corpo. Gli argomenti vengono passati come parametri di query e la firma viene calcolata sulla stringa di byte vuota — quindiverify(b"", sig, secret)(Python) oppureverify(Buffer.alloc(0), sig, secret)(Node). Non calcolare l’hash della stringa di query. - Le organizzazioni senza un webhook legacy configurato non hanno un segreto dell’organizzazione. In
questo caso, le chiamate degli strumenti includono solo
X-ThunderPhone-Call-IDe nessuna intestazione della firma. Configura il webhook legacy (PUT /v1/webhook) per ottenere un segreto di firma, oppure autentica le chiamate degli strumenti con una tua intestazione tramiteendpoint.headers.
endpoint, inviati
al webhook della tua organizzazione come telephony.tool / web.tool) è un normale
webhook firmato: si applica la procedura standard descritta sopra. Consulta
Strumenti funzione per entrambi i formati di richiesta.
Problemi comuni
Ri-serializzazione con la formattazione predefinita
Ri-serializzazione con la formattazione predefinita
Analizzare il body e riesportarlo con le impostazioni predefinite
della libreria JSON (spazi dopo
, / :, chiavi ordinate per inserimento) produce
byte diversi e compromette l’HMAC. Verifica il body grezzo oppure, se
devi ri-serializzarlo, usa esattamente la nostra forma canonica: chiavi
ordinate, separatori compatti, UTF-8.Il framework analizza automaticamente JSON
Il framework analizza automaticamente JSON
Il middleware
express.json() di Express consuma lo stream del body
e perdi i byte grezzi. Usa express.raw() specificamente sulla route
webhook oppure memorizza nel buffer il body grezzo in un pre-middleware.
Lo stesso vale per NestJS / Koa: consulta la loro documentazione sul “raw body”.Confronto non sicuro rispetto ai tempi
Confronto non sicuro rispetto ai tempi
expected === signature in JS o expected == signature in
Python sono confronti con tempi variabili. Usa crypto.timingSafeEqual
o hmac.compare_digest rispettivamente. La differenza di prestazioni
è nulla.Secret errato per gli endpoint degli strumenti
Secret errato per gli endpoint degli strumenti
Le chiamate dirette agli endpoint degli strumenti sono firmate con il secret webhook
a livello di organizzazione (
GET /v1/webhook), non con alcun secret per endpoint
da /v1/developer/webhook-endpoints. Riutilizza la stessa funzione verify(),
ma assicurati di fornirle il secret dell’organizzazione nelle route degli strumenti.Hash della stringa di query negli strumenti GET/DELETE
Hash della stringa di query negli strumenti GET/DELETE
Per i metodi degli strumenti senza body, la firma copre la stringa di byte
vuota, mantenendo un’unica procedura universale: calcola l’HMAC del body grezzo
della richiesta, qualunque esso sia. L’hash dell’URL o della stringa di query non corrisponderà mai.
Mancata restituzione di 401 in caso di mancata corrispondenza
Mancata restituzione di 401 in caso di mancata corrispondenza
Restituire 200 quando la verifica fallisce rende l’handler un bersaglio per replay.
Rispondi sempre con un codice diverso da 2xx se la verifica fallisce.
Passaggi successivi
Panoramica dei webhook
Semantica di consegna, tentativi, IP di origine.
Endpoint webhook
Gestisci più URL, ruota i secret.
Function Tools
I due percorsi di invocazione degli strumenti e le relative strutture delle richieste.
Integrazioni degli strumenti
Crea un’integrazione completa supportata da strumenti, dall’inizio alla fine.