Skip to content

Webhook ingress: collapse failure responses to one generic 401 - #448

Merged
TheGreatAxios merged 2 commits into
mainfrom
cl-7135-webhook-ingress-returns-404403401-by-failure-mode
Aug 29, 2026
Merged

TheGreatAxios merged 2 commits into
mainfrom
cl-7135-webhook-ingress-returns-404403401-by-failure-mode

Conversation

@TheGreatAxios

Copy link
Copy Markdown
Contributor

Fixes CL-7135 — https://linear.app/abklabs/issue/CL-7135

Problem

packages/webhook-triggers/src/ingress-routes.ts's header comment
(lines 1-9) says failure responses are "deliberately generic" so a
probe against a wrong triggerId can't distinguish "no such trigger"
from "wrong secret" — but the handler (:52-82, pre-fix) actually
returned distinct 404 (unknown trigger), 403 (disabled trigger), and
401 (bad/missing signature) responses, which is exactly the
distinguishing signal the comment says the endpoint withholds.

Change

  • Unknown trigger, disabled trigger, and bad/missing signature now
    all return the same 401 unauthorized response body
    ({"error":{"code":"unauthorized","message":"invalid or missing signature"}}) via a shared unauthorizedResponse() helper.
  • The distinguishing detail (which of the three it was) stays in the
    server-side log line only, unchanged.
  • Left 400 bad_request (malformed JSON body) and Hono's default
    405 (method not allowed) as-is: both only fire after a trigger is
    proven to exist and be correctly signed, so they can't be used to
    probe for trigger existence — a caller must already know the
    correct secret to reach them.
  • Updated the header comment to describe what the code now does.

Caller check

grep -rn "not_found\|forbidden" packages/webhook-triggers apps/web/src
turns up not_found/forbidden only in management-routes.ts (the
separate, session-authenticated management API, untouched by this
change) and its tests. apps/web/src/webhook-triggers-api.ts only
builds the ingress URL for display (webhookTriggerUrl) — it never
calls the ingress route or branches on its response, so nothing in
this repo relies on the removed 404/403 distinction.

Tests

packages/webhook-triggers/test/ingress-routes.test.ts: the three
failure-mode tests (unknown trigger, disabled trigger, missing
signature, wrong-secret signature) now assert status 401 and an
identical body. Confirmed red against the pre-fix handler (404/403
returned) and green after.

Assert unknown-trigger, disabled-trigger, and bad-signature all
return the same 401 unauthorized body instead of the current
404/403/401 split, which lets a probe tell the failure modes apart.
Unknown trigger, disabled trigger, and bad/missing signature returned
distinct 404/403/401 responses, contradicting the header comment's
claim that failures are generic. All three now return the same 401
unauthorized body; the distinguishing detail stays in the server log
line only.

Fixes CL-7135.
@TheGreatAxios
TheGreatAxios force-pushed the cl-7135-webhook-ingress-returns-404403401-by-failure-mode branch from c0a3f1c to 40298c8 Compare August 29, 2026 04:46
@TheGreatAxios
TheGreatAxios merged commit 4ad9956 into main Aug 29, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant