feat: first-class helper for Standard Webhooks (Svix) signature verification
Mantenedores costumam responder em até 1 dia
Ninguém assumiu esta issue ainda.
Avaliação
- Dificuldade
- 4/5
- Tempo estimado
- 3-5 dias
- Facilidade para iniciantes
- 52/100
- Tipo de issue
- Funcionalidade
- Clareza
- Razoavelmente clara
- Status de atividade
- Ativa
- Stack de tecnologia
- typescript
- Domínio
- security
Direção de pesquisa
Start by locating the SDK's existing verifyRequestSignature helper and its tests to understand the API conventions and current result shape. Then determine where a Standard Webhooks helper fits and how its signature, raw-body, and timestamp checks should be tested; done means the helper verifies valid signatures, rejects invalid or expired ones, and returns the documented result shape.
Escrita pelo modelo de indexação a partir do texto da issue.
Descrição
Title : feat: first-class helper for Standard Webhooks (Svix) signature verification
Labels : enhancement
Is your feature request related to a problem? Please describe.
I'm building event-driven automations where Trigger.dev jobs react to webhook events emitted by Composio (and a growing number of other providers that have adopted the Standard Webhooks spec — Stripe, GitHub, Slack, Linear, etc.). Composio sends three headers (webhook-id, webhook-timestamp, webhook-signature: v1,<base64>) and the signature is HMAC-SHA256 over ${id}.${timestamp}.${raw_body} with the secret base64-decoded and a tolerance window (default 300s).
The built-in verifyRequestSignature helper only covers single-header schemes (Stripe/GitHub/Cal.com/Novu style), so it can't validate Standard Webhooks signatures out of the box. I get why — supporting every provider's signature scheme isn't Trigger.dev's job, and the helper is the right escape hatch for ad-hoc cases.
The friction isn't the helper itself; it's that every Trigger.dev user integrating with a Standard Webhooks provider ends up writing the same ~50 lines of crypto + header parsing in their verify lambda. That's the part that feels like it could live in the SDK.
Describe the solution you'd like to see
A first-class helper that handles the Standard Webhooks signature scheme, roughly:
import { verifyStandardWebhooks, STANDARD_WEBHOOKS_TOLERANCE_SECONDS } from "@trigger.dev/sdk";
const endpoint = client.defineHttpEndpoint({
id: "composio",
source: "composio.dev",
verify: async (request) => {
return await verifyStandardWebhooks({
request,
secret: process.env.COMPOSIO_WEBHOOK_SECRET!,
// optional, defaults to 300s per the Standard Webhooks spec
tolerance: STANDARD_WEBHOOKS_TOLERANCE_SECONDS,
});
},
});
What the helper should cover:
- Read
webhook-id,webhook-timestamp,webhook-signatureheaders - Validate the
v1,signature prefix (and tolerate futurev1a,/v1b,variants if the spec adds them) - Base64-decode the secret before HMAC
- Compute
HMAC-SHA256(secret, ${id}.${timestamp}.${raw_body})withcrypto.timingSafeEqual - Enforce the timestamp tolerance window (anti-replay)
- Return the same
{ success: true }/{ success: false, reason: "..." }shape asverifyRequestSignatureso it's a drop-in
Bonus if it also exposes the parsed, verified payload (mirroring what the Composio SDK does on its verifyWebhook return type) — that lets users skip the manual JSON.parse after success: true.
Describe alternate solutions
I considered a few:
- PR my own implementation into the SDK. I can do this, but the vouched-contributor + changesets + single-feature-per-PR process makes it heavier than a feature request first. And honestly I'd rather the maintainers pick the API shape —
verifyStandardWebhooksvs. a genericverifyWebhook({ scheme: "standard-webhooks", ... })flag, where in the helper tree it lives, etc. - Publish a separate community package (
@trigger-dev-community/standard-webhooks-verify). Viable, but the moment Trigger.dev ships its own helper, the community package dies. Putting it upstream also makes it discoverable next toverifyRequestSignature. - Move the verification outside Trigger.dev. A small service in front of Trigger.dev that does the verification + republishes to a queue that Trigger.dev jobs subscribe to. Works, but it's exactly the kind of workaround that disappears when the gap closes. I'd rather not maintain it if I don't have to — and it pushes trust boundaries out of the SDK, which is the opposite of where they belong.
Additional information
Adoption is broader than it looks. Standard Webhooks isn't a niche format — it's becoming the de facto signature spec for SaaS webhooks:
- Big-name migrations to Standard Webhooks: Stripe, GitHub, Slack, Linear, Shopify (via Svix)
- Svix-native providers: most new B2B SaaS that use Svix as their delivery layer (Resend, Novu, Knock, Courier, ngrok, Composio, etc.)
- Spec is actively maintained: the Standard Webhooks org publishes reference SDKs in Node, Python, Go, Ruby, Java, .NET, Rust, PHP — so wrapping one of those in a Trigger.dev helper is low-risk and well-tested upstream crypto
That means a single helper in the SDK would unblock integrations with every provider in the list above — not just one. The same ~50 lines of crypto currently written by hand per integration become write-once-for-everyone.
Why now : the Standard Webhooks spec keeps winning — Stripe and GitHub both migrated to it; Linear, Svix-hosted providers, and a long tail of "send us webhooks" SaaS follow. Every new Standard Webhooks integration in Trigger.dev costs ~50 lines of boilerplate that the SDK could own.
I'm not blocked on this — my workaround works — but it felt worth flagging since the cost of closing the gap is low and the gain compounds with every new Standard Webhooks integration anyone tries to build.
Spec references :
- https://www.standardwebhooks.com/ — the spec
- https://docs.composio.dev/docs/webhook-verification — provider example that uses it
- https://github.com/standard-webhooks/standard-webhooks — reference implementations in multiple languages
- Linguagem predominante
- TypeScript
- Estrelas
- 16.5k
- Forks
- 1.5k
- Merge médio
- 1d 15h
- PRs com merge (30d)
- 17
Preparar o ambiente
Este projeto não oferece contêiner de desenvolvimento, Dockerfile nem guia de contribuição, então a configuração fica por sua conta: comece pelo README e veja nosso guia da primeira contribuição para os passos gerais.
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de triggerdotdev/trigger.dev
-
bug: retry.fetch ignores the caller's abort signal and retries aborted requestsTalvez livre de novo Um pull request para esta issue foi fechado sem ser mesclado. Aberta
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 76/100
triggerdotdev/trigger.dev#5116 · 2 comentários ·
Mantenedores costumam responder em até 1 dia
-
bug: Chat transport crashes on Safari < 17.4: AbortSignal.any is not a functionTalvez livre de novo Um pull request para esta issue foi fechado sem ser mesclado. Aberta
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 83/100
triggerdotdev/trigger.dev#5098 · 2 comentários ·
Mantenedores costumam responder em até 1 dia
-
bug: Side menu items lose their active state on detail pagesTalvez livre de novo Um pull request para esta issue foi fechado sem ser mesclado. Aberta
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
triggerdotdev/trigger.dev#5088 ·
Mantenedores costumam responder em até 1 dia
-
bug: RBAC loader logs "plugin found but failed to load" when @triggerdotdev/plugins is simply not installedTalvez livre de novo @itsfaryal assumiu há 17 dias e não há nenhum pull request aberto. Aberta
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 82/100
triggerdotdev/trigger.dev#5083 · 1 comentário ·
Mantenedores costumam responder em até 1 dia
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 83/100
triggerdotdev/trigger.dev#5072 · 1 comentário ·
Mantenedores costumam responder em até 1 dia
Todas as issues de triggerdotdev/trigger.dev
Issues semelhantes
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
Mantenedores costumam responder em até 1 dia
-
bug platform-android
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 68/100
Termix-SSH/Mobile#146 · 1 comentário ·
Mantenedores costumam responder em até 2 dias
-
bug
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 66/100
devswha/herdr-web-ui#3875 ·
-
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 88/100
-
area: runtime chore cli consistency dependencies developer-experience difficulty: easy discovery documentation enhancement good first issue help wanted hygiene json-output packaging priority: P3 tests version
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 78/100
Mantenedores costumam responder em até 1 dia