X-ThunderPhone-Signature. Implemente a verificação corretamente uma vez e
use o mesmo auxiliar em todos os handlers.
O algoritmo
- Leia o corpo bruto da solicitação — os bytes exatos que enviamos para você via POST.
- Calcule
hmac_sha256(secret, body).hexdigest(). - Compare em tempo constante com
X-ThunderPhone-Signature. (Uma comparação ingênua de strings expõe informações de temporização.)
, e : sem espaços), UTF-8. Isso oferece uma segunda receita totalmente
equivalente quando seu framework expõe apenas JSON analisado:
serialize novamente de forma canônica e calcule o HMAC disso.
Qual segredo?
Armazene o segredo no seu gerenciador de segredos ou em uma variável de ambiente — nunca faça commit dele.
Implementações de referência
Todas as quatro verificam o corpo bruto da solicitação:Configuração específica do framework
Verificação de chamadas de ferramenta
Quando o agente invoca diretamente uma das suas ferramentas de função (a ferramenta tem umendpoint), a solicitação inclui dois cabeçalhos do ThunderPhone junto
com os endpoint.headers configurados:
X-ThunderPhone-Call-ID— o ID numérico da chamada ao vivo.X-ThunderPhone-Signature— HMAC-SHA256, usando como chave o seu segredo de webhook no nível da organização, sobre os bytes exatos do corpo da solicitação.
verify() funciona sem alterações, com duas particularidades:
- Ferramentas
GET/DELETEnão têm corpo. Os argumentos são enviados como parâmetros de consulta, e a assinatura é calculada sobre a string de bytes vazia — portanto,verify(b"", sig, secret)(Python) ouverify(Buffer.alloc(0), sig, secret)(Node). Não gere hash da string de consulta. - Organizações sem um webhook legado configurado não têm um segredo da organização.
Nesse caso, as chamadas de ferramenta incluem apenas
X-ThunderPhone-Call-IDe nenhum cabeçalho de assinatura. Configure o webhook legado (PUT /v1/webhook) para obter um segredo de assinatura ou autentique as chamadas de ferramenta com seu próprio cabeçalho viaendpoint.headers.
endpoint, entregues
ao webhook da sua organização como telephony.tool / web.tool) é um webhook
comum assinado — a receita padrão acima se aplica. Consulte
Ferramentas de função para ver os dois formatos de solicitação.
Erros comuns
Resserializar com a formatação padrão
Resserializar com a formatação padrão
Analisar o corpo e serializá-lo novamente com os padrões da sua biblioteca JSON
(espaços após
, / :, chaves na ordem de inserção) produz
bytes diferentes e invalida o HMAC. Verifique o corpo bruto — ou, se
precisar resserializá-lo, corresponda exatamente ao nosso formato canônico: chaves
ordenadas, separadores compactos, UTF-8.O framework analisa JSON automaticamente
O framework analisa JSON automaticamente
O middleware
express.json() do Express consome o fluxo do corpo
e você perde os bytes brutos. Use express.raw() especificamente na rota
do webhook ou armazene o corpo bruto em buffer em um pré-middleware.
O mesmo vale para NestJS / Koa — consulte a documentação sobre “corpo bruto”.Comparação insegura em relação ao tempo
Comparação insegura em relação ao tempo
expected === signature em JS ou expected == signature em
Python são comparações com tempo variável. Use crypto.timingSafeEqual
ou hmac.compare_digest, respectivamente. A diferença de desempenho
é nula.Segredo incorreto para endpoints de ferramentas
Segredo incorreto para endpoints de ferramentas
Chamadas diretas a endpoints de ferramentas são assinadas com o segredo de webhook
no nível da organização (
GET /v1/webhook) — não com qualquer segredo por endpoint
de /v1/developer/webhook-endpoints. Reutilize a mesma função verify(),
mas certifique-se de fornecer a ela o segredo da organização nas rotas de ferramentas.Gerar hash da string de consulta em ferramentas GET/DELETE
Gerar hash da string de consulta em ferramentas GET/DELETE
Para métodos de ferramentas sem corpo, a assinatura abrange a string de bytes
vazia, mantendo uma única receita universal: aplique HMAC ao corpo bruto da solicitação,
seja ele qual for. Gerar hash da URL ou da string de consulta nunca corresponderá.
Não retornar 401 em caso de divergência
Não retornar 401 em caso de divergência
Retornar 200 quando a verificação falha transforma o manipulador em um alvo de
repetição. Sempre responda com um código diferente de 2xx se a verificação falhar.
Próximas etapas
Visão geral dos webhooks
Semântica de entrega, novas tentativas, IPs de origem.
Endpoints de webhook
Gerencie várias URLs, alterne segredos.
Ferramentas de função
Os dois caminhos de invocação de ferramentas e os formatos das solicitações.
Integrações de ferramentas
Crie uma integração completa com ferramentas, de ponta a ponta.