feat: first-class helper for Standard Webhooks (Svix) signature verification
維護者通常 1 天內回覆
還沒有人認領這個 Issue。
評估
- 難度
- 4/5
- 預估耗時
- 3-5 天
- 新手友好度
- 52/100
- Issue 類型
- 功能
- 描述清晰度
- 基本清楚
- 活躍度
- 活躍
- 技術堆疊
- typescript
- 領域
- security
研究方向
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.
由索引模型根據 Issue 內容生成。
描述
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
- 主要語言
- TypeScript
- 星號
- 16.5k
- 分支
- 1.5k
- 平均合併
- 1 天 15 小時
- 30 天內合併 PR
- 17
環境準備
這個專案沒有提供開發容器、Dockerfile 或貢獻指南,環境需要你自己搭建:先看它的 README,通用步驟見我們的新手貢獻指南。
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
triggerdotdev/trigger.dev 的其他 Issue
-
bug: retry.fetch ignores the caller's abort signal and retries aborted requests可能重新可做 關聯的 PR 已關閉且未合併。 未關閉
難度 2/5 1-3 小時 新手友好度 76/100
triggerdotdev/trigger.dev#5116 · 2 則留言 ·
維護者通常 1 天內回覆
-
bug: Chat transport crashes on Safari < 17.4: AbortSignal.any is not a function可能重新可做 關聯的 PR 已關閉且未合併。 未關閉
難度 2/5 1-3 小時 新手友好度 83/100
triggerdotdev/trigger.dev#5098 · 2 則留言 ·
維護者通常 1 天內回覆
-
bug: Side menu items lose their active state on detail pages可能重新可做 關聯的 PR 已關閉且未合併。 未關閉
難度 2/5 1-3 小時 新手友好度 72/100
triggerdotdev/trigger.dev#5088 ·
維護者通常 1 天內回覆
-
bug: RBAC loader logs "plugin found but failed to load" when @triggerdotdev/plugins is simply not installed可能重新可做 @itsfaryal 於 17 天前認領,目前沒有進行中的 PR。 未關閉
難度 2/5 1-3 小時 新手友好度 82/100
triggerdotdev/trigger.dev#5083 · 1 則留言 ·
維護者通常 1 天內回覆
-
難度 2/5 1-3 小時 新手友好度 83/100
triggerdotdev/trigger.dev#5072 · 1 則留言 ·
維護者通常 1 天內回覆
查看 triggerdotdev/trigger.dev 的全部 Issue
相似的 Issue
-
難度 2/5 1-3 小時 新手友好度 72/100
維護者通常 1 天內回覆
-
bug platform-android
難度 2/5 1-3 小時 新手友好度 68/100
Termix-SSH/Mobile#146 · 1 則留言 ·
維護者通常 2 天內回覆
-
bug
難度 2/5 1-3 小時 新手友好度 66/100
devswha/herdr-web-ui#3875 ·
-
難度 1/5 1 小時以內 新手友好度 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
難度 2/5 1-3 小時 新手友好度 78/100
維護者通常 1 天內回覆